// AsNumericEdit.cpp : implementation file
//

#include "stdafx.h"
#include "AsNumericEdit.h"

/*
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
*/

/////////////////////////////////////////////////////////////////////////////
// CAsNumericEdit

CAsNumericEdit::CAsNumericEdit():
	minMaxCheckEnable_(false),
	minValue_(0),
	maxValue_(0),
	precision_(1),
	decimalSeparator_('.')
{
}

CAsNumericEdit::~CAsNumericEdit()
{
}


BEGIN_MESSAGE_MAP(CAsNumericEdit, CEdit)
	//{{AFX_MSG_MAP(CAsNumericEdit)
	ON_WM_CHAR()
	ON_CONTROL_REFLECT(EN_KILLFOCUS, OnKillfocus)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CAsNumericEdit message handlers

void CAsNumericEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	if ((char)nChar == decimalSeparator_) {
		CString tmp;
		int pos;

		if (precision_ == 0)	// precision_ == 0 means integer value
			return;

		GetWindowText(tmp);

		pos = tmp.Find(decimalSeparator_);
		if (pos != -1)
			return;

	} else if (nChar == '-') {
		CString tmp;

		GetWindowText(tmp);

		if (minMaxCheckEnable_ && minValue_ >= 0)
			return;

	} else if (nChar >= '0' && nChar <= '9' ||
			   nChar == VK_BACK ||
			   nChar == VK_LEFT	||
			   nChar == VK_RIGHT ||
			   nChar == VK_DELETE) {
		
	} else if (nChar == VK_RETURN) {
		Validate();
	} else {
		// any other invalid char
		//
		return;
	}
	
	CEdit::OnChar(nChar, nRepCnt, nFlags);
}

void CAsNumericEdit::SetMinValue(double minValue)
{
	minValue_ = minValue;
}

double CAsNumericEdit::GetMinValue() const
{
	return minValue_;
}

void CAsNumericEdit::SetMaxValue(double maxValue)
{
	maxValue_ = maxValue;
}

double CAsNumericEdit::GetMaxValue() const
{
	return maxValue_;
}

void CAsNumericEdit::SetPrecision(int precision)
{
	if (precision < 0)
		precision = 0;

	precision_ = precision;
}

int CAsNumericEdit::GetPrecision() const
{
	return precision_;
}

void CAsNumericEdit::SetMinMaxCheckEnable(bool enable)
{
	minMaxCheckEnable_ = enable;
}

bool CAsNumericEdit::GetMinMaxCheckEnable() const
{
	return minMaxCheckEnable_;
}

double CAsNumericEdit::GetValue()
{
	Validate();

	CString tmp;

	GetWindowText(tmp);
	
	return atof((const char*)tmp);;
}

double CAsNumericEdit::Validate()
{
	CString tmp;
	double value;

	GetWindowText(tmp);

	value = ValidateString(tmp);

	tmp = FormatValue(value);
		
	SetWindowText(tmp);

	return value;
}

void CAsNumericEdit::OnKillfocus() 
{
	Validate();	
}

double CAsNumericEdit::ValidateString(const CString& valueStr)
{
	double value;

	value = atof((const char*)valueStr);

	return ValidateValue(value);
}

double CAsNumericEdit::ValidateValue(double value)
{
	if (minMaxCheckEnable_) {
		value = min(value, maxValue_);
		value = max(value, minValue_);
	}

	return value;
}

CString CAsNumericEdit::FormatValue(double value)
{
	CString tmp;
	CString fmt;

	fmt.Format("%%1.%df", precision_);
	tmp.Format(fmt, value);

	return tmp;
}

void CAsNumericEdit::SetValue(double value)
{
	value = ValidateValue(value);

	SetWindowText(FormatValue(value));
}
