/*******************************************************************************************
 * Object: FormErrorList
 * Description: Implementation of hashtable
 *******************************************************************************************/

FormErrorList.prototype.i_titles = null;
FormErrorList.prototype.i_errors = null;
FormErrorList.prototype.i_redborder	= null;
FormErrorList.prototype.i_showlist	= null;
FormErrorList.prototype.i_fades	= null;
FormErrorList.prototype.i_title	= null;

/**
 * FormErrorList - Constructor
 * Create a new HashTable object.
 */
function FormErrorList(){
  this.i_titles = new HashTable();
  this.i_errors = new HashTable();
  this.i_redborder = true;
  this.i_showlist = true;
  this.i_fades = true;
	this.i_title = "Fix these errors in the form before resubmit";
}

/**
 * Clear
 * clear old error messages
 */
FormErrorList.prototype.Clear = function (){
  // must clear old errors displayed
  if (this.i_errors != null) {
    var keys = this.i_errors.Keys();
    var temp = null;
    for (var i = 0; i < keys.length; i++) {
      
      temp = document.getElementById("err_" + keys[i]);
      if (temp) {
        temp.innerHTML = "";
        temp.style.display = "none";
      }
      
      if (this.i_redborder) {
        temp = document.getElementById(keys[i]);
        if (temp) {
          temp.style.borderColor = "";
          temp.style.borderStyle = "";
          temp.style.borderWidth = "";
        }
      }
    }
  }
  this.i_titles = new HashTable();
  this.i_errors = new HashTable();
}

/**
 * addError
 * add the error to the list
 * param: fieldname - String, key fieldname
 * param: friendlyname - String, friendly fieldname
 * param: message - String, field error message
 */
FormErrorList.prototype.addError = function (fieldname, friendlyname, message){
  var ret = false;
  
  if (this.i_errors.ContainsKey(fieldname) == false) {
    this.i_titles.Add(fieldname, friendlyname);
    this.i_errors.Add(fieldname, message);
    ret = true;
  }
  
  return ret;
}

/**
 * containsError
 * returns true if error exists for field
 * param: fieldname - String, key fieldname
 */
FormErrorList.prototype.containsError = function (fieldname){
  var ret = false;
  if (this.i_errors.ContainsKey(fieldname)) {
    ret = true;
  }
  return ret;
}

/**
 * getError
 * returns error message for field
 * param: fieldname - String, key fieldname
 */
FormErrorList.prototype.getError = function (fieldname){
  var ret = "";
  if (this.i_errors.ContainsKey(fieldname)) {
    ret = "<span class='error'>^" + this.i_errors.getItem(fieldname) + "</span>";
    if (this.i_redborder == true) {
       this.borderForInput(fieldname);
    }
  }
  return ret;
}

/**
 * getErrorList
 * returns error message list for all fields
 */
FormErrorList.prototype.getErrorList = function (){
  var ret, keys, vbcrlf;
  ret = "";
  vbcrlf = "\n";
  keys = this.i_errors.Keys();
  
  if (this.i_errors.IsEmpty() == false && this.i_showlist == true) {
    ret = "<a name='errorBox'></a>" + vbcrlf;    
    ret += "<table border='0' cellpadding='0' cellspacing='0' width='' class='errorbox'>" + vbcrlf;
    ret += "<tr><th colspan='2'>" + this.i_title + "<!-- JS --></th></tr>" + vbcrlf;
    ret += "<tr><td><ul>";

    for (var i = 0; i < keys.length; i++) {
      ret += "<li><b>" + this.i_titles.getItem(keys[i]) + "</b> " + this.i_errors.getItem(keys[i]) + "</li>" + vbcrlf;
    }
    
    ret += "</ul></td></tr>";
    ret += "</table>" + vbcrlf;
  }
  
  if (this.i_errors.IsEmpty() == false) {
    // display each error
    var temp = null;
    for (var i = 0; i < keys.length; i++) {
      
      temp = document.getElementById("err_" + keys[i]);
      if (temp) {
        if (this.i_fades && typeof Spry != "undefined") {
          Spry.Effect.AppearFade("err_" + keys[i], {duration:1000, from:25, to:100, toggle:false});
        }
        temp.innerHTML = this.getError(keys[i]);
        temp.style.display = "inline";        
      }
    }
  }

  if (this.i_showlist == true) {
    // display the full list
    var errorList = document.getElementById("errorList");
    if (errorList) {
      if (this.i_fades && typeof Spry != "undefined") {
        if (errorList.innerHTML == "") {
          Spry.Effect.AppearFade('errorList', {duration:2000, from:10, to:100, toggle:false});
        }
      }
      errorList.innerHTML = ret;
      if (window.location.hash != 'errorBox') {
        window.location.hash = 'errorBox';
      }
    }
  }
    
  return ret;
}

/**
 * errorPresent
 * returns true if there are any errors present
 */
FormErrorList.prototype.errorPresent = function (){
  return (!this.i_errors.IsEmpty());
}

/**
 * errorCount
 * returns the error list count
 */
FormErrorList.prototype.errorCount = function (){
  return (this.i_errors.Count());
}

/**
 * ToString
 * returns the error list count
 */
FormErrorList.prototype.ToString = function (){
  return this.i_errors.ToString();
}

/**
 * borderForInput
 * returns javascript to put a red border around a form input
 * param: inputname - String, form inpute name value
 */
FormErrorList.prototype.borderForInput = function (inputname){
  var temp;
  temp = document.getElementById(inputname);
  if (temp) {
    temp.style.borderColor = "#FF0000";
    temp.style.borderStyle = "solid";
    temp.style.borderWidth = "2px";
  }
}

/**
 * setRedBorders
 * let the red borders property equal value
 */
FormErrorList.prototype.setRedBorders = function (val){
  this.i_redborder = val;
}

/**
 * setShowList
 * let the error list be displayed
 */
FormErrorList.prototype.setShowList = function (val){
  this.i_showlist = val;
}

/**
 * setFades
 * let the fades be displayed
 */
FormErrorList.prototype.setFades = function (val){
  this.i_fades = val;
}

/**
 * setTitle
 * let the title be set to this value
 */
FormErrorList.prototype.setTitle = function (val){
  this.i_title = val;
}

/**
 * getRedBorders
 * return the red borders property
 */
FormErrorList.prototype.getRedBorders = function (){
  return this.i_redborder;
}

/**
 * getShowList
 * return the show error list property
 */
FormErrorList.prototype.getShowList = function (){
  return this.i_showlist;
}

/**
 * getFades
 * return the show fades property
 */
FormErrorList.prototype.getFades = function (){
  return this.i_fades;
}


//FormErrorListDebug();

function FormErrorListDebug() {
  var feh;
  feh = new FormErrorList();
  feh.setRedBorders(true);
  feh.setShowList(true);
  
  document.write("add1 = " + feh.addError("test1","Test #1","is a required field") + "<br/>");
  document.write("add2 = " + feh.addError("test2","Test #2","is a required field") + "<br/>");
  
  document.write("getShowList() = " + feh.getShowList() + "<br/>");
  document.write("getRedBorders() = " + feh.getRedBorders() + "<br/>");
  document.write("errorPresent() = " + feh.errorPresent() + "<br/>");
  document.write("errorCount() = " + feh.errorCount() + "<br/>");
  document.write("ToString() = " + feh.ToString() + "<br/>");
  
  document.write(feh.getErrorList());

  feh = null;
}


/*******************************************************************************************
 * Object: Hashtable
 * Description: Implementation of hashtable
 *******************************************************************************************/

HashTable.prototype.keys		= null;
HashTable.prototype.items	 	= null;

/**
 * HashTable - Constructor
 * Create a new HashTable object.
 */
function HashTable(){
	this.keys = new Array();
	this.items = new Array();
}

/**
 * setItem
 * set the value of an existing key
 * param: key - String, key name
 * param: value - Object, the object to replace
 */
HashTable.prototype.setItem = function (key, value){
	if (value == null)
		return;

	for (var i = 0; i < this.keys.length; i++){
		//did we found our key?
		if (key == this.keys[i]){
		  //set the value
			this.items[key] = value;
			return;
		}
	}	
}

/**
 * setKey
 * reset the key of an existing key
 * param: key - String, key name
 * param: newkey - String, new key name
 */
HashTable.prototype.setKey = function (key, newkey){
	if (newkey == null)
		return;

	for (var i = 0; i < this.keys.length; i++){
		//did we found our key?
		if (key == this.keys[i]){
		  //set the key
		  this.keys[i] = newkey;
			return;
		}
	}	
}

/**
 * getItem
 * Return an element
 * param: key - String, key name
 * Return: object - The requested object
 */
HashTable.prototype.getItem = function (key){
		return this.items[key];
}


/**
 * ContainsKey
 * Return true if key is present
 * param: key - String, key name
 */
HashTable.prototype.ContainsKey = function (key){
	if (key == null)
		return false;
		
  for (var i = 0; i < this.keys.length; i++){
		//did we found our key?
		if (key == this.keys[i]){
		  //set the key
			return true;
		}
	}
	return false;
}

/**
 * ContainsItem
 * Return true if an element exists
 * param: item - String, item value
 */
HashTable.prototype.ContainsItem = function (item){
	if (item == null)
		return false;
		
	for (var i = 0; i < this.keys.length; i++){
		//did we found our key?
		if (item == this.items[this.keys[i]]){
		  //set the key
			return true;
		}
	}
	return false;
}

/**
 * Clear
 * destroy all arrays
 */
HashTable.prototype.Clear = function (){
	this.keys = new Array();
	this.items = new Array();
}


/**
 * Add
 * Add new key and value
 * param: key - String, key name
 * param: value - Object, the object to insert
 */
HashTable.prototype.Add = function (key, value){
	if (value == null)
		return;

	if (this.items[key] == null)
		this.keys[this.keys.length] = key;

	this.items[key] = value;
}

/**
 * Remove
 * Remove an element
 * param: key - String, key name
 */
HashTable.prototype.Remove = function (key){
	for (var i = 0; i < this.keys.length; i++){
		//did we found our key?
		if (key == this.keys[i]){
			//remove it from the hash
			this.items[this.keys[i]] = null;
			//and throw away the key...
			this.keys.splice(i ,1);
			return;
		}
	}
}

/**
 * Count
 * Return: Number of elements in the hashtable
 */
HashTable.prototype.Count = function (){
    return this.keys.length;
}

/**
 * IsEmpty
 * Return: True if hashtable is empty
 */
HashTable.prototype.IsEmpty = function (){
    return (this.keys.length <= 0);
}

/**
 * Keys
 * Return: array of keys
 */
HashTable.prototype.Keys = function (){
    return this.keys;
}

/**
 * Items
 * Return: array of items
 */
HashTable.prototype.Items = function (){
    var ret = new Array();
    if (this.keys.length > 0) {
  		for (var i = 0; i < this.keys.length; i++) {
        ret[i] = this.items[this.keys[i]];
  		}  		
	  }    
    return ret;
}


/**
 * ToString
 * Returns a string representation of this HashTable object in the form of a set of entries,
 * enclosed in braces and separated by the ASCII characters ", " (comma and space).
 * Each entry is rendered as the key, an equals sign =, and the associated element,
 * where the toString method is used to convert the key and element to strings.
 * Return: a string representation of this hashtable.
 */
HashTable.prototype.ToString = function (){
  var ret = "[";
	try {
		if (this.keys.length > 0) {
  		for (var i = 0; i < this.keys.length; i++) {
  		  ret += "{" + this.keys[i] + " = " + this.items[this.keys[i]] + "}";
    		if (i < this.keys.length - 1) {
    		  ret += ",";
    	  }
  		}  		
	  }
	} catch(e) {
		// do nothing here :-)
	} finally {
		ret += "]";
	}
	return ret;
}