/*
 * CFormData.js
 * $Revision: 1.2 $ $Date: 2003/07/14 20:09:14 $
 */

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Netscape code.
 *
 * The Initial Developer of the Original Code is
 * Netscape Corporation.
 * Portions created by the Initial Developer are Copyright (C) 2003
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s): Bob Clary <bclary@netscape.com>
 *
 * ***** END LICENSE BLOCK ***** */

function CFormData()
{
  this.init();
}

CFormData.prototype.init =
function()
{
  this.mValueHash = {};
  this.mNames     = [];
  this.mValidatorHash = {};
};

CFormData.prototype.getValue = 
function(/* String */ aName)
{
  var values = this.mValueHash[aName];

  if (typeof(values) == 'undefined')
  {
    return null;
  }

  if (!values || values.length == 0)
  {
    return '';
  }

  if (values.length == 1)
  {
    return values[0];
  }

  return values;
};

CFormData.prototype.setValue = 
function(/* String */ aName, /* Array or Object */ value)
{
  if (!this.mValueHash[aName])
  {
    this.mNames[this.mNames.length] = aName;
    this.mValidatorHash[aName] = { isValid: function() { return true; }, message: ''};
  }

  if (typeof(value) != 'string' && typeof(value.length) == 'number')
  {
    this.mValueHash[aName] = value.slice(0);
  }
  else
  {
    this.mValueHash[aName] = [ value ];
  }
};

CFormData.prototype.setValueFromInput =
function(/* HTMLInput */ input)
{
  var values = [];
  var inputs = input.form[input.name];

  if (inputs.options)
  {
    inputs = inputs.options; // for opera
  }

  if (typeof(inputs.length) != 'number')
  {
    values[0] = input.value;
  }
  else
  {
    for (var i = 0; i < inputs.length; ++i)
    {
      if (inputs[i].checked || inputs[i].selected)
      {
        values[values.length] = inputs[i].value;
      }
    }
  }

  this.setValue(input.name, values);

};

CFormData.prototype.setValidator =
function(/* String */ aName, /* Function */ aValidator, /* String */ aMessage)
{
  var isValid = aValidator;
  this.mValidatorHash[aName] = { isValid: isValid, message: aMessage };
};

CFormData.prototype.validate =
function (/* String */ aName)
{
  var validator = this.mValidatorHash[aName];
  if (validator)
  {
    return validator.isValid(this, aName);
  }
  return true;
};

CFormData.prototype.getMessage =
function (/* String */ aName)
{
  var validator = this.mValidatorHash[aName];
  if (validator)
  {
    return aName + ': ' + validator.message;
  }
  return null;
};

CFormData.prototype.getNames = 
function()
{
  var names = this.mNames.slice(0);
  return names;
};

CFormData.prototype.fromString = 
function(/* String */ aQueryString)
{
  if (!aQueryString)
  {
    return;
  }

  if (aQueryString.indexOf('?') == 0);
  {
    aQueryString = aQueryString.substring(1);
  }

  aQueryString = aQueryString.replace(/[\&]amp;/g, '&');
  var parmList = aQueryString.split('&');

  for (var i = 0; i < parmList.length; i++)
  {
    var a     = parmList[i].split('=');
    var name  = unescape(a[0]);
    var value;
    if (a.length == 1)
    {
      value = true;
    }
    else
    {
      value = a[1].replace(/\+/g, ' ');
      value = unescape(value);
    }

    if (!this.mValueHash[name])
    {
      this.mValueHash[name] = [ value ];
      this.mNames[this.mNames.length] = name;
    }
    else
    {
      this.mValueHash[name][this.mValueHash[name].length] = value;
    }
  }
};

CFormData.prototype.fromForm = 
function(/* HTMLFormElement */ form)
{
   var values;

   for (var i = 0; i < form.elements.length; ++i)
   {
     var elm = form.elements[i];

     if (!elm.name || typeof(elm.value) == 'undefined')
     {
       continue; // skip non values
     }

     this.setValueFromInput(elm)
   }
};

CFormData.prototype.toString = 
function()
{
  var parms = '';

  for (var name in this.mValueHash)
  {
    for (var j = 0; j < this.mValueHash[name].length; ++j)
    {
      if (parms)
      {
        parms += '&';
      }
      var value = this.mValueHash[name][j];
      value = escape(value);
      value = value.replace(/\+/g, '%2B');
      parms += name + '=' + value;
    }
  }
  parms = '?' + parms;

  return parms;
};

CFormData.prototype.toForm = 
function(/* HTMLFormElement */ form)
{
  for (var i = 0; i < form.elements.length; ++i)
  {
    var elm = form.elements[i];
    if (typeof(elm.checked) == 'boolean')
    {
      elm.checked = false;
    }
    else if (typeof(elm.selected) == 'boolean')
    {
      elm.selected = false;
    }
  }

  for (var name in this.mValueHash)
  {
    for (var j = 0; j < this.mValueHash[name].length; ++j)
    {
      if (typeof(form[name].length) != 'number')
      {
        this._toFormValue(form[name], this.mValueHash[name][j]);
      }
      else
      {
        for (var k = 0; k < form[name].length; ++k)
        {
          this._toFormValue(form[name][k], this.mValueHash[name][j]);
        }
      }
    }
  }
};

CFormData.prototype._toFormValue = 
function (/* HTMLInputElement */ aInput, /* String */ aValue)
{
  if (typeof(aInput.type) != 'undefined' && aInput.type.indexOf('text') != -1)
  {
    aInput.value = aValue;
  }
  else if (typeof(aInput.selected) == 'boolean')
  {
    if (aInput.value == aValue)
    {
      aInput.selected = true;
    }
  }
  else if (aInput.type == 'checkbox' || aInput.type == 'radio')
  {
    if (aInput.value == aValue)
    {
      aInput.checked = true;
    }
  }
};

