
/* ----------------------------------------------------------------------------
 * Name: varsObject
 * Creates an object for a map.
 * Parameters:
 *   k: Map key
 *   v: Map value
 * Returns: Pointer to object
 */
function varObject(k, v) {
  this.key = k;
  this.value = v

  return this;
}

/* ----------------------------------------------------------------------------
 * Name: Vars (obect)
 * Creates a Vars object.
 * Parameters: none
 * Returns: Pointer to itself
 */
function Vars() {
  this.varMap = new Array();

  return this;
} // Vars

/* ----------------------------------------------------------------------------
 * Name: Vars::Parse
 * Parses a vars string.
 * Parameters:
 *   parseMe: String to be parsed
 * Returns: n/a
 */
Vars.prototype.Parse = function(parseMe) {
  var name = "";
  var field = "";
  var pos = 0;
  var p = 0;
  var isEscaped = false;

  this.varMap = new Array();

  while(p < parseMe.length) {
    // Store name field.
    name = "";
    for(pos=p; pos < parseMe.length && parseMe.substr(pos, 1) != ':'; pos++)
      name += parseMe.substr(pos, 1);

    //parseMe = parseMe.erase(0, pos+1);
    p = pos+1;

    field = "";
    for(pos=p; pos < parseMe.length; pos++) {
      if (!isEscaped && parseMe.substr(pos, 1) == '|')
        break;

      if (!isEscaped && parseMe.substr(pos, 1) == '\\')
        isEscaped = true;
      else if (isEscaped && parseMe.substr(pos, 1) == 'n') {
        isEscaped = false;
        field += '\n';
      } // else if
      else {
        isEscaped = false;
        field += parseMe.substr(pos, 1);
      } // else
    } // for

    p=pos+1;
    //parseMe = parseMe.erase(0, pos+1);

    if (name.length > 0 && field.length > 0) {
      //appendById('o', "Name: " + name + "<br />");
      //appendById('o', "Field: " + field + "<br />");

      this.add(name, unescape(field));
    } // if
  } // while
} // Vars::Parse

/* ----------------------------------------------------------------------------
 * Name: Vars::listVars
 * Lists the variables currently stored in Vars object.
 * Parameters: none
 * Returns: n/a
 */
Vars.prototype.listVars = function() {
  var ret = "List: ";
  var i = "";

  for(i=0; i < this.varMap.length; i++) {
    ret += '"' + this.varMap[i]["key"] + '" => "' + this.varMap[i]["value"] + '" ';
  } // for

  return ret;
} // Vars::listVars

/* ----------------------------------------------------------------------------
 * Name: isKey
 * Looks up the validity of a key.
 * Parameters:
 *   k: Map key
 * Returns: True if key name exists.
 */
Vars.prototype.isKey = function(k) {
  var i;

  for(i=0; i < this.varMap.length; i++) {
    if (this.varMap[i]["key"] == k.toUpperCase())
      return true;
  } // for

  return false;
} // Vars::isKey

Vars.prototype.isName = function(k) {
  return this.isKey(k);
} // Vars::isName

Vars.prototype.is = function(k) {
  return this.isKey(k);
} // Vars::is

/* ----------------------------------------------------------------------------
 * Name: add
 * Adds a key and value to the varMap.
 * Parameters:
 *   k: Map key.
 *   v: Map value.
 * Returns: True if add was succesful, false if key already existed.
 */
Vars.prototype.add = function(k, v) {

  if (this.isName(k))
    return false;

  this.varMap.push(new varObject(k.toUpperCase(), v));

  return true;
} // Vars::add

/* ----------------------------------------------------------------------------
 * Name: remove
 * Removes a key and value from the varMap.
 * Parameters:
 *   k: Map key.
 * Returns: True if remove was succesful, false if key didn't exist.
 */
Vars.prototype.remove = function(k) {
  var i;
  var tmp = new Array();

  if (!this.isName(k))
    return false;

  for(i=0; i < this.varMap.length; i++) {
    if (this.varMap[i]["key"] == k.toUpperCase())
      continue;

    tmp.push(this.varMap[i]);
  } // for

  this.varMap = tmp;

  return true;
} // Vars::remove

/* ----------------------------------------------------------------------------
 * Name: length
 * Get the size of the Vars map.
 * Parameters: none
 * Returns: Size of varMap.
 */
Vars.prototype.length = function() {
  return this.varMap.length;
} // Vars::length

/* ----------------------------------------------------------------------------
 * Name: clear
 * Clears varMap.
 * Parameters: none
 * Returns: Previous size of varMap.
 */
Vars.prototype.clear = function() {
  var ret = this.varMap.length;

  this.varMap = new Array();

  return ret;
} // Vars::clear

/* ----------------------------------------------------------------------------
 * Name: get
 * Gets the field for a given key.
 * Parameters:
 *   k: Map key
 * Returns: Value of key or empty string on error.
 */
Vars.prototype.get = function(k) {
  var i;

  for(i=0; i < this.varMap.length; i++) {
    if (this.varMap[i]["key"] == k.toUpperCase())
      return this.varMap[i]["value"];
  } // for

  return "";
} // Vars::get

Vars.prototype.getField = function(k) {
  return this.get(k);
} // Vars::getField


/* ----------------------------------------------------------------------------
 * Name: Escape
 * Escapes a key value.
 * Parameters:
 *   parseMe: String to be escaped.
 * Returns: Escaped string.
 */
Vars.prototype.Escape = function(parseMe) {
  var ret = "";
  var pos = 0;

  for(pos = 0; pos < parseMe.length; pos++) {
    if (parseMe.substr(pos, 1) == '|' || parseMe.substr(pos, 1) == '\\')
      ret += '\\' + parseMe.substr(pos, 1);
    else
      ret += parseMe.substr(pos, 1);
  } // for

  return ret;
} // Vars::Escape

/* ----------------------------------------------------------------------------
 * Name: String::erase
 * Returns a string with portion erased.
 * Parameters:
 *   s: Start position.
 *   l: Length of string to be erased from start position.
 * Returns: String without erased portion.
 */
String.prototype.erase = function(s, l) {
  var pos;
  var ret = "";
  var f = (s + l);

  for(pos=0; pos < this.length; pos++) {
    if (pos >= s && pos < f)
      continue;

    ret += this.substr(pos, 1);
  } // for

  return ret;
} // String::erase

