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

#include "StdAfx.h"
//#include "VWRecordFormatObj.h"

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

#include "CustomObjects.h"


//--------------------------------------------------------------------
VWRecordFormatObj::VWRecordFormatObj(MCObjectHandle hFormatHandle)
{
	fhObject		= hFormatHandle;

	VWFC_ASSERT( VWRecordFormatObj::IsRecordFormatObject( fhObject ) );
	if ( ! VWRecordFormatObj::IsRecordFormatObject( fhObject ) )
		THROW_VWFC_EXCEPTION( VWBadObjectTypeException, 0, "bad handle type when creating" );
}

VWRecordFormatObj::VWRecordFormatObj(const TXString& formatName)
{
	Str63			name;
	ASSERTN( kVStanev, formatName.GetLength() < 63 );
	formatName.CopyInto( name/*, 63*/ );

	TFormatHandler	fh( name );
	
	fhObject		= ::GS_GetNamedObject( gCBP, TXString(formatName) );
	VWFC_ASSERT( VWRecordFormatObj::IsRecordFormatObject( fhObject ) );
	if ( ! VWRecordFormatObj::IsRecordFormatObject( fhObject ) )
		THROW_VWFC_EXCEPTION( VWBadObjectTypeException, 0, "bad handle type when creating" );
}

VWRecordFormatObj::VWRecordFormatObj(const VWRecordFormatObj& src)
{
	fhObject	= src.fhObject;
}

VWRecordFormatObj::~VWRecordFormatObj()
{
}

VWRecordFormatObj& VWRecordFormatObj::operator=(const VWRecordFormatObj& src)
{
	fhObject	= src.fhObject;
	return *this;
}

TXString VWRecordFormatObj::GetFormatName() const
{
	VWFC_ASSERT( fhObject );
	TFormatHandler	fh( fhObject );
	
	Str63 nameOfFormat;
	fh.GetNameOfFormat( nameOfFormat );

	return nameOfFormat;
}

bool VWRecordFormatObj::IsParametric() const
{
	VWFC_ASSERT( fhObject );
	TFormatHandler	fh( fhObject );
	return fh.IsParametric() ? true : false;
}

void VWRecordFormatObj::SetParametric(bool bIsParametric)
{
	VWFC_ASSERT( fhObject );
	TFormatHandler	fh( fhObject );
	fh.SetIsParametric( bIsParametric );
}

bool VWRecordFormatObj::GetFormatVisibility() const
{
	TVariableBlock		varBlock;
	::GS_GetObjectVariable( gCBP, fhObject, ovFormatVisibility, varBlock );

	Boolean				bVis	= false;
	VERIFYN( kVStanev, varBlock.GetBoolean( bVis ) );
	return bVis ? true : false;
}

void VWRecordFormatObj::SetFormatVisibility(bool bVisibility)
{
	TVariableBlock		varBlock	= TVariableBlock( (Boolean) bVisibility );
	::GS_SetObjectVariable( gCBP, fhObject, ovFormatVisibility, varBlock );
}

size_t VWRecordFormatObj::AddParamLong(const TXString& name, long value, bool bUpdateExistingRecords)
{
	VWFC_ASSERT( fhObject );
	TFormatHandler	fh( fhObject );

	Str20			fieldName;
	ASSERTN( kVStanev, name.GetLength() < 20 );
	name.CopyInto( fieldName/*, 20*/ );
	TRecordItem		defaultValue( kFieldLongInt );
	VERIFYN( kVStanev, defaultValue.SetFieldValue( value ) );

	short index	= fh.AddField( fieldName, defaultValue, bUpdateExistingRecords );
	return index - 1;
}

size_t VWRecordFormatObj::AddParamBool(const TXString& name, bool value, bool bUpdateExistingRecords)
{
	VWFC_ASSERT( fhObject );
	TFormatHandler	fh( fhObject );

	Str20			fieldName;
	ASSERTN( kVStanev, name.GetLength() < 20 );
	name.CopyInto( fieldName/*, 20*/ );
	TRecordItem		defaultValue( kFieldBoolean );
	VERIFYN( kVStanev, defaultValue.SetFieldValue( (Boolean) value ) );

	short index	= fh.AddField( fieldName, defaultValue, bUpdateExistingRecords );
	return index - 1;
}

size_t VWRecordFormatObj::AddParamReal(const TXString& name, double value, bool bUpdateExistingRecords)
{
	VWFC_ASSERT( fhObject );
	TFormatHandler	fh( fhObject );

	Str20			fieldName;
	ASSERTN( kVStanev, name.GetLength() < 20 );
	name.CopyInto( fieldName/*, 20*/ );
	TRecordItem		defaultValue( kFieldReal );
	VERIFYN( kVStanev, defaultValue.SetFieldValue( (double_param) value ) );

	short index	= fh.AddField( fieldName, defaultValue, bUpdateExistingRecords );
	return index - 1;
}

size_t VWRecordFormatObj::AddParamString(const TXString& name, const TXString& value, bool bUpdateExistingRecords)
{
	VWFC_ASSERT( fhObject );
	TFormatHandler	fh( fhObject );

	Str20			fieldName;
	ASSERTN( kVStanev, name.GetLength() < 20 );
	name.CopyInto( fieldName/*, 20*/ );
	TRecordItem		defaultValue( kFieldText );
	VERIFYN( kVStanev, defaultValue.SetFieldValue( (const char*) value, value.GetLength() ) );

	short index	= fh.AddField( fieldName, defaultValue, bUpdateExistingRecords );
	return index - 1;
}

size_t VWRecordFormatObj::GetParamsCount() const
{
	VWFC_ASSERT( fhObject );
	TFormatHandler	fh( fhObject );
	return (size_t) fh.GetNumOfFields();
}

TXString VWRecordFormatObj::GetParamName(size_t paramIndex) const
{
	VWFC_ASSERT( fhObject );
	TFormatHandler	fh( fhObject );

	Str20	nameOfField;
	// NOTE! 'GetNameOfField' return 1 based value
	fh.GetNameOfField( DemoteTo<short>( kVStanev, paramIndex+1 ), nameOfField );
	return nameOfField;
}

TXString VWRecordFormatObj::GetParamLocalizedName(size_t paramIndex) const
{
	TXString			paramName;

	UnivParmTabHandle	hParameterRes = (UnivParmTabHandle) ::GS_GetResource( gCBP, OST_Prm, kUnivParmResID );
	if ( hParameterRes && *hParameterRes ) {
		if ( paramIndex >= 0 && paramIndex < (size_t) (*hParameterRes)->numParms ) {
			unsigned char*	psLocalizedName	= (*hParameterRes)->parms[ paramIndex ].fLocalizedName;

			paramName		= psLocalizedName;
		}
		::GS_ReleaseResource(gCBP, (Handle) hParameterRes);
	}
	else {
		// Current parameter resource not found.  Look for old resource type ('PARM').
		paramName	= this->GetParamName( paramIndex );
	}

	return paramName;
}

// returns ((size_t) -1) if not found
size_t VWRecordFormatObj::GetParamIndex(const TXString& paramName) const
{
	VWFC_ASSERT( fhObject );
	TFormatHandler	fh( fhObject );

	// NOTE! 'GetFieldIndex' return 1 based value
	int		index	= fh.GetFieldIndex( paramName );
	if ( index == 0 )
		return (size_t) -1;	// not found

	return (size_t) (index - 1);
}

EFieldStyle VWRecordFormatObj::GetParamStyle(size_t paramIndex) const
{
	VWFC_ASSERT( fhObject );
	TFormatHandler	fh( fhObject );

	// NOTE! 'GetFieldStyle' return 1 based value
	return (EFieldStyle) fh.GetFieldStyle( DemoteTo<short>( kVStanev, paramIndex+1 ) );
}

TXString VWRecordFormatObj::GetParamValue(size_t paramIndex) const
{
	VWFC_ASSERT( fhObject );
	TFormatHandler	fh( fhObject );

	// NOTE! itemIndex is expected from the SDK as 1 based value
	short			itemIndex	= DemoteTo<short>( kVStanev, paramIndex+1 );
	EFieldStyle		style		= (EFieldStyle) fh.GetFieldStyle( itemIndex );
	TRecordItem valueItem( style );
	Boolean			ok			= fh.GetFieldDefault( itemIndex, valueItem );
	VWFC_ASSERT( ok );

	TXString	value;
	if ( style == kFieldText ) {
		char*		string		= NULL;
		size_t		len			= 0;

		if ( ok ) {
			valueItem.GetFieldValue( string, len );
			value	= TXString( string, len );
		}
	}
	else {
		Str255		theString;
		if ( valueItem.GetFieldValueAsString( theString ) ) {
			value	= theString;
		}
	}

	return value;}

void VWRecordFormatObj::SetParamValue(size_t paramIndex, const TXString& value)
{
	VWFC_ASSERT( fhObject );
	TFormatHandler	fh( fhObject );

	// NOTE! itemIndex is expected from the SDK as 1 based value
	short			itemIndex	= DemoteTo<short>( kVStanev, paramIndex+1 );
	EFieldStyle		style		= (EFieldStyle) fh.GetFieldStyle( itemIndex );
	TRecordItem		recItem( style );
	if ( VWFC_VERIFY( fh.GetFieldDefault( itemIndex, recItem ) ) ) {
		if ( style == kFieldText ) {
			const char* szText		= value;
			size_t		textLen		= value.GetLength();

			if ( VWFC_VERIFY( recItem.SetFieldValue( szText, textLen ) ) ) {
				VWFC_VERIFY( fh.SetFieldDefault( itemIndex, recItem ) );
			}
		}
		else {
			Str255		theString;
			ASSERTN( kVStanev, value.GetLength() < 255 );
			value.CopyInto( theString/*, 255*/ );
			if ( VWFC_VERIFY( recItem.SetFieldValueAsString( theString ) ) ) {
				VWFC_VERIFY( fh.SetFieldDefault( itemIndex, recItem ) );
			}
		}
	}
}

long VWRecordFormatObj::GetParamLong(size_t paramIndex) const
{
	VWFC_ASSERT( fhObject );
	TFormatHandler	fh( fhObject );

	// NOTE! itemIndex is expected from the SDK as 1 based value
	short		itemIndex	= DemoteTo<short>( kVStanev, paramIndex+1 );
	TRecordItem valueItem( fh.GetFieldStyle( itemIndex ) );
	Boolean		ok			= fh.GetFieldDefault( itemIndex, valueItem );
	VWFC_ASSERT( ok );

	long		value	= 0;
	if ( ok ) {
		valueItem.GetFieldValue( value );
	}

	return value;
}

void VWRecordFormatObj::SetParamLong(size_t paramIndex, long value)
{
	VWFC_ASSERT( fhObject );
	TFormatHandler	fh( fhObject );

	// NOTE! itemIndex is expected from the SDK as 1 based value
	short			itemIndex	= DemoteTo<short>( kVStanev, paramIndex+1 );
	TRecordItem		recItem( fh.GetFieldStyle( itemIndex ) );
	if ( VWFC_VERIFY( fh.GetFieldDefault( itemIndex, recItem ) ) ) {
		if ( VWFC_VERIFY( recItem.SetFieldValue( value ) ) ) {
			VWFC_VERIFY( fh.SetFieldDefault( itemIndex, recItem ) );
		}
	}
}

bool VWRecordFormatObj::GetParamBool(size_t paramIndex) const
{
	VWFC_ASSERT( fhObject );
	TFormatHandler	fh( fhObject );

	// NOTE! itemIndex is expected from the SDK as 1 based value
	short		itemIndex	= DemoteTo<short>( kVStanev, paramIndex+1 );
	TRecordItem valueItem( fh.GetFieldStyle( itemIndex ) );
	Boolean		ok			= fh.GetFieldDefault( itemIndex, valueItem );
	VWFC_ASSERT( ok );

	Boolean		value	= 0;
	if ( ok ) {
		valueItem.GetFieldValue( value );
	}

	return value ? true : false;
}

void VWRecordFormatObj::SetParamBool(size_t paramIndex, bool value)
{
	VWFC_ASSERT( fhObject );
	TFormatHandler	fh( fhObject );

	// NOTE! itemIndex is expected from the SDK as 1 based value
	short			itemIndex	= DemoteTo<short>( kVStanev, paramIndex+1 );
	TRecordItem		recItem( fh.GetFieldStyle( itemIndex ) );
	if ( VWFC_VERIFY( fh.GetFieldDefault( itemIndex, recItem ) ) ) {
		Boolean		boolValue	= value;
		if ( VWFC_VERIFY( recItem.SetFieldValue( boolValue ) ) ) {
			VWFC_VERIFY( fh.SetFieldDefault( itemIndex, recItem ) );
		}
	}
}

double VWRecordFormatObj::GetParamReal(size_t paramIndex) const
{
	VWFC_ASSERT( fhObject );
	TFormatHandler	fh( fhObject );

	// NOTE! itemIndex is expected from the SDK as 1 based value
	short		itemIndex	= DemoteTo<short>( kVStanev, paramIndex+1 );
	TRecordItem valueItem( fh.GetFieldStyle( itemIndex ) );
	Boolean		ok			= fh.GetFieldDefault( itemIndex, valueItem );
	VWFC_ASSERT( ok );

	double		value	= 0;
	if ( ok ) {
		valueItem.GetFieldValue( value );
	}

	return value;
}

void VWRecordFormatObj::SetParamReal(size_t paramIndex, double value)
{
	VWFC_ASSERT( fhObject );
	TFormatHandler	fh( fhObject );

	// NOTE! itemIndex is expected from the SDK as 1 based value
	short			itemIndex	= DemoteTo<short>( kVStanev, paramIndex+1 );
	TRecordItem		recItem( fh.GetFieldStyle( itemIndex ) );
	if ( VWFC_VERIFY( fh.GetFieldDefault( itemIndex, recItem ) ) ) {
		if ( VWFC_VERIFY( recItem.SetFieldValue( value ) ) ) {
			VWFC_VERIFY( fh.SetFieldDefault( itemIndex, recItem ) );
		}
	}
}

TXString VWRecordFormatObj::GetParamString(size_t paramIndex) const
{
	VWFC_ASSERT( fhObject );
	TFormatHandler	fh( fhObject );

	// NOTE! itemIndex is expected from the SDK as 1 based value
	short		itemIndex	= DemoteTo<short>( kVStanev, paramIndex+1 );
	TRecordItem valueItem( fh.GetFieldStyle( itemIndex ) );
	Boolean		ok		= fh.GetFieldDefault( itemIndex, valueItem );
	VWFC_ASSERT( ok );

	TXString	value;
	char*		string		= NULL;
	size_t		len			= 0;

	if ( ok ) {
		valueItem.GetFieldValue( string, len );
		value	= TXString( string, len );
	}

	return value;
}

void VWRecordFormatObj::SetParamString(size_t paramIndex, const TXString& value)
{
	VWFC_ASSERT( fhObject );
	TFormatHandler	fh( fhObject );

	// NOTE! itemIndex is expected from the SDK as 1 based value
	short			itemIndex	= DemoteTo<short>( kVStanev, paramIndex+1 );
	TRecordItem		recItem( fh.GetFieldStyle( itemIndex ) );
	if ( VWFC_VERIFY( fh.GetFieldDefault( itemIndex, recItem ) ) ) {
		const char* szText		= value;
		size_t		textLen		= value.GetLength();

		if ( VWFC_VERIFY( recItem.SetFieldValue( szText, textLen ) ) ) {
			VWFC_VERIFY( fh.SetFieldDefault( itemIndex, recItem ) );
		}
	}
}

/*static*/ bool VWRecordFormatObj::IsRecordFormatObject(MCObjectHandle hObj)
{
	short	type	= ::GS_GetObjectType( gCBP, hObj );
	return type == kFormatNode;
}

/*static*/ bool VWRecordFormatObj::IsRecordFormatObject(MCObjectHandle hObj, const char* szName)
{
	if ( ! VWRecordFormatObj::IsRecordFormatObject( hObj ) )
		return false;

	TFormatHandler	fh( hObj );
	
	Str63 nameOfFormat;
	fh.GetNameOfFormat( nameOfFormat );
	
	return TXString(szName) == TXString(nameOfFormat);
}

/*static*/ MCObjectHandle VWRecordFormatObj::GetRecordFormat(const char* szName)
{
	return ::GS_GetNamedObject( gCBP, TXString(szName) );
}

/*static*/ void VWRecordFormatObj::DeleteRecordFormat(MCObjectHandle hRecFormat)
{
	if ( VWRecordFormatObj::IsRecordFormatObject( hRecFormat ) ) {
		TFormatHandler	fh( hRecFormat );
		fh.DeleteFormat();
	}
}