// <script>

// global constants
var NULLABLE = -1;
var NOT_NULLABLE = 0;
var KEY_ENTER = 13;
var TRAP_ENTER = -1;

var g_FormCtrlObj;

function imkFormControl(strFormName,isCheckForEnter)
{

  // public methods
  this.AddField         = imkAddField;
  this.ValidateForm     = imkValidateForm;
  this.Init             = imkFormControlInit;
  this.Submit           = null;
  // private methods
  this._InitFields      = imkInitFields;
  this._CheckEnter      = imkFormCheckEnter;
  this._RotateFocus     = imkFormRotateFocus;
  this._Submit          = null;

  // public properties
  this.Name              = strFormName;
  // private properties
  this._TheFields        = new Object();
  this._TheForm          = null;
  this._NumFields        = -1;
  this._IsCheckForEnter  = Boolean(isCheckForEnter);
  
  if (this._IsCheckForEnter && g_FormCtrlObj)
    alert("imkFormValidLib is only able to trap the enter key for one form object per page.  Library will not properly function.");
  
  g_FormCtrlObj = this;
}

function imkFormControlInit(CustomSubmitFunc, CustomEnterCheckFunc)
{
  this._TheForm = (this.Name.search(/document\./) != -1) ? eval(this.Name) : eval("document." + this.Name);
  if (this._IsCheckForEnter)
  {
    if (IsNN4)
      document.captureEvents(Event.KEYPRESS);

    document.onkeypress = (IsEmpty(CustomEnterCheckFunc)) ? this._CheckEnter : eval(CustomEnterCheckFunc);
  }
  this.Submit = this._TheForm.submit;
  this._Submit = (IsEmpty(CustomSubmitFunc) ? new Function("if (!this.ValidateForm) return; this.Submit();") : eval(CustomSubmitFunc));
  this._InitFields();
}

function imkAddField(strFieldName,strFormFieldName,initValue,strFieldType,intFieldLength,isNullable)
{
  this._TheFields[++this._NumFields] = new imkField(strFieldName,strFormFieldName,initValue,strFieldType,intFieldLength,isNullable,this._NumFields, this);
  this._TheFields[strFormFieldName] = this._TheFields[this._NumFields];
}

function imkInitFields()
{
  for (var i = 0; i <= this._NumFields; i++)
    this._TheFields[i]._Init();
}

function imkValidateForm()
{
  for (var i = 0; i <= this._NumFields; i++)
  {
    if (!this._TheFields[i]._Validate())
    {
      switch (this._TheFields[i]._Type)
      {
        case 'byte':
          alert("Enter a whole number between 0 and 255 for " + this._TheFields[i]._Label + ".");
          break;
        case 'uint':
          alert("Enter a whole number between 1 and 65535 for " + this._TheFields[i]._Label + ".");
          break;
        case 'int':
          alert("Enter a whole number between -32768 and 32767 for " + this._TheFields[i]._Label + ".");
          break;
        case 'long':
          alert("Enter a whole number between -2147483648 and 2147483647 for " + this._TheFields[i]._Label + ".");
          break;
        case 'sng':
          alert("Enter a decimal number with up to 7 digits for " + this._TheFields[i]._Label + ".");
          break;
        case 'dbl':
          alert("Enter a decimal number with up to 15 digits for " + this._TheFields[i]._Label + ".");
          break;
        case 'radio':
          alert("Select an option for: " + this._TheFields[i]._Label + ".");
          break;
        case 'text':
          if (this._TheFields[i]._IsNullable)
            alert("Enter no more than " + this._TheFields[i]._Length + " characters for " + this._TheFields[i]._Label + ".");
          else
            alert(this._TheFields[i]._Label + " can not be empty and must have fewer than " + this._TheFields[i]._Length + " characters.");
          break;
        case 'list':
          if (this._TheFields[i]._IsMultiple)
            alert("Select one or more options for " + this._TheFields[i]._Label + ".");
          else
            alert("Select an option for " + this._TheFields[i]._Label + ".");
          break;
        default:
          alert("Invalid entry in " + this._TheFields[i]._Label + ".");
      } // end of switch
      if (this._TheFields[i]._Type == 'radio')
      {
        if (this._TheFields[i]._FormFieldObj.length)
          this._TheFields[i]._FormFieldObj[0].focus();
        else
          this._TheFields[i]._FormFieldObj.focus();
      }
      else
      {
        this._TheFields[i]._FormFieldObj.focus();
      }
      return false;
    } // end of if (!this._TheFields[i].Validate())
  } // end of for (var i = 0; i <= this.NumFields; i++)
  return true;
}

function imkFormCheckEnter(evt)
{
  if (IsIE4 == true)
  {
    if (window.event.keyCode == KEY_ENTER)
    {
      g_FormCtrlObj._RotateFocus(window.event.srcElement.id)
      return false; // stop processing this event
    }
  }
  else
  {
    if (evt.which == KEY_ENTER)
      g_FormCtrlObj._RotateFocus(evt.target.name);
    else
      routeEvent(evt); // don't stop processing
  }
}

function imkFormRotateFocus(FormField)
{
  var id = g_FormCtrlObj._TheFields[FormField]._id;
  
  if (id <= g_FormCtrlObj._NumFields)
  {
    for (++id ; id <= g_FormCtrlObj._NumFields ; ++id)
    {
      if (g_FormCtrlObj._TheFields[id]._Type != 'hidden')
      {
        g_FormCtrlObj._TheFields[id]._FormFieldObj.focus();
        return;
      }
    }
  }

  g_FormCtrlObj._Submit();
}

function imkField(strFieldName,strFormFieldName,initValue,strFieldType,intFieldLength,isNullable,id,objFormCtrl)
{
  // this entire object is private and internal to the library only
  // set properties
  this._Label           = strFieldName;
  this._FormFieldName   = strFormFieldName;
  this._Value           = imkTrim(initValue);
  this._Values          = new Object(); // for use with selection lists only and ultimately checkboxes
  this._Type            = strFieldType;
  this._Length          = intFieldLength;
  this._IsNullable      = Boolean(isNullable);
  this._Ctrl            = objFormCtrl;
  this._FormFieldObj    = null;
  this._GetFormFieldObj = imkGetFormFieldObj;
  this._id              = id;
  this._IsMultiple      = null;  // for use with selection lists only and ultimately checkboxes

  // set strFieldType
  switch (strFieldType)
  {
    case 'byte':
      this._Validate  = imkValidateByte;
      this._Init      = imkInitField;
      break;
    case 'int':
      this._Validate  = imkValidateInt;
      this._Init      = imkInitField;
      break;
    case 'uint':
      this._Validate  = imkValidateUInt;
      this._Init      = imkInitField;
      break;
    case 'long':
      this._Validate  = imkValidateLong;
      this._Init      = imkInitField;
      break;
    case 'sng':
      this._Validate  = imkValidateSingle;
      this._Init      = imkInitField;
      break;
    case 'dbl':
      this._Validate  = imkValidateDouble;
      this._Init      = imkInitField;
      break;
    case 'text':
      this._Validate  = imkValidateText;
      this._Init      = imkInitField;
      break;
    case 'hidden':
      this._Validate  = new Function("return true");
      this._Init      = imkInitField;
      break;
    case 'radio':
      this._Validate  = imkValidateRadio;
      this._Init      = imkInitFieldRadio;
      break;
    case 'list':
      this._Validate  = imkValidateList;
      this._Init      = imkInitList;
      break;
    default:
      alert("Invalid Field Type");
      this._Validate  = new Function("return true");
      this._Init      = imkInitField;
  }

}

function imkInitField()
{
  this._GetFormFieldObj();
  this._FormFieldObj.value = this._Value;
  this._Ctrl[this._FormFieldName] = this._FormFieldObj;
}

function imkInitList()
{
  this._GetFormFieldObj();
  this._Ctrl[this._FormFieldName] = this._FormFieldObj;

  this._IsMultiple = (this._FormFieldObj.type == "select-one" ? false : true);
  
  var i = 0;
  
  if (this._FormFieldObj.length)
  {
    var len = this._FormFieldObj.length;
    if (!this.IsMultiple)
    {
      for (; i < len; i++)
      {
        if ((this._FormFieldObj.options[i].value == this._Value) || (this._FormFieldObj.options[i].text == this._Value))
        {
          this._FormFieldObj.selectedIndex = i;
          break;
        }
      }
    }
    else
    {
      var arr_Values = this._Value.split("|");
      for ( ; i < arr_Values.length; i++)
        this._Values[arr_Values[i]] = arr_Values[i];
        
      for (i = 0; i < len; i++)
        if (this._Values[this._FormFieldObj.options[i].value] || this.Values[this._FormFieldObj.options[i].text])
          this._FormFieldObj.options[i].selected = true;
    }
  }
}

function imkValidateList()
{
  for (var i = 0, len = this._FormFieldObj.length; i < len; i++)
    if (this._FormFieldObj.options[i].selected)
      return true;
  return (this._IsNullable ? true : false);
}

function imkInitFieldRadio()
{
  this._GetFormFieldObj();
  this._Ctrl[this._FormFieldName] = this._FormFieldObj;

  if (this._FormFieldObj.length)
  {
    for (var i = 0; i < this._FormFieldObj.length; i++)
    {
      if (this._FormFieldObj[i].value == this._Value)
      {
        this._FormFieldObj[i].checked = true;
        break;
      } // if (this._FormFieldObj.value == this.Value)
    } // for (var i = 0; i < this._FormFieldObj.length; i++)
  } // if (this._FormFieldObj.length)
  else
  {
    if (this._FormFieldObj.value == this.Value)
      this._FormFieldObj.checked = true;
  }
}

function imkValidateRadio()
{
  if (GetRadioValue(this._FormFieldObj))
    return true;
  return false;
}

function imkValidateText()
{
  if (this._FormFieldObj.value.length > this._Length)
    return false;
  if (!this._IsNullable && IsEmpty(this._FormFieldObj.value))
    return false;
  return true;
}

function imkValidateSingle()
{

  if (isNaN(this._FormFieldObj.value))
    return false;
  if (this._FormFieldObj.value.search(/\./) != -1)
  {
    if (this._FormFieldObj.value.length > 8)
      return false;
  }
  else
  {
    if (this._FormFieldObj.value.length > 7)
      return false;
  }
  if (!this._IsNullable && IsEmpty(this._FormFieldObj.value))
    return false;
  return true;
}

function imkValidateDouble()
{
  if (isNaN(this._FormFieldObj.value))
    return false;

  if (this._FormFieldObj.value.search(/\./) != -1)
  {
    if (this._FormFieldObj.value.length > 16)
      return false;
  }
  else
  {
    if (this._FormFieldObj.value.length > 15)
      return false;
  }

  if (!this._IsNullable && IsEmpty(this._FormFieldObj.value))
    return false;

  return true;
}

function imkValidateByte()
{
  if (isNaN(this._FormFieldObj.value))
    return false;

  if (!this._IsNullable && IsEmpty(this._FormFieldObj.value))
    return false;

  if (this._FormFieldObj.value < 0 || this._FormFieldObj.value > 255)
    return false;

  return true;
}

function imkValidateInt()
{
  if (isNaN(this._FormFieldObj.value))
    return false;

  if (!this._IsNullable && IsEmpty(this._FormFieldObj.value))
    return false;

  if (this._FormFieldObj.value < -32768 || this._FormFieldObj.value > 32767)
    return false;

  return true;
}

function imkValidateUInt()
{
  if (isNaN(this._FormFieldObj.value))
    return false;

  if (!this._IsNullable && IsEmpty(this._FormFieldObj.value))
    return false;

  if (this._FormFieldObj.value < 1 || this._FormFieldObj.value > 65536)
    return false;

  return true;
}

function imkValidateLong()
{
  if (isNaN(this._FormFieldObj.value))
    return false;

  if (!this._IsNullable && IsEmpty(this._FormFieldObj.value))
    return false;

  if (this._FormFieldObj.value < -2147483648 || this._FormFieldObj.value > 2147483647)
    return false;

  return true;
}

function imkGetFormFieldObj()
{
  this._FormFieldObj = (this._Ctrl._TheForm != null) 
                        ? this._Ctrl._TheForm[this._FormFieldName] 
                        : ((this._Ctrl.Name.search(/document\./) != -1) 
                            ? eval(this._Ctrl.Name + "." + this._FormFieldName) 
                            : eval("document." + this._Ctrl.Name + "." + this._FormFieldName));
}

function GetRadioValue(RadioObject)
{
  var ValueChecked = null;
  if (RadioObject.length)
  {
    // there is more than one radio button
    for (var i = 0; i < RadioObject.length; i++)
      if (RadioObject[i].checked)
        ValueChecked = RadioObject[i].value;
    
  }
  else
  {
    // there is only one radio button and the length is undefined
    if (RadioObject.checked)
      ValueChecked = RadioObject.value;
  }
  return ValueChecked;
}


// supporting functions good for registration pages

function IsValidUsername(Username)
{
  var illegalFirstChars = "_.0123456789";
  var firstChar = Username.substring(0,1);
  var search = illegalFirstChars.indexOf(firstChar);
  var userlen = Username.length
  if (userlen < 5) // username too short
    return false;
  if (search != -1) // illegal character found in first positon
    return false;
  if (HasBadCharacters(Username)) // illegal characters found within the string
    return false;
  return true;
}

function IsValidPasswordCombo(Password,Password2)
{
  if (Password.length < 5)
    return false;
  if (Password != Password2)
    return false;
  if (ContainSpaces(Password))
    return false;
  return true;
}

function IsEmailValid(str_address) 
{ 
  str_address = str_address.toString();
  var isEmail = str_address.match(/^([A-Za-z0-9_-]+[.]?)+@[A-Za-z0-9_.-]+\.(((com|net|org|edu|gov|mil|biz|info|pro|coop|aero|museum|name|[a-z]{2})$)|(((com|net|org|edu|gov|mil|biz|info|pro|coop|aero|museum|name)\.[a-z]{2})$))/); 

  return (!isEmail ? false : true);
} 


/*
// Blown away in favor of a regular expression based test
function IsEmailValid(EmailAddress)
{
  var AtSym       = EmailAddress.indexOf('@');
  var AtSymArray  = EmailAddress.split('@');
  var AtSymPeriod = EmailAddress.indexOf('@.');
  var Periods     = EmailAddress.indexOf('..')
  var FirstPeriod = EmailAddress.indexOf('.')
  var LastPeriod  = EmailAddress.lastIndexOf('.');
  var SglQuot     = EmailAddress.indexOf("'");
  var DblQuot     = EmailAddress.indexOf('"');
  var Length      = EmailAddress.length - 1;   // Array is from 0 to length-1

//  alert("At Sym " + AtSym + "\nPeriod " + Period + "\nSpace " + Space + "\nLength " + Length + "\nAtSymArray " + AtSymArray.length);

  if ((AtSym < 1) ||                    // '@' cannot be in first position
      (LastPeriod <= AtSym+1) ||        // Must be at least one valid char btwn '@' and '.'
      (LastPeriod == Length-1) ||       // Must be at least two valid char after last '.'
      (LastPeriod < Length-3) ||        // Cannot be any more than three chars after last '.'
      (Periods != -1) ||                // Cannot have two '.' in a row
      (ContainSpaces(EmailAddress)) ||  // No empty spaces permitted
      (SglQuot != -1) ||                // not single quotes permitted
      (DblQuot != -1) ||                // not double quotes permitted
      (AtSymArray.length > 2) ||        // More than one '@'
      (AtSymPeriod != -1) ||            // '@' and '.' exist next to each other
      (FirstPeriod == 0))               // first char is a period
  {  
    return false;
  }
  return true;
}
*/

function ContainSpaces(CheckMe) {
	return (CheckMe.indexOf(' ') != -1) ? true : false;
}

function HasBadCharacters(CheckMe) {
	var extraChars = "_.-@0123456789";
	for (var i = 0, size = CheckMe.length; i != size; i++) {
		var aChar = CheckMe.substring(i,i+1);
		aChar = aChar.toUpperCase();
		search = extraChars.indexOf(aChar);
		if (search == -1 && (aChar < "A" || aChar > "Z")) return true;
	}
	return false;
}

function IsEmpty(value)
{
  return (value == "" || value == null || value == "undefined" || value.search(/^\s*$/) != -1) ? true : false;
}

function imkLTrim(theString){return (!IsEmpty(theString)) ? theString.substr(theString.search(/\S/)) : theString;}
function imkRTrim(theString){return (!IsEmpty(theString)) ? theString.substr(0, theString.search(/\S\s*$/) + 1) : theString;}
function imkTrim(theString){return imkRTrim(imkLTrim(theString));}
