/* 
	this C++/MFC code is public domain. 

	It is the core of CopierScale, a freeware program that you can find here: 
	http://www.nutsnbits.com/copierscale.htm
	A look to the program interface should hopefully let you understand easily
	what all this is about and what to put in the C++ variables.
		
	As the author of this code, I would appreciate a notification and/or my name 
	written somewhere if you do something useful with it, but that is not mandatory.

	Daniel Munoz - www.nutsnbits.com - daniel@nutsnbits.com
*/


UINT	m_iZoomMax;
UINT	m_iZoomMin;
CString	m_sResult;
float	m_fInputDenom;
float	m_fInputNum;
float	m_fOutputDenom;
float	m_fOutputNum;


BOOL Identical (float f1, float f2, float epsilon=20*FLT_EPSILON)
{
	if (f1 == 0 || f2 == 0) 
		return f1==f2;
	return (fabs(f1)>fabs(f2)? fabs(f2/f1-1) : fabs(f1/f2-1)) < epsilon;
}


void ComputeResultToString() 
{
	// TODO: Add your control notification handler code here
	if (UpdateData (TRUE))
	{
		if ((m_fInputNum<=0) ||
			(m_fInputDenom<=0) ||
			(m_fOutputNum<=0) ||
			(m_fOutputDenom<=0))
		{
			AfxMessageBox ("Please use positive values");
			return;
		}

		m_sResult.Empty ();
		
		float fInput=m_fInputNum/m_fInputDenom;
		float fOutput=m_fOutputNum/m_fOutputDenom;
		float fZoom=fOutput/fInput;
		float fMin=(float) m_iZoomMin/100.f;
		float fMax=(float) m_iZoomMax/100.f;

		if ((fZoom>=fMin) && (fZoom<=fMax))
		{
			int iZoom=(int) (fZoom*100.f+0.5f);
			CString line;
			line.Format ("Single step : Use %d%% on original", iZoom);
			m_sResult+=line+"\r\n";
			if (!Identical((float) iZoom/100.f,fZoom))
			{
				line.Format ("(exact value should be %f%%)",fZoom*100.f);
				m_sResult+=line+"\r\n";
			}
		}
		else
		{
			BOOL bExit=FALSE;
			for (int i=1;!bExit;i++)
			{
				if (i>100)
				{
					m_sResult="Error : Aborting !";
					break;
				}

				float fCurrent=fZoom;
				if (fCurrent<fMin)
					fCurrent=fMin;
				else if (fCurrent>fMax)
					fCurrent=fMax;
				else 
					bExit=TRUE;

				int iCurrent=(int) (fCurrent*100.f+0.5f);

				CString line;
				line.Format ("Step %d : Use %d%% on %s", i, iCurrent, (i==1) ? "original" : "result");
				m_sResult+=line+"\r\n";

				if ((bExit) && !Identical((float) iCurrent/100.f,fCurrent))
				{
					line.Format ("(exact value should be %f%%)",fCurrent*100.f);
					m_sResult+=line+"\r\n";
				}

				fZoom/=(float) iCurrent/100.f;
			}
		}
		
		UpdateData (FALSE);
	}
}

