
#include <stdio.h>

#include "floatstr_t.h"

// Class FloatStr
void FloatStr::Init(float In_Value, float In_Min_Value, float In_Max_Value, float In_StepSize, int In_AfterDot, int In_MaxLength, char In_Text[20], char In_PreText[10], char In_Unit[5])
{
	Value        = In_Value;
	Stored_Value = In_Value;
	Min_Value    = In_Min_Value;
	Max_Value    = In_Max_Value;
	StepSize     = In_StepSize;
	AfterDot     = In_AfterDot;
	MaxLength    = In_MaxLength;
	
	sprintf(Text, "%s", In_Text);
	
	sprintf(PreText, "%s", In_PreText);
	
	sprintf(Unit, "%s", In_Unit);
	
	sprintf(DimensionUnit, "");
	
	RenderText();
	
}

float FloatStr::Read_Value(void)
{
	return Value;
}

void FloatStr::Write_Value(float In_Value)
{
	Value = In_Value;
}

float FloatStr::Read_Stored_Value(void)
{
	return Stored_Value;
}

void FloatStr::Write_Stored_Value(float In_Stored_Value)
{
	Stored_Value = In_Stored_Value;
}

float FloatStr::Read_Min_Value(void)
{
	return Min_Value;
}

void FloatStr::Write_Min_Value(float In_Min_Value)
{
	Min_Value = In_Min_Value;
}

float FloatStr::Read_Max_Value(void)
{
	return Max_Value;
}

void FloatStr::Write_Max_Value(float In_Max_Value)
{
	Max_Value = In_Max_Value;
}

float FloatStr::Read_StepSize(void)
{
	return StepSize;
}

void FloatStr::Write_StepSize(float In_StepSize)
{
	StepSize = In_StepSize;
}

int FloatStr::Read_AfterDot(void)
{
	return AfterDot;
}

void FloatStr::Write_AfterDot(int In_AfterDot)
{
	AfterDot = In_AfterDot;
}

int FloatStr::Read_MaxLength(void)
{
	return MaxLength;
}

void FloatStr::Write_MaxLength(int In_MaxLength)
{
	MaxLength = In_MaxLength;
}
//##########################################################################################################################################################
// BF several bugs fixed.
// Values are printed with after dot positions now. Fixed overflow and underrun and cleaned up
// the variable declarations in this routine.

void FloatStr::RenderText(void)
{
	
	char           Calc_AfterDot = AfterDot;
	volatile float Calc_Value    = Value;
	
	float floatad = 0;
	int   intbd   = 0;
	int   intad   = 0;

	
	if (Calc_Value == 0)
	{
		sprintf(Text, "%s 0.0 %s", PreText, Unit);
		return;
	}        	
	else if (Calc_Value > 0)
	{
		if (Calc_Value > 1)
		{ DimensionUnit[0] = ' '; }	

		if (Calc_Value < 1)
		{
			Calc_Value *= 1000;
			DimensionUnit[0] = 'm';
		}
		if (Calc_Value < 1)
		{
			Calc_Value *= 1000;
			DimensionUnit[0] = '&';	
		}
		if (Calc_Value < 1)
		{
			Calc_Value *= 1000;
			DimensionUnit[0] = 'n';	
		}				
		if (Calc_Value >= 1000)
		{
			Calc_Value /= 1000;
			DimensionUnit[0] = 'k';
		}
		if (Calc_Value >= 1000)
		{
			Calc_Value /= 1000;
			DimensionUnit[0] = 'M';
		}
		if (Calc_Value >= 1000)
		{
			Calc_Value /= 1000;
			DimensionUnit[0] = 'G';
		}
		if (Calc_Value >= 1000)		//Value is too big -> infinite
		{
			sprintf(Text, "%s *** %s", PreText, Unit);
			return;
		}

	}
	else if (Calc_Value < 0)
	{
		if (Calc_Value < -1)
		{ DimensionUnit[0] = ' '; }

		if (Calc_Value > -1)
		{
			Calc_Value *= 1000;
			DimensionUnit[0] = 'm';
		}
		if (Calc_Value > -1)
		{
			Calc_Value *= 1000;
			DimensionUnit[0] = '&';	
		}
		if (Calc_Value > -1)
		{
			Calc_Value *= 1000;
			DimensionUnit[0] = 'n';	
		}			
		if (Calc_Value <= -1000)
		{
			Calc_Value /= 1000;
			DimensionUnit[0] = 'k';
		}
		if (Calc_Value <= -1000)
		{
			Calc_Value /= 1000;
			DimensionUnit[0] = 'M';
		}
		if (Calc_Value <= -1000)
		{
			Calc_Value /= 1000;
			DimensionUnit[0] = 'G';
		}
		if (Calc_Value >= 1000)		//Value is too small -> Zero
		{
			sprintf(Text, "%s 0.0 %s", PreText, Unit);
			return;
		}
	}
	// Copy Float to Integer
	intbd = (int)Calc_Value;	//get before dot integer
		
	//check how many after dot positions are possible depending on maximum print length
	if (intbd > 0)
	{	
		if (intbd < 9)
		{
			if ((AfterDot + 1) > MaxLength) Calc_AfterDot = MaxLength - 1;
		}
		else if (intbd < 99)
		{
			if ((AfterDot + 2) > MaxLength) Calc_AfterDot = MaxLength - 2;
		}
		else
		{
			if ((AfterDot + 3) > MaxLength) Calc_AfterDot = MaxLength - 3;
		}
	}
	else
	{	
		if (intbd > -9)
		{
			if ((AfterDot + 1) > MaxLength) Calc_AfterDot = MaxLength - 1;
		}
		else if (intbd > -99)
		{
			if ((AfterDot + 2) > MaxLength) Calc_AfterDot = MaxLength - 2;
		}
		else
		{
			if ((AfterDot + 3) > MaxLength) Calc_AfterDot = MaxLength - 3;
		}
	}
		
	floatad = (float)(Calc_Value - intbd); 	//get after dot value as float - cut off before dot
	
	if(floatad < 0)
	{ floatad *= -1 ;}			//we don't need negative values after dot
	
	//convert after dot to integer (with 1-4 positions)
	switch(Calc_AfterDot)
	{	
		case 0: intad = (int)(floatad * 1); break;
		case 1: intad = (int)(floatad * 10); break;
		case 2: intad = (int)(floatad * 100); break;
		case 3: intad = (int)(floatad * 1000); break;
		case 4: intad = (int)(floatad * 10000); break;
	}
		
	//copy values to text string depending on positions after dot
	switch(Calc_AfterDot)
	{
		case 0: sprintf(Text, "%s%3d.0 %s%s", PreText, intbd, DimensionUnit, Unit); break;
		case 1: sprintf(Text, "%s%3d.%01d %s%s", PreText, intbd, intad, DimensionUnit, Unit); break;
		case 2: sprintf(Text, "%s%3d.%02d %s%s", PreText, intbd, intad, DimensionUnit, Unit); break;
		case 3: sprintf(Text, "%s%3d.%03d %s%s", PreText, intbd, intad, DimensionUnit, Unit); break;
		case 4: sprintf(Text, "%s%3d.%04d %s%s", PreText, intbd, intad, DimensionUnit, Unit); break;
	}  
	
}

char* FloatStr::Read_Text(void)
{
	return(&Text[0]);
}

char* FloatStr::Read_PreText(void)
{
	return(&PreText[0]);
}

void FloatStr::Write_PreText(char In_PreText[10])
{
	sprintf(PreText, "%s", In_PreText);
}

char* FloatStr::Read_Unit(void)
{
	return(&Unit[0]);
}

void FloatStr::Write_Unit(char In_Unit[5])
{
	sprintf(Unit, "%s", In_Unit);
}

void FloatStr::DoStep(char Direction)
{
	float Calc_Value = Value;
/*	
	if (Calc_Value < 0.000001) StepSize = 0.000000005;
	else
	{
		StepSize = 0.01;
		while (Calc_Value < 1)
		{
			Calc_Value = Calc_Value * 10;
			StepSize = StepSize / 10;
		}
	}
*/	
	if (Direction == 1)
	 { if (Value < Max_Value) Value = Value + StepSize; }
	else
	 { if (Value > Min_Value) Value = Value - StepSize; }
}
/*BF
void FloatStr::floatprintf(float fvalue)
{
	long int pre, aft,factor;
	int i;
	
	//calculating pre FP value
	pre = (long int)fvalue;
	if(pre == 0 && fvalue < 0)	//negativ
		printf("-%d.",pre);
	else
		printf("%d.",pre);
		
	//get leading zero
	if((fvalue - pre) != 0) //check if numbers after FP exist
	{
		for(factor = 10, i= 0 ;0 == (long int)((fvalue - pre) * factor) && i<11; factor*=10, i++)
		{ printf("0"); }
	}
	else
	{	
		printf("000");
		return;
	}
	
	//calc after FP value, minimum 3 numbers after FP
	aft = (long int)((fvalue - pre) * factor * 100);
	
	if(aft < 0)	//kill sign
	{ aft *= -1; }

	printf("%d",aft);

	if(i >= 11)
	printf("overflow");

}
*/

