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

#include "StdAfx.h"

//#include "VWStringConv.h"



struct SScale {
	const char*		szName;
	double			dScale;
};

static const SScale	g_arrScales[] = 
{
	{ "Custom",					0 },
	{ "1/32\" = 1'0\"",			1.0/384 },
	{ "1/16\" = 1'0\"",			1.0/192 },
	{ "3/32\" = 1'0\"",			1.0/128 },
	{ "1/8\" = 1'0\"",			1.0/96 },
	{ "3/16\" = 1'0\"",			1.0/64 },
	{ "1/4\" = 1'0\"",			1.0/48 },
	{ "3/8\" = 1'0\"",			1.0/32 },
	{ "1/2\" = 1'0\"",			1.0/24 },
	{ "3/4\" = 1'0\"",			1.0/16 },
	{ "1\" = 1'0\"",			1.0/12 },
	{ "1-1/2\" = 1'0\"",		1.0/8 },
	{ "2\" = 1'0\"",			1.0/6 },
	{ "3\" = 1'0\"",			1.0/4 },
	{ "1\" = 10'0\"",			1.0/120 },
	{ "1\" = 20'0\"",			1.0/240 },
	{ "1\" = 30'0\"",			1.0/360 },
	{ "1\" = 40'0\"",			1.0/480 },
	{ "1\" = 50'0\"",			1.0/600 },
	{ "1\" = 100'0\"",			1.0/1200 },
	{ "1:1",					1.0 },
	{ "1:2",					1.0/2 },
	{ "1:4",					1.0/4 },
	{ "1:5",					1.0/5 },
	{ "1:8",					1.0/8 },
	{ "1:10",					1.0/10 },
	{ "1:20",					1.0/20 },
	{ "1:25",					1.0/25 },
	{ "1:50",					1.0/50 },
	{ "1:100",					1.0/100 },
	{ "1:200",					1.0/200 },
	{ "1:500",					1.0/500 },
	{ "1:1000",					1.0/1000 },
	{ "1:5000",					1.0/5000 },
	{ "1:10000",				1.0/10000 },
	{ "2x",						2.0 },
	{ "3x",						3.0 },
	{ "4x",						4.0 },
	{ "5x",						5.0 },
	{ "6x",						6.0 },
	{ "8x",						8.0 },
	{ "10x",					10.0 },
	{ "15x",					15.0 },
	{ "20x",					20.0 },
	{ "50x",					50.0 },
	{ "100x",					100.0 },
	{ "500x",					500.0 },
	{ NULL,						0 }
};

using namespace VWFC::Tools;

VWStringConv::VWStringConv(const TXString& str)
{
	fbIsString		= true;
	fTheString		= str;
	fdValue			= 0;
}

VWStringConv::VWStringConv(double value)
{
	fbIsString		= false;
	fdValue			= value;
}

VWStringConv::~VWStringConv()
{
}

double VWStringConv::GetScale() const
{
	if ( fbIsString ) {
		for(size_t i=0; g_arrScales[i].szName; i++) {
			if ( fTheString.CompareNoCase( g_arrScales[i].szName ) == 0 ) {
				return g_arrScales[i].dScale;
			}
		}

		return 0;
	}
	else
		return fdValue;
}

TXString VWStringConv::GetScaleString(double dEpsilon/* = kNearlyEqualEpsilonForDoubles*/) const
{
	if ( ! fbIsString ) {
		for(size_t i=0; g_arrScales[i].szName; i++) {
			if ( MathUtils::Equalish( g_arrScales[i].dScale, fdValue, dEpsilon ) ) {
				return g_arrScales[i].szName;
			}
		}

		TXString	string;
		if ( fdValue == (double)( (int)fdValue ) )
			string.Format( "1:%d", (int)fdValue );
		else
			string.Format( "1:%.3f", fdValue );
		return string;
	}
	else
		return fTheString;
}

double VWStringConv::GetDimCoord() const
{
	if ( fbIsString ) {
		WorldCoord	coord	= 0;
		VWFC_VERIFY( ::GS_DimStringToCoord( gCBP, fTheString, coord ) );

		return coord;
	}
	else
		return fdValue;
}

TXString VWStringConv::GetDimCoordString() const
{
	if ( ! fbIsString ) {
		Str255		string;
		::GS_CoordToDimString( gCBP, fdValue, string );
		return string;
	}
	else
		return fTheString;
}

TXString VWStringConv::GetDimGeneralCoordString() const
{
	if ( ! fbIsString ) {
		long		precision	= 1;
		VERIFYN( kVStanev, ::GS_GetProgramVariable( gCBP, varUnit1DecDimPrecision, & precision ) );

		double		upi			= 25.4;
		VERIFYN( kVStanev, ::GS_GetProgramVariable( gCBP, varUnit1UnitsPerInch, & upi ) );

		short		format		= ufDecimal;
		VERIFYN( kVStanev, ::GS_GetProgramVariable( gCBP, varUnit1Format, & format ) );

		// convert in document units
		double		dValue			= fdValue * upi / 25.4;
		if ( format == ufFeetAndInches ) {
			// GS_DoubleToString funtion requires the value to be in feet when document is in feet&inches
			dValue		/= 12;		// 1' = 12"
		}

		Str255		str;
		Byte		accuracy		= DemoteTo<Byte>( kVStanev, precision );
		::GS_DoubleToString( gCBP, nsDimension, accuracy, 0 /*unused*/, dValue, str );

		return str;
	}
	else
		return fTheString;
}

double VWStringConv::GetAngleDeg() const
{
	if ( fbIsString ) {
		double	value		= 0;
		VWFC_VERIFY( ::GS_StringToAngleN( gCBP, fTheString, value ) );
		return value;
	}
	else	
		return fdValue;
}

TXString VWStringConv::GetAngleDegString() const
{
	if ( ! fbIsString ) {
		Str255		string;
		::GS_AngleToStringN( gCBP, fdValue, string );
		return string;
	}
	else 
		return fTheString;
}

double VWStringConv::GetArea() const
{
	// not implemented
	ASSERTN( kVStanev, false );
	return 0;
}

//debug
TXString VWStringConv::GetAreaString(bool bPreserveNumber /*= false*/) const
{
	long		precision	= 1;
	VERIFYN( kVStanev, ::GS_GetProgramVariable( gCBP, varUnit1AreaDecPrecision, & precision ) );

	double		upsi			= 25.4 * 25.4;
	VERIFYN( kVStanev, ::GS_GetProgramVariable( gCBP, varUnit1AreaUnitsPerSquareInch, & upsi ) );

	double		dValue			= fdValue;

	if ( ! bPreserveNumber ) {
		// convert in document units
		dValue					= fdValue * upsi / (25.4 * 25.4);
	}

	Str255		str;
	Byte		accuracy		= DemoteTo<Byte>( kVStanev, precision );
	::GS_DoubleToString( gCBP, nsDimensionArea, accuracy, 0 /*unused*/, dValue, str );

	return str;
}

double VWStringConv::GetVolume() const
{
	// not implemented
	ASSERTN( kVStanev, false );
	return 0;
}

TXString VWStringConv::GetVolumeString() const
{
	long		precision	= 1;
	VERIFYN( kVStanev, ::GS_GetProgramVariable( gCBP, varUnit1VolumeDecPrecision, & precision ) );

	double		upci			= 25.4 * 25.4 * 25.4;
	VERIFYN( kVStanev, ::GS_GetProgramVariable( gCBP, varUnit1VolumeUnitsPerCubicInch, & upci ) );

	// convert in document units
	double		dValue			= fdValue * upci / (25.4 * 25.4 * 25.4);

	Str255		str;
	Byte		accuracy		= DemoteTo<Byte>( kVStanev, precision );
	::GS_DoubleToString( gCBP, nsDimensionVolume, accuracy, 0 /*unused*/, dValue, str );

	return str;
}

double VWStringConv::GetVWDocumentDouble(TNumStyleClass style) const
{
	if ( fbIsString ) {
		double value		= 0;
		VWFC_VERIFY( ::GS_StringToDouble( gCBP, style, fTheString, value ) );
		return value;
	}
	else 
		return fdValue;
}

TXString VWStringConv::GetVWDocumentDoubleString(TNumStyleClass style, UInt8 accuracy, UInt8 format) const
{
	if ( ! fbIsString ) {
		Str255		string;
		::GS_DoubleToString( gCBP, style, accuracy, format, fdValue, string );
		return string;
	}
	else
		return fTheString;
}

/*
TXString DXFScaleString(const double inScale)

{
	const short kMessageListID = 3308;
	short stringID = 38;

	if      (DoublesAreNearlyEqual(inScale, 192.0))		stringID = 1;	//	"1/16\"=1'";
	else if (DoublesAreNearlyEqual(inScale, 96.0))		stringID = 2;	//	"1/8\"=1'";
	else if (DoublesAreNearlyEqual(inScale, 48.0))		stringID = 3;	//	"1/4\"=1'";
	else if (DoublesAreNearlyEqual(inScale, 24.0))		stringID = 4;	//	"1/2\"=1'";
	else if (DoublesAreNearlyEqual(inScale, 16.0))		stringID = 5;	//	"3/4\"=1'";
	else if (DoublesAreNearlyEqual(inScale, 12.0))		stringID = 6;	//	"1\"=1'";
	else if (DoublesAreNearlyEqual(inScale, 8.0))		stringID = 7;	//	"1-1/2\"=1'";
	else if (DoublesAreNearlyEqual(inScale, 6.0))		stringID = 8;	//	"2\"=1'";
	else if (DoublesAreNearlyEqual(inScale, 4.0))		stringID = 9;	//	"3\"=1'";
	else if (DoublesAreNearlyEqual(inScale, 120.0))		stringID = 10;	//	"1\"=10'";
	else if (DoublesAreNearlyEqual(inScale, 240.0))		stringID = 11;	//	"1\"=20'";
	else if (DoublesAreNearlyEqual(inScale, 360.0))		stringID = 12;	//	"1\"=30'";
	else if (DoublesAreNearlyEqual(inScale, 480.0))		stringID = 13;	//	"1\"=40'";
	else if (DoublesAreNearlyEqual(inScale, 600.0))		stringID = 14;	//	"1\"=50'";
	else if (DoublesAreNearlyEqual(inScale, 1200.0))	stringID = 15;	//	"1\"=100'";
	
	else if (DoublesAreNearlyEqual(inScale, 1.0))		stringID = 16;	//	"1:1";
	else if (DoublesAreNearlyEqual(inScale, 2.0))		stringID = 17;	//	"1:2";
	else if (DoublesAreNearlyEqual(inScale, 4.0))		stringID = 18;	//	"1:4";  // bogus - the 4 above will grab it first
	else if (DoublesAreNearlyEqual(inScale, 5.0))		stringID = 19;	//	"1:5";
	else if (DoublesAreNearlyEqual(inScale, 10.0))		stringID = 20;	//	"1:10";
	else if (DoublesAreNearlyEqual(inScale, 25.0))		stringID = 21;	//	"1:25";
	else if (DoublesAreNearlyEqual(inScale, 50.0))		stringID = 22;	//	"1:50";
	else if (DoublesAreNearlyEqual(inScale, 100.0))		stringID = 23;	//	"1:100";
	else if (DoublesAreNearlyEqual(inScale, 200.0))		stringID = 24;	//	"1:200";
	else if (DoublesAreNearlyEqual(inScale, 500.0))		stringID = 25;	//	"1:500";
	else if (DoublesAreNearlyEqual(inScale, 1000.0))	stringID = 39;	//	"1:1000";
	else if (DoublesAreNearlyEqual(inScale, 5000.0))	stringID = 40;	//	"1:5000";
	else if (DoublesAreNearlyEqual(inScale, 10000.0))	stringID = 41;	//	"1:10000";
	else if (DoublesAreNearlyEqual(inScale, 50000.0))	stringID = 42;	//	"1:50000";

	else if (DoublesAreNearlyEqual(inScale, 0.5))		stringID = 26;	//	"2x";
	else if (DoublesAreNearlyEqual(inScale, 1.0/3.0))	stringID = 27;	//	"3x";	// XXX JDW MISC - this and /6 fail to make nice string; investigate
	else if (DoublesAreNearlyEqual(inScale, 0.25))		stringID = 28;	//	"4x";
	else if (DoublesAreNearlyEqual(inScale, 0.2))		stringID = 29;	//	"5x";
	else if (DoublesAreNearlyEqual(inScale, 1.0/6.0))	stringID = 30;	//	"6x";
	else if (DoublesAreNearlyEqual(inScale, 0.125))		stringID = 31;	//	"8x";
	else if (DoublesAreNearlyEqual(inScale, 0.1))		stringID = 32;	//	"10x";
	else if (DoublesAreNearlyEqual(inScale, 1.0/15.0))	stringID = 33;	//	"15x";
	else if (DoublesAreNearlyEqual(inScale, 0.05))		stringID = 34;	//	"20x";
	else if (DoublesAreNearlyEqual(inScale, 0.02))		stringID = 35;	//	"50x";
	else if (DoublesAreNearlyEqual(inScale, 0.01))		stringID = 36;	//	"100x";
	else if (DoublesAreNearlyEqual(inScale, 0.005))		stringID = 37;	//	"200x";
	else 												stringID = 38;	//	"1:^0"
	
	Str255 str;
	RsrcMgr::GSGetIndString(str, kMessageListID, stringID);

	if (stringID == 38)	{
		// below code from GetScale_NewPap(inScale, 0, &env);... could be improved			Terrible naming
		Str255						s;
		decform 					f;

		f.digits = 3;
		f.style = (inScale < 0.001 || inScale >= 1000.0) ? FLOATDECIMAL : FIXEDDECIMAL;
		Num2IntlStr(f, inScale, s);
		TXString str2(str);
		TXString temp(s);
		str2.Replace("^0", (const char*)temp);
		
		return str2;
	}
	else {
		return TXString(str);
	}
	
	return str;
}
*/