// indexOf on arrays doesn't work in IE
function IndexOf(a,item)
{
  var len = a.length;

  for (var i = 0; i < len; i++) 
  { 
    if (a[i] === item) { return i; }
  } 

  return -1;
}

// lb is listbox handle, a is associative array of data
function loadLB(lb,a)
{
  var newOption; 
  var Key;   

  clearListBox(lb);
  for (Key in a)
  { 
    newOption = document.createElement("option");
    newOption.text  = a[Key];
    newOption.value = Key;
    lb.options.add(newOption);
  }
}

// Add a single element to a listbox
function loadLBElement(lb,Value,Text)
{
  var newOption; 

  newOption = document.createElement("option");
  newOption.text  = Text;
  newOption.value = Value;
  lb.options.add(newOption);
}

// Add a single element to a listbox with selected option
function loadSLBElement(lb,Value,Text,Selected)
{
  var newOption; 

  // Create option object
  newOption = document.createElement("option");

  // Set the Text and Value
  newOption.text  = Text;
  newOption.value = Value;

  // Make 'selected' visible by setting background color
  // to yellow.
  // style.color = "blue"; would set the font color
  if (Selected)
  { newOption.style.background = "yellow"; }

  // Add option
  lb.options.add(newOption);
}

// Update Text of lb item based on valuee
function updateLBVText(lb,V,T)
{
  for (var i = 0; i < lb.length; i++)
  {
    if (lb.options[i].value == V)
    {
      lb.options[i].text = T;
      return;
    }
  }
}

// lb is listbox, a is associative array, i is index value to filter on.
// Assumes array records have leading index value to match against i.
// '|' is the record delimiter
function loadSubLB(lb,a,i)
{
  var newOption;    // Used to create options to add
  var Key;          // used to step through associative array
  var FID;          // id at front of assoc array record to filter on
  var Text;         // test of assoc array record to use in object
  var Fields;       // array for splitting assoc array record

  clearListBox(lb); // empty the listbox for refilling

  for (Key in a)    // step through keys of associative array a
  { 
    Fields = new Array();        // Set up Fields array
    Fields = a[+Key].split("|"); // split assoc array record
    FID    = Fields[0];          // first field is id to filter on
    Text   = Fields[1];          // second field is text to insert into obj

    if (+FID == +i) // test if this is the type of record we want
    {
      // Set up the new option
      newOption = document.createElement("option");
      newOption.text  = Text;
      newOption.value = Key;

      // and add to the listbox
      lb.options.add(newOption);
    }
  }
}  

function countBits(Num,Start,Len)
{
  if (typeof(Num)   == "undefined") { Num   = 0; }
  if (typeof(Start) == "undefined") { Start = 0; }
  if (typeof(Len)   == "undefined") { Len   = 8; }

  for(var c = 0,i = Start; i < Len; i++)
  { (Num & (1 << i)) && c++; }

  return c;
}

function unselectMLBoxAll(lb)
{
  for (var i = 0; i < lb.options.length; i++)
  {
    lb.options[i].selected = false;
  }
}

function clearListBox(lb)
{
  for (var i=lb.options.length-1; i>=0; i--)
  {
    lb.options[i] = null;
  }
  lb.selectedIndex = -1;
}

function selectLBValue(lb,v)
{
  if (v == -1) { lb.selectedIndex = -1; return }

  for (var i=0; i<lb.length && (lb.options[i].value != v); i++) {}
  lb.selectedIndex = (i == lb.length) ? -1 : i;
}

// lb is listbox object, v is value, selected = true or false
function selectMLBValue(lb,v,selected)
{
  for (var i=0; i<lb.length && (lb.options[i].value != v); i++) {}

  if (i < lb.length)
  { lb.options[i].selected = selected; }
}

function selectLBText(lb,t)
{
  for (var i=0; i<lb.length && (lb.options[i].text != t); i++) {}
  lb.selectedIndex = (i == lb.length) ? -1 : i;
}

function ROUND(N,P)
{
  if (typeof N != "number") { alert("N is not a number: " + N); return (0); }
  else { return (N.toFixed(P)); }
}

// Clean up dollar sign, percent and commas to leave valid number
function format2num (S)
{
  S = (typeof S == 'undefined') ? 0 : S;

  if (S.match(/\%/))
  {
    S = S.replace(/\%/,"");
    S = isNaN(S) ? S : (S / 100);
  }
  else
  {
    S = S.replace(/[,\$]/g,"");
  }

  return (+S);
}

// Format number N as as string of format F with precision P for display
// F types = [M,N,P] (Money, Number, Percent)
function num2format(N,F,P)
{
  // clean up and set defaults as needed
  N = (typeof N == 'undefined') ? 0  : N;
  F = (typeof F == 'undefined') ? '' : F;
  P = (typeof P == 'undefined') ? 0  : P;

  // If it is not a number, bail on format and return
  if (isNaN(N)) { return (N); }

  var i;                 // Counter
  var A = new Array();   // inputed array of chars
  var B = new Array();   // formatted array of chars

  switch(F)
  {
    case 'M': // Money?

      // Make N have cents and convert to array of chars
      A = (N.toFixed(2)).split("");

      // Move cents over first (to decimal point from right)
      for (i = 0; i < 3; i++) { B.unshift(A.pop()); }

      // Set any needed commas
      while (A.length > 3)
      {
        for(i = 0; i < 3; i++) { B.unshift(A.pop()); }
        B.unshift(',');
      }

      // Tidy up remaining numbers from A
      while (A.length) { B.unshift(A.pop()); }
  
      // Add $ to front
      B.unshift('$');

      break;

    case 'N':  // Straight up number with commas?

      // Make N array of chars with precision P
      A = (N.toFixed(P) + "").split("");

      // Move chars from right of A to decimal point
      if (P > 0)
      { 
        while (B[0] != '.') { B.unshift(A.pop()); } 
      }

      // Set any needed commas
      while (A.length > 3)
      {
        for(i = 0; i < 3; i++) { B.unshift(A.pop()); }
        B.unshift(',');
      }

      // Tidy up remaining numbers from A
      while (A.length) { B.unshift(A.pop()); }

      break;

    case 'P': // Percentage?

      // Return N X 100, precision 1, plus % sign on end
      // If char to right of . is 0, remove decimal and last 0
      return (((N * 100).toFixed(1)).replace(/\.0/,"") + "%");
  }

  // Return the string if B array used
  return (B.join(""));
}

// Pad string S with C up to length N.  Return left N chars of padded S.
var PadSpaces = "\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0" +
                "\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0" +    
                "\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0" +    
                "\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0" +    
                "\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0" +    
                "\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0";
function PadString(S,N)
{
  return (S + PadSpaces).substr(0,N);
}
