/**
 * to keep track of the previously selected index in a select box
 */
var previous_index = 0;

/**
 * keep track of checkboxes checked (see checkbox_limit)
 */
var check_order = new Array();

/**
 * limit of checkboxes that can be checked (see checkbox_limit)
 */
var check_limit = 0;

/**
 * populates selDest based on the selection(s) in selSource and the values in
 * map.
 */
function select_populate(selSource, selDest, map, useAll) {
  var p = new Array();

  /* clear the destination select */
  select_clear(selDest);
  useAll ? select_add_option(selDest, '', 'All') : null;
  for(var i = 0; i < selSource.length; i++) {
    if(selSource.options[i].selected) {
      if(selSource.options[i].value == '') {
        /* load the entire array */
        for(var m in map) {
          p = map[m];
          if(p) {
            for(var j in p)
              select_add_option(selDest, j, p[j]);
          }
        }
      } else {
        /* load the array of options for the selected key */
        p = map[selSource.options[i].value];
        if(p != null) {
          /* add them all to the destination select */
          for(var j in p)
            select_add_option(selDest, j, p[j]);
        }
      }
    }
  }
  // set the first option to selected
  selDest.selectedIndex = 0;
}

/**
 * adds an option to a select box
 */
function select_add_option(select, value, text) {
  select.options[select.length] = new Option(text, value);
}

/**
 * clears all the options in a select box
 */
function select_clear(select) {
  select.options.length = 0;
}

/**
 * disables a select box
 */
function select_disable(select) {
  select.disabled = true;
}

/**
 * enables a select box
 */
function select_enable(select) {
  select.disabled = false;
}

/**
 * adds or subtracts the given value multiplied by the current value of the
 * given select box to/from the value in the given text box. 
 */
function select_total(select, txt, value) {
  var old_qty = parseFloat(select.options[previous_index].value);
  var qty = parseFloat(select.options[select.selectedIndex].value);

  txt_value_sub(txt, old_qty * value);
  txt_value_add(txt, qty * value);
  previous_index = select.selectedIndex;
}

function select_linked_total(select, link, txt, value, link_value) {
  if(link.type == "checkbox") {
    select_total(select, txt, value);
    checkbox_linked_total(link, txt, link_value);
  }
}

/**
 * stores the currently selected index of the given select box into the
 * previous_index global
 */
function select_store(select) {
  if(select.selectedIndex)
    previous_index = select.selectedIndex;
}

/**
 * adds a numeric value to a value in a text box
 */
function txt_value_add(txt, value) {
  txt.value = (parseFloat(txt.value) + parseFloat(value)).toFixed(2);
}

/**
 * subtracts a numeric value from a value in a text box
 */
function txt_value_sub(txt, value) {
  txt.value = (parseFloat(txt.value) - parseFloat(value)).toFixed(2);
}

/**
 * adds or subtracts the given value to/from the value in the given text field
 * based on the state of the given checkbox. checked means add, unchecked means
 * subtract
 */
function checkbox_total(checkbox, txt, value) {
  if(checkbox.checked)
    txt_value_add(txt, value);
  else
    txt_value_sub(txt, value);
}

/**
 * adds or subtracts the given value multiplied by the value of link to/from
 * the value of txt depending on whether the given checkbox is checked or not
 */
function checkbox_linked_total(checkbox, link, txt, value) {
  var link_value = 0;
  
  if(link.type == "select-one")
    link_value = parseFloat(link.options[link.selectedIndex].value);
  else if(link.type == "text")
    link_value = parseFloat(link.value);
  
  checkbox_total(checkbox, txt, link_value * value);
}

function checkbox_set_limit(limit) {
  check_limit = limit;
}

function checkbox_limit(checkbox) {
  var prev_checkbox;
  
  if(checkbox.checked) {
    if(check_order.length < check_limit) {
      check_order.push(checkbox);
    } else {
      prev_checkbox = check_order.shift();
      prev_checkbox.checked = false;
    }
  } else {
    for(var i = 0; i < check_order.length; i++) {
      if(check_order[i] == checkbox) {
        var first = check_order.slice(0, i);
        var second = check_order.slice(i + 1);
        check_order = first.concat(second);
        break;
      }
    }
  }
}

/**
 *
 */
function checkbox_limit_group(limit) {
  var cnt = 0;
  var group = null;
  
  if(document.getElementsByTagName && document.createTextNode) {
    group = getElementsByClassName('group', 'input', document);
    if(group != null) {
      for(var i = 0; i < group.length; i++) {
        if(group[i].checked)
          cnt++;
      }
    }
  }
  
  if(group != null) {
    if(cnt == limit) {
      for(var i = 0; i < group.length; i++) {
        if(!group[i].checked)
          group[i].disabled = true;
      }
    } else {
      for(var i = 0; i < group.length; i++)
        group[i].disabled = false;
    }
  }
}

function group(limit) {
  if(document.getElementsByTagName && document.createTextNode) {
    var group = getElementsByClassName('group', 'input', document);
    if(group != null) {
      for(var i = 0; i < group.length; i++) {
        // set event handlers for row
        group[i].onclick = function(){checkbox_limit_group(limit)};
      }
    }
  }  
}

/**
 *
 */
function form_total(form, txt, base, prices, links) {
  var total = 0;
  var qty = 1;

  if(base)
    total = base;
  
  for(var i = 0; i < form.length; i++) {
    qty = 1;
    var name = form.elements[i].name;
    var type = form.elements[i].type;

    if(prices[name]) {
      /* field name matches map value */

      if(links[name]) {
        /* field is linked to a quantity field, get quantity of linked field */
        qty = parseFloat(form_element_value(form[links[name]['link']]));
        qty += parseFloat(links[name]['base']);
      }
      
      if(type == "text" || type == "select-one") {
        /* text & select fields are quantities, multiply by value */
        total += (qty * (parseFloat(form.elements[i].value) * prices[name]));
      } else if(type == "radio" || type == "checkbox") {
        /* radio and checkboxes are added if they are selected */
        if(form.elements[i].checked) {
          total += (qty * prices[name]);
        }
      }
    }
  }
  
  txt.value = total.toFixed(2);
}

function form_element_value(element) {
  var value;
  
  if(element.type == 'text' || 'checkbox')
    value = element.value;
  else if(element.type == 'select-one')
    value = element.options[element.selectedIndex].value;
    
  return value;
}

function initFormHighlighter() {
  if(document.getElementsByTagName && document.createElement) {
    var forms = document.getElementsByTagName('form');
    for(var i = 0; i < forms.length; i++) {
      var elements = forms[i].elements;
      for(var j = 0; j < elements.length; j++) {
        if(elements[j].type == 'text' || elements[j].type == 'textarea' || elements[j].type == 'select-multiple' || elements[j].type == 'select-one' || elements[j].type == 'password') {
          elements[j].onfocus = function() { formHighlight(this); };
          elements[j].onblur = function() { formUnHighlight(this); };
        }
      }
    }
  }
}

function formHighlight(element) {
  element.className = addClass(element, 'highlight');
}

function formUnHighlight(element) {
  element.className = removeClass(element, 'highlight');
}

function selectAll(name) {
  if(document.getElementsByTagName && document.createElement) {
    var inputs = document.getElementsByTagName('input');
    for(var i = 0; i < inputs.length; i++) {
      if(inputs[i].type == 'checkbox' && inputs[i].name.indexOf(name) == 0)
        inputs[i].checked = true;
    }
  }
}

function unselectAll(name) {
  if(document.getElementsByTagName && document.createElement) {
    var inputs = document.getElementsByTagName('input');
    for(var i = 0; i < inputs.length; i++) {
      if(inputs[i].type == 'checkbox' && inputs[i].name.indexOf(name) == 0)
        inputs[i].checked = false;
    }
  }
}

function selectOlder(name, timestamp) {
  if(document.getElementsByTagName && document.createElement) {
    var inputs = document.getElementsByTagName('input');
    for(var i = 0; i < inputs.length; i++) {
      if(inputs[i].type == 'checkbox' && inputs[i].name.indexOf(name) == 0 && timestamp > inputs[i].value)
        inputs[i].checked = true;
    }
  }  
}

