/******************************************************************************
 JXFloatInput.cc

	Maintains a line of editable text for entering a floating point value.

	BASE CLASS = JXInputField

	Copyright © 1996 by John Lindal. All rights reserved.

 ******************************************************************************/

#include <JXFloatInput.h>
#include <jXGlobals.h>
#include <JString.h>
#include <jAssert.h>

/******************************************************************************
 Constructor

 ******************************************************************************/

JXFloatInput::JXFloatInput
	(
	JXContainer*		enclosure,
	const HSizingOption	hSizing,
	const VSizingOption	vSizing,
	const JCoordinate	x,
	const JCoordinate	y,
	const JCoordinate	w,
	const JCoordinate	h
	)
	:
	JXInputField(enclosure, hSizing, vSizing, x,y, w,h)
{
	SetIsRequired();
	itsHasLowerLimitFlag = itsHasUpperLimitFlag = kFalse;
	SetValue(0.0);
}

/******************************************************************************
 Destructor

 ******************************************************************************/

JXFloatInput::~JXFloatInput()
{
}

/******************************************************************************
 GetValue

 ******************************************************************************/

JBoolean
JXFloatInput::GetValue
	(
	JFloat* value
	)
	const
{
	const JString& text = GetText();
	return JConvertToBoolean(text.ConvertToFloat(value) && ValueValid(*value));
}

/******************************************************************************
 SetValue

 ******************************************************************************/

void
JXFloatInput::SetValue
	(
	const JFloat value
	)
{
	if (ValueValid(value))
		{
		const JString text = value;
		if (text != GetText())
			{
			SetText(text);
			}
		}
}

/******************************************************************************
 Set limits

 ******************************************************************************/

void
JXFloatInput::SetLimits
	(
	const JFloat minValue,
	const JFloat maxValue
	)
{
	assert( minValue < maxValue );
	SetLowerLimit(minValue);
	SetUpperLimit(maxValue);
}

void
JXFloatInput::SetLowerLimit
	(
	const JFloat minValue
	)
{
	assert( !itsHasUpperLimitFlag || minValue < itsUpperLimit );

	itsHasLowerLimitFlag = kTrue;
	itsLowerLimit = minValue;

	JFloat x;
	if (!GetValue(&x))
		{
		SetValue(itsLowerLimit);
		}
}

void
JXFloatInput::SetUpperLimit
	(
	const JFloat maxValue
	)
{
	assert( !itsHasLowerLimitFlag || itsLowerLimit < maxValue );

	itsHasUpperLimitFlag = kTrue;
	itsUpperLimit = maxValue;

	JFloat x;
	if (!GetValue(&x))
		{
		SetValue(itsUpperLimit);
		}
}

/******************************************************************************
 InputValid (virtual)

 ******************************************************************************/

JBoolean
JXFloatInput::InputValid()
{
	if (!JXInputField::InputValid())
		{
		return kFalse;
		}
	else
		{
		const JString& text = GetText();

		if (!IsRequired() && text.IsEmpty())
			{
			return kTrue;
			}

		JFloat value;
		if (!text.ConvertToFloat(&value))
			{
			(JGetUserNotification())->ReportError("This field accepts only numbers.");
			return kFalse;
			}

		const JBoolean valid = ValueValid(value);
		if (!valid && itsHasLowerLimitFlag && itsHasUpperLimitFlag)
			{
			JString errorStr  = "This field accepts only numbers between ";
			errorStr += JString(itsLowerLimit);
			errorStr += " and ";
			errorStr += JString(itsUpperLimit);
			errorStr += " inclusive.";
			(JGetUserNotification())->ReportError(errorStr);
			}
		else if (!valid && itsHasLowerLimitFlag)
			{
			JString errorStr  = "This field accepts only numbers greater than or equal to ";
			errorStr += JString(itsLowerLimit);
			errorStr += ".";
			(JGetUserNotification())->ReportError(errorStr);
			}
		else if (!valid && itsHasUpperLimitFlag)
			{
			JString errorStr  = "This field accepts only numbers less than or equal to ";
			errorStr += JString(itsUpperLimit);
			errorStr += ".";
			(JGetUserNotification())->ReportError(errorStr);
			}
		return valid;
		}
}
