//
//	Copyright © 2007 Nemetschek North America 
//	All Rights Reserved.
//
// Created by Vladislav Stanev

#include "StdAfx.h"

#include "CustomObjects.h"

using namespace VWFC::Tools;
using namespace VWFC::VWObjects;
using namespace VWFC::Math;

// --------------------------------------------------------------------------------------------------------
CParamProviderAbstract::CParamProviderAbstract()
{
}

CParamProviderAbstract::~CParamProviderAbstract()
{
}

// ---------------------------------------------------------------------------------------------------
// Process boolean parmeter
// ---------------------------------------------------------------------------------------------------
void CParamProviderAbstract::ProcessParameter(bool bRead, bool& inOutValue, bool oldVaue, size_t paramIndex)
{
	if ( bRead ) {
		inOutValue			= this->GetParamBool( paramIndex );
	}
	else if ( oldVaue != inOutValue )  {
		this->SetParamBool( paramIndex, inOutValue );
	}
}

// ---------------------------------------------------------------------------------------------------
// Process long parameter
// ---------------------------------------------------------------------------------------------------
void CParamProviderAbstract::ProcessParameter(bool bRead, UInt32& inOutValue, UInt32 oldVaue, size_t paramIndex)
{
	if ( bRead ) {
		inOutValue			= this->GetParamLong( paramIndex );
	}
	else if ( oldVaue != inOutValue )  {
		this->SetParamLong( paramIndex, inOutValue );
	}
}

// ---------------------------------------------------------------------------------------------------
// Process long parameter
// ---------------------------------------------------------------------------------------------------
void CParamProviderAbstract::ProcessParameter(bool bRead, SInt32& inOutValue, UInt32 oldVaue, size_t paramIndex)
{
	if ( bRead ) {
		inOutValue			= this->GetParamLong( paramIndex );
	}
	else if ( oldVaue != inOutValue )  {
		this->SetParamLong( paramIndex, inOutValue );
	}
}

// ---------------------------------------------------------------------------------------------------
// Process double parameter
// ---------------------------------------------------------------------------------------------------
void CParamProviderAbstract::ProcessParameter(bool bRead, double& inOutValue, double oldVaue, size_t paramIndex)
{
	if ( bRead ) {
		inOutValue			= this->GetParamReal( paramIndex );
	}
	else if ( ! MathUtils::Equalish( inOutValue, oldVaue, VWPoint2D::sEpsilon ) )  {
		this->SetParamReal( paramIndex, inOutValue );
	}
}

// ---------------------------------------------------------------------------------------------------
// Process string parameter
// ---------------------------------------------------------------------------------------------------
void CParamProviderAbstract::ProcessParameter(bool bRead, TXString& inOutValue, const TXString& oldVaue, size_t paramIndex)
{
	if ( bRead ) {
		inOutValue			= this->GetParamString( paramIndex );
	}
	else if ( oldVaue != inOutValue )  {
		this->SetParamString( paramIndex, inOutValue );
	}
}

// ---------------------------------------------------------------------------------------------------
// Process control point parameter, represented by a pair of kFieldCoordLocX and kFieldCoordLocY parameters.
// This functionality doesn't handle the kFieldControlPoint parametric field type.
// ---------------------------------------------------------------------------------------------------
void CParamProviderAbstract::ProcessParameter(bool bRead, VWPoint2D& inOutValue, const VWPoint2D& oldVaue, size_t paramIndexXCoord, size_t paramIndexYCoord)
{
	if ( bRead ) {
		inOutValue			= this->GetParamCtrlPt( paramIndexXCoord, paramIndexYCoord );
	}
	else if ( oldVaue != inOutValue )  {
		this->SetParamCtrlPt( paramIndexXCoord, paramIndexYCoord, inOutValue );
	}
}

// ---------------------------------------------------------------------------------------------------
// Decode enumeration parameter string from parameter enum values
// ---------------------------------------------------------------------------------------------------
UInt32 CParamProviderAbstract::DecodeEnumString(size_t paramIndex, const TXString& string, UInt32 def) const
{	
	UInt32				result	= def;

	TXStringSTLArray	arrChoices;
	if ( this->GetParamChoices( paramIndex, arrChoices ) ) {
		size_t choicesCnt	= arrChoices.size();
		for(size_t i=0; i<choicesCnt; i++) {
			const TXString&		strChoice	= arrChoices[ i ];
			if ( strChoice == string ) {
				result	= i;
				break;
			}
		}
	}

	return result;
}

// ---------------------------------------------------------------------------------------------------
// Encode enumeration parameter string from parameter enum values
// ---------------------------------------------------------------------------------------------------
TXString CParamProviderAbstract::EncodeEnumString(size_t paramIndex, UInt32 index, UInt32 def) const
{
	TXString			result;

	TXStringSTLArray	arrChoices;
	if ( this->GetParamChoices( paramIndex, arrChoices ) ) {
		size_t choicesCnt	= arrChoices.size();
		if ( index < choicesCnt ) {
			result	= arrChoices[ index ];
		}
		else if ( def < choicesCnt ) {
			result	= arrChoices[ def ];
		}
	}

	return result;
}

// ---------------------------------------------------------------------------------------------------
// Decode enumeration parameter string from specivied string array
// ---------------------------------------------------------------------------------------------------
UInt32 CParamProviderAbstract::DecodeEnumString(char** arrStrings, const TXString& string, UInt32 def) const
{
	UInt32	result	= def;
	for(size_t i=0; arrStrings && arrStrings[i]; i++) {
		if ( string == arrStrings[i] ) {
			result = i;
			break;
		}
	}

	return result;
}

// ---------------------------------------------------------------------------------------------------
// Encode enumeration parameter string from specivied string array
// ---------------------------------------------------------------------------------------------------
TXString CParamProviderAbstract::EncodeEnumString(char** arrStrings, UInt32 index, UInt32 defIndex) const
{
	size_t	stringsCount	= 0;
	for(size_t i=0; arrStrings && arrStrings[i]; i++) {
		stringsCount++;
	}

	ASSERTN( kVStanev, defIndex < stringsCount );
	if (index < stringsCount )	return arrStrings[ index ];
	else						return arrStrings[ defIndex ];
}

bool CParamProviderAbstract::ResourceGetParamChoices(size_t paramIndex, TXStringSTLArray& outArray) const
{
	outArray.clear();

	bool				ok				= false;
	UnivParmTabHandle	hParameterRes	= (UnivParmTabHandle) ::GS_GetResource( gCBP, OST_Prm, kUnivParmResID );
	if ( hParameterRes && *hParameterRes ) {
		if ( paramIndex >= 0 && paramIndex < (size_t) (*hParameterRes)->numParms ) {
			const UnivParmSpec&	paramDef	= (*hParameterRes)->parms[ paramIndex ];
			if ( paramDef.fType == kFieldPopUp && paramDef.fChoices > 0 ) {
				ParmChoiceTabHandle		hChoicesRes	= (ParmChoiceTabHandle) ::GS_GetResource( gCBP, OST_Chc, paramDef.fChoices );
				if ( hChoicesRes && *hChoicesRes ) {
					ok			= true;
					for(short i=0; i<(*hChoicesRes)->numChoices; i++) {
						const unsigned char*	psName	= (*hChoicesRes)->choices[i].fUniversalChoiceName;

						outArray.push_back( TXString( psName ) );
					}
				}

				::GS_ReleaseResource(gCBP, (Handle) hChoicesRes);

			}
		}
		::GS_ReleaseResource(gCBP, (Handle) hParameterRes);
	}

	return ok;
}

// --------------------------------------------------------------------------------------------------------
CObjectParamProvider::CObjectParamProvider(VWParametricObj& obj)
: fObj( obj )
{
}

CObjectParamProvider::~CObjectParamProvider()
{
}

long CObjectParamProvider::GetParamLong(size_t paramIndex) const
{
	return fObj.GetParamLong( paramIndex );
}

void CObjectParamProvider::SetParamLong(size_t paramIndex, long value)
{
	fObj.SetParamLong( paramIndex, value );
}

bool CObjectParamProvider::GetParamBool(size_t paramIndex) const
{
	return fObj.GetParamBool( paramIndex );
}

void CObjectParamProvider::SetParamBool(size_t paramIndex, bool value)
{
	fObj.SetParamBool( paramIndex, value );
}

double CObjectParamProvider::GetParamReal(size_t paramIndex) const
{
	return fObj.GetParamReal( paramIndex );
}

void CObjectParamProvider::SetParamReal(size_t paramIndex, double value)
{
	fObj.SetParamReal( paramIndex, value );
}

TXString CObjectParamProvider::GetParamString(size_t paramIndex) const
{
	return fObj.GetParamString( paramIndex );
}

void CObjectParamProvider::SetParamString(size_t paramIndex, const TXString& value)
{
	fObj.SetParamString( paramIndex, value );
}

VWPoint2D CObjectParamProvider::GetParamCtrlPt(size_t paramIndexXCoord, size_t paramIndexYCoord) const
{
	return VWPoint2D(	fObj.GetParamReal( paramIndexXCoord ),
						fObj.GetParamReal( paramIndexYCoord ) );
}

void CObjectParamProvider::SetParamCtrlPt(size_t paramIndexXCoord, size_t paramIndexYCoord, const VWPoint2D& value)
{
	fObj.SetParamReal( paramIndexXCoord, value.x );
	fObj.SetParamReal( paramIndexYCoord, value.y );
}

bool CObjectParamProvider::GetParamChoices(size_t paramIndex, TXStringSTLArray& outArray) const
{
	return this->ResourceGetParamChoices( paramIndex, outArray );
}


// --------------------------------------------------------------------------------------------------------
CFormatParamProvider::CFormatParamProvider(VWRecordFormatObj& obj)
: fObj( obj )
{
}

CFormatParamProvider::~CFormatParamProvider()
{
}

long CFormatParamProvider::GetParamLong(size_t paramIndex) const
{
	return fObj.GetParamLong( paramIndex );
}

void CFormatParamProvider::SetParamLong(size_t paramIndex, long value)
{
	fObj.SetParamLong( paramIndex, value );
}

bool CFormatParamProvider::GetParamBool(size_t paramIndex) const
{
	return fObj.GetParamBool( paramIndex );
}

void CFormatParamProvider::SetParamBool(size_t paramIndex, bool value)
{
	fObj.SetParamBool( paramIndex, value );
}

double CFormatParamProvider::GetParamReal(size_t paramIndex) const
{
	return fObj.GetParamReal( paramIndex );
}

void CFormatParamProvider::SetParamReal(size_t paramIndex, double value)
{
	fObj.SetParamReal( paramIndex, value );
}

TXString CFormatParamProvider::GetParamString(size_t paramIndex) const
{
	return fObj.GetParamString( paramIndex );
}

void CFormatParamProvider::SetParamString(size_t paramIndex, const TXString& value)
{
	fObj.SetParamString( paramIndex, value );
}

VWPoint2D CFormatParamProvider::GetParamCtrlPt(size_t paramIndexXCoord, size_t paramIndexYCoord) const
{
	return VWPoint2D(	fObj.GetParamReal( paramIndexXCoord ),
						fObj.GetParamReal( paramIndexYCoord ) );
}

void CFormatParamProvider::SetParamCtrlPt(size_t paramIndexXCoord, size_t paramIndexYCoord, const VWPoint2D& value)
{
	fObj.SetParamReal( paramIndexXCoord, value.x );
	fObj.SetParamReal( paramIndexYCoord, value.y );
}

bool CFormatParamProvider::GetParamChoices(size_t paramIndex, TXStringSTLArray& outArray) const
{
	return this->ResourceGetParamChoices( paramIndex, outArray );
}
