

// ##########################################################################
// #                                                                        #
// #                             ExtNumberEditor                            #
// #                                                                        #
// #                            - Definitionen -                            #
// #                                                                        #
// ##########################################################################



#include"gui/extnumed.h"
#include"ui/cntroler.h"


// **************************************************************************
// *                             OBJEKT-HANDLING                            *
// **************************************************************************



// ************
// Konstruktion
// ************


ExtNumberEditor :: ExtNumberEditor(UI_VObjCollection*  parent,
											  const UI_Rectangle& shape,
											  UI_ViewID           id,
											  unsigned            range,
											  unsigned            pr,
											  char                sep,
											  bool                sgn
											 )
					  : UI_StringEditor (parent, shape, id),
						 Cnv             (range,pr,sep,sgn)
{
  Maximum   = 0;
  Minimum   = 0;
  MaxDef    = FALSE;
  MinDef    = FALSE;
  initModel(0);
};



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

// Destruktion
// ***********


ExtNumberEditor :: ~ExtNumberEditor()
{};


// ****************
//  Initialisierung
// ****************


void ExtNumberEditor :: Initialize()
{
  UI_StringEditor::Initialize();
  limitLength ();
  return;
};


void ExtNumberEditor :: _PrivateInitialize ()
{
	 UI_StringEditor::_PrivateInitialize ();
	 _insertPos = -1; // Force cursor to be at left end
	 return;
};


// ****************
// Attributszugriff
// ****************


StringConverter& ExtNumberEditor :: cnv()
{
  return Cnv;
};


double ExtNumberEditor :: get_Minimum () const
{

  return Minimum;

};



void   ExtNumberEditor :: set_Minimum (double m)

{

  Minimum = m;

  MinDef  = TRUE;

  return;

};



double ExtNumberEditor :: get_Maximum () const

{

  return Maximum;

};



void   ExtNumberEditor :: set_Maximum (double m)

{

  Maximum = m;

  MaxDef  = TRUE;

  return;

};



// **************************************************************************
// *                             VIEW-HANDLING                              *
// **************************************************************************





// **************************************************************************
// *                            EVENT-HANDLING                              *
// **************************************************************************



bool ExtNumberEditor :: KeyTyped(char c)
{
  bool res = UI_StringEditor::KeyTyped(c);
  double x = Cnv.asDouble( (CL_String&)(Model()) );
  if (valueCorrection(x))
		InsertionPosition() = -1;
  sendEvent();
  return res;
};



void ExtNumberEditor :: sendEvent()
{
  UI_Event* e = new UI_Event(Event_StrEdChanged,this);
  _Controller->AddEvent (e);
  return;
};



// **************************************************************************
// *                            MODEL-HANDLING                              *
// **************************************************************************



bool ExtNumberEditor :: initModel(double x)
{
  bool      res = FALSE;
  CL_String s   = "";
  valueCorrection(x);
  if (Cnv(x,s))
	{
	  res = TRUE;
	  s.ReplaceAll(" ","");
	  ((CL_String&)(Model())) = s;
	};
  return res;
};


double ExtNumberEditor :: asDouble()
{
  return Cnv.asDouble((CL_String&)(Model()));
};


long int ExtNumberEditor :: asLong()
{
  return Cnv.asLong((CL_String&)(Model()));
};


bool ExtNumberEditor :: valueCorrection(double& x) const
{

  bool res = FALSE;

  if (!withinBounds(x))

	{

	  res = TRUE;

	  if (x > Maximum)

		  x = Maximum;

	  else if (x < Minimum)

				 x = Minimum;

	};

  return res;
};


bool   ExtNumberEditor :: hasMinimum  () const
{

  return MinDef;

};



bool   ExtNumberEditor :: hasMaximum  () const

{

  return MaxDef;

};



bool   ExtNumberEditor :: withinBounds(double x) const

{

  if (  (MinDef && x < Minimum)

	  || (MaxDef && x > Maximum)

	  )

		 return FALSE;

  else return TRUE;

};



void   ExtNumberEditor :: disableMaximum ()

{

  MaxDef  = FALSE;

  return;

};



void   ExtNumberEditor :: disableMinimum ()

{

  MinDef  = FALSE;

  return;

};


bool ExtNumberEditor::FilterChar (short& key)
{
	 bool b = FALSE;

	 CL_Integer& pos = InsertionPosition();
	 if (pos >= Cnv.size())
		  return FALSE; // Disallow appending

	 if (   (key < 32 || key > 126)                        // control key
		  || (key >= '0' && key <= '9' && precisionOk(pos)) // digit
		  || (key == Cnv.separator()   && separatorOk(pos)) // comma or point
		  || (key == '-'               && signOk(pos))      // sign
		 )
			b = TRUE;

	 CL_String& model = (CL_String&)  Model();
	 short n =  model.Size();
	 if (n >= Cnv.size() && pos >= 0 && pos < n)
	 {
		  short savePos = pos;
		  model.Delete (pos, 1); // Delete the character to the right
		  pos = savePos;         // Needed because the above change in model
										 // can alter the cursor position
	 };

	 if (!b)
		  _Controller->Beep();
	 return  b;
};


bool ExtNumberEditor :: precisionOk(CL_Integer& pos)
{
  bool res = FALSE;
  long int cp = commaPos();
  long int pr = (long int&)Cnv.precision();
  long int rg = (long int&)Cnv.range();
  if (cp == -1 && pos < rg)
	  res = TRUE;
  else
	{
	 if (pos < cp)
		res = ( cp - pos <= rg);
	 else if (cp < pos)
			  res = ( pos - cp <= pr);
    };
  return res;
};


long int ExtNumberEditor :: commaPos()
{
  return ((CL_String&)Model()).CharIndex(Cnv.separator());
};


bool ExtNumberEditor :: separatorOk(CL_Integer& pos)
{
  bool res = FALSE;
  if (Cnv.precision() > 0)
	{
	  int sep = ((CL_String&)Model()).CharIndex(Cnv.separator());
	  if (sep == -1)
			res = TRUE;
	  else if (sep == pos)
			  {
				 pos++;
				 res = TRUE;
			  };
	};
  return res;
};


bool ExtNumberEditor :: signOk(CL_Integer& pos)
{
  bool res = FALSE;
  if (Cnv.sign() && pos == 0)
	{
	  int sgn = ((CL_String&)Model()).CharIndex('-');
	  if (sgn == -1)
			  res = TRUE;
		else res = FALSE;
	};
  return res;
};


void ExtNumberEditor :: limitLength()
{
  SetLengthLimit(Cnv.size());
  return;
};

