// **************************
// statusbar text functions *
// **************************
function setStatus (txt) {
  try {
    if (txt) {
      if (window.status != txt)
        window.status = txt;
      return true;
    } else {
      if (window.status != document.title)
        window.status = document.title;
      return true;
    }
  } catch (e) {}
} // setStatus

var numLoading = 0;

function showLoading() {
  var loading = gel('div_loading_block');
  if (!loading) {
    loading = document.createElement('div');
    loading.id = 'div_loading_block';
    loading.innerHTML = '<img src="/img/spinner.gif" height="18" width="18" border="0" />';
    loading.style.position = 'absolute';
    loading.style.top = '2px';
    loading.style.right = '2px';
    loading.style.zIndex = 20000;
    document.getElementsByTagName('body').item(0).appendChild(loading);
  }
  loading.style.display = 'block';
  numLoading++;
}

function showLoadingPos(x,y) {
  var loading = gel('div_loading_block');
  if (!loading) {
    loading = document.createElement('div');
    loading.id = 'div_loading_block';
    loading.innerHTML = '<img src="/img/spinner.gif" height="18" width="18" border="0" />';
    loading.style.position = 'absolute';
    loading.style.top = (2+y)+'px';
    loading.style.right = (2+x)+'px';
    loading.style.zIndex = 20000;
    document.getElementsByTagName('body').item(0).appendChild(loading);
  }
  loading.style.display = 'block';
  numLoading++;
}

function showLoading_OLD() {
  var loading = gel('div_loading_block');
  if (!loading) {
    loading = document.createElement('div');
    loading.id = 'div_loading_block';
    loading.innerHTML = '<font style="font-family:verdana,sans-serif; font-size:12px; color:white;">Loading...</' + 'font>';
    loading.style.position = 'absolute';
    loading.style.top = '4px';
    loading.style.right = '4px';
    loading.style.backgroundColor = '#CC3333'; //'red';
    loading.style.width = '65px';
    loading.style.padding = '2px';
    document.getElementsByTagName('body').item(0).appendChild(loading);
  }
  loading.style.display = 'block';
  numLoading++;
}

function hideLoading() {
  numLoading--;
  if(numLoading < 1) {
    var loading = gel('div_loading_block');
    if (loading) loading.style.display = 'none';
  }
}

// **************************
// calculator functions
// **************************
function openPopupCalc (val) {
  switch (parseInt(val)) {
  case 1:
    window.open ("/tools/calculators/calc-basic.phtml",'winCalcPopup1','history=no,toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=yes,width=280,height=300');
    break;
  case 2:
    window.open ("/tools/calculators/calc-homeeq.phtml",'winCalcPopup2','history=no,toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=400,height=420');
    break;
  case 3:
    window.open ("http://home.xl2web.com/xl2webModel.jsp?uid=S1F0J7P3",'winCalcPopup3','history=no,toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=740,height=520');
    break;
  case 4:
    window.open ("/tools/calculators/rater/",'winCalcPopup4','history=no,toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=840,height=480');
    break;
  }
}

function MapAddress (address, city, state, zip) {
  var url = "";
  url += "http://maps.google.com/maps?";
  url += "q="+address+",+"+city+",+"+state+"+"+zip+"&iwloc=A&hl=en&t=h";
  //alert (url);
  window.open (url);
  return;
}

// Window Events
function addLoadEvent(func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
      oldonload();
      func();
    }
  }
}
function addResizeEvent(func) {
  var oldonresize = window.onresize;
  if (typeof window.onresize != 'function') {
    window.onresize = func;
  } else {
    window.onresize = function() {
      oldonresize();
      func();
    }
  }
}
function addScrollEvent(func) {
  var oldonscroll = window.onscroll;
  if (typeof window.onscroll != 'function') {
    window.onscroll = func;
  } else {
    window.onscroll = function() {
      oldonscroll();
      func();
    }
  }
}
function addObjectMouseOverEvent(object,func) {
  var oldonmouseover = object.onmouseover;
  if (typeof object.onmouseover != 'function') {
    object.onmouseover = func;
  } else {
    object.onmouseover = function() {
      oldonmouseover();
      func();
    }
  }
}

function setScreenSize (win, w, h, max) {
  win.resizeTo (w,h);
  if (max) win.moveTo (0, 0);
  return;
}

function stripeTable (table) {
  try {
    var rows=gel(table).getElementsByTagName('tr');
    var c = 0; // visible lines counter
    for (i=1;i<rows.length;i++){
      if (rows[i].style.display != 'none' && rows[i].nodeType == 1) {
        rows[i].style.cursor="default";
        if (c%2 == 0) {
          rows[i].setAttribute('class', 'bgNone');
          rows[i].setAttribute('className', 'bgNone');
        } else {
          rows[i].setAttribute('class', 'bgGrey');
          rows[i].setAttribute('className', 'bgGrey');
        }
        c++;
      }
    }
  } catch (e) {}
  return;
}

function stripeTableTrack (table) {
  try {
    var rows=gel(table).getElementsByTagName('tr');
    var c = 0; // visible lines counter
    for (i=1;i<rows.length;i++){
      if (rows[i].style.display != 'none' && rows[i].nodeType == 1) {
        rows[i].onmouseover = function(){this.setAttribute('class','bgOver');this.setAttribute('className','bgOver');};
        if (c%2 == 0){
          rows[i].setAttribute('class', 'bgNone');
          rows[i].setAttribute('className', 'bgNone');
          rows[i].onmouseout = function(){this.setAttribute('class','bgNone');this.setAttribute('className','bgNone');}
        } else {
          rows[i].setAttribute('class', 'bgGrey');
          rows[i].setAttribute('className', 'bgGrey');
          rows[i].onmouseout = function(){this.setAttribute('class','bgGrey');this.setAttribute('className','bgGrey');}
        }
        rows[i].style.cursor="pointer";
        c++;
      }
    }
  } catch (e) {}
  return;
}

function setInputsDisabled (val,exclusions) {
  // exclusions expected as array
  var types = new Array ('select', 'input');
  //alert (types.indexOf('input'));
  for (i=0; i<types.length; i++) {
    var ctls = document.getElementsByTagName(types[i]);
    for (c=0; c<ctls.length; c++) {
      if ((!exclusions) | (exclusions && exclusions.indexOf(ctls[c].name) < 0))
        ctls[c].disabled = val;
    }
  }
}

function disableSelection (element) {
  element.onselectstart = function() { return false; };
  element.unselectable = "on";
  element.style.MozUserSelect = "none";
  element.style.cursor = "pointer"; // cursor:pointer default
}

function gel (id) {
  return document.getElementById(id);
}

function getRadioValue (opt) {
  for (var i = 0; i < opt.length; i++)
    if (opt[i].checked) { break; }
  return opt[i].value;
}

function setRadioValue (opt, val) {
  for (var i = 0; i < opt.length; i++)
    opt[i].checked = (opt[i].value == val) ? true : false;
  return;
}

function SelectAddItem (sel, txt, val, selected) {
  var opt = new Option(txt, val, selected);
  sel.options[sel.length] = opt;
}

function SelectDelItem (sel, idx) {
  if (sel.length>0) {
    sel.options[idx] = null;
  }
}

function SelectAll (ctl) {
  if (ctl.length > 0) {
    for(var i=0; i < ctl.length; i++) {
      ctl[i].selected=true;
    }
    ctl[0].selected=true;
  }
}

function SelectNone (ctl) {
  if (ctl.length > 0) {
    for(var i=0; i < ctl.length; i++) {
      ctl[i].selected=false;
    }
    ctl[0].selected=true;
    ctl[0].selected=false;
  }
}

function SelectVal (ctl, val) {
  if (ctl.length > 0) {
    for(var i=0; i < ctl.length; i++) {
      if (ctl[i].value==val)
        ctl[i].selected=true;
    }
  }
}

function SelectShowLoading (oSel) {
  oSel.length = 0;
  oSel.options[oSel.length] = new Option("Loading...", "0");
  oSel.style.color="#FF0000";
  oSel.options[0].style.color="#FF0000";
}

function SelectHideLoading (oSel) {
  oSel.length = 0;
  oSel.style.color="#000000";
  try {
    oSel.options[0].style.color="#000000";
  } catch (e) {}
}


function ZeroEmpty (txt) {
  if (parseFloat(txt.value) == 0) {
    txt.value = '';
  }
}

function ZeroFill (txt) {
  var s = txt.value;
  if (s.trim() == '') {
    txt.value = 0;
  }
}

function formatCurrency (amount) {
  var i = parseFloat(amount);
  if(isNaN(i)) { i = 0.00; }
  var minus = '';
  if(i < 0) { minus = '-'; }
  i = Math.abs(i);
  i = parseInt((i + .005) * 100);
  i = i / 100;
  s = new String(i);
  if(s.indexOf('.') < 0) { s += '.00'; }
  if(s.indexOf('.') == (s.length - 2)) { s += '0'; }
  s = minus + s;
  s = formatComma (s);
  return s;
}  // end of function

function formatComma (amount) {
  var delimiter = ","; // replace comma if desired
  var a = amount.split('.',2)
  var d = a[1];
  var i = parseInt(a[0]);
  if(isNaN(i)) { return ''; }
  var minus = '';
  if(i < 0) { minus = '-'; }
  i = Math.abs(i);
  var n = new String(i);
  var a = [];
  while(n.length > 3) {
    var nn = n.substr(n.length-3);
    a.unshift(nn);
    n = n.substr(0,n.length-3);
  }
  if(n.length > 0) { a.unshift(n); }
  n = a.join(delimiter);
  if(d.length < 1) { amount = n; }
  else { amount = n + '.' + d; }
  amount = minus + amount;
  return amount;
}  // end of function


// ****************************************************************
//  CALCULATION FUNCTIONS
// ****************************************************************

function calc_pmt_var (ifact, ir, np, pv, fv, fp, fpip, typ) {
  // correct internal php values
  ifact = parseFloat(ifact);
  ir = parseFloat(ir);
  np = parseInt(np);
  fv = parseFloat(fv);
  pv = parseFloat(pv);
  fp = parseInt(fp);
  fpip = parseInt(fpip);
  typ = parseInt(typ);
  // calc values
  fc  = 0.00;
  fvb = fv;
  pmt = 0.00;
  pr  = 0.00;
  ppr = 0.00;
  for (i = 0; i < 100; i++) {
    pv = pv + (pr - ppr);
    ppr = pr;
    pmt = calc_pmt (ir, np, pv, fvb, fp, typ);
    if (fv && fpip) fvb = fv + pmt;
    fc = (np * pmt) - pv;
    pr = (pv + fc) / 100 * ifact;
  }
  return pmt;
}


function calc_pmt (ir, np, pv, fv, fp, typ) {
  // correct internal php values
  ir = parseFloat(ir);
  np = parseInt(np);
  fv = parseFloat(fv);
  pv = parseFloat(pv);
  typ = parseInt(typ);
  pv = (pv *(1+ir/100/365*(fp-30)));
  // Calculate the PVIF and FVIFA
  pvif = calc_pvif (ir/1200, np);
  fvifa = calc_fvifa (ir/1200, np);
  var pmt = -((-pv * pvif - fv ) / ((1.0 + (ir/1200) * typ) * fvifa));
  return pmt;
}

function calc_pvif (ir, np) {
  return (Math.pow (1 + ir, np));
}

function calc_fvifa (ir, np) {
  if (ir == 0)
    return np;
  else
    return (Math.pow (1 + ir, np) - 1) / ir;
}

function getMonthName (month) {
  var months = new Array();
  months[1] = 'January';
  months[2] = 'February';
  months[3] = 'March';
  months[4] = 'April';
  months[5] = 'May';
  months[6] = 'June';
  months[7] = 'July';
  months[8] = 'August';
  months[9] = 'September';
  months[10] = 'October';
  months[11] = 'November';
  months[12] = 'December';
  if (month >= 1 && month <= 12)
    return months[month];
  return '';
}

// ****************************************************************
//  STRING FUNCTIONS
// ****************************************************************

function serializeVariable (name, variable) {
  ser = 's:' + name.length + ':"' + name + '";s:' + variable.toString().length + ':"' + variable + '";';
  return ser;
}

String.prototype.trim = function() {
  // skip customering and trailing whitespace
  // and return everything in between
  var x=this;
  x=x.replace(/^\s*(.*)/, "$1");
  x=x.replace(/(.*?)\s*$/, "$1");
  return x;
}

if (!Array.prototype.indexOf) {
  Array.prototype.indexOf = function(elt /*, from*/) {
    var len = this.length;
    var from = Number(arguments[1]) || 0;
    from = (from < 0)
         ? Math.ceil(from)
         : Math.floor(from);
    if (from < 0)
      from += len;

    for (; from < len; from++) {
      if (from in this && this[from] === elt)
        return from;
    }
    return -1;
  };
}

// ****************************************************************
//  TOOLTIP STUFF FOLLOWS
// ****************************************************************

// ********************************
// application-specific functions
// ********************************

// store variables to control where the popup will appear relative to the cursor position
// positive numbers are below and to the right of the cursor, negative numbers are above and to the left
var xOffset = 0;
var yOffset = 8;

function showPopup (targetObjectId, eventObj) {
  if(eventObj) {
    // hide any currently-visible popups
    hideCurrentPopup();
    // stop event from bubbling up any farther
    eventObj.cancelBubble = true;
    // move popup div to current cursor position
    // (add scrollTop to account for scrolling for IE)
    var newXCoordinate = (eventObj.pageX)?eventObj.pageX + xOffset:eventObj.x + xOffset + ((document.body.scrollLeft)?document.body.scrollLeft:0);
    var newYCoordinate = (eventObj.pageY)?eventObj.pageY + yOffset:eventObj.y + yOffset + ((document.body.scrollTop)?document.body.scrollTop:0);
    moveObject(targetObjectId, newXCoordinate, newYCoordinate);
    // and make it visible
    if( changeObjectVisibility(targetObjectId, 'visible') ) {
      // if we successfully showed the popup
      // store its Id on a globally-accessible object
      window.currentlyVisiblePopup = targetObjectId;
      return true;
    } else {
      // we couldn't show the popup, boo hoo!
      return false;
    }
  } else {
    // there was no event object, so we won't be able to position anything, so give up
    return false;
  }
} // showPopup

function hideCurrentPopup() {
  // note: we've stored the currently-visible popup on the global object window.currentlyVisiblePopup
  if(window.currentlyVisiblePopup) {
    changeObjectVisibility(window.currentlyVisiblePopup, 'hidden');
    window.currentlyVisiblePopup = false;
  }
} // hideCurrentPopup


// ***********************
// hacks and workarounds *
// ***********************

// initialize hacks whenever the page loads
window.onload = initializeHacks;

// setup an event handler to hide popups for generic clicks on the document
document.onclick = hideCurrentPopup;

function initializeHacks() {
  // this ugly little hack resizes a blank div to make sure you can click
  // anywhere in the window for Mac MSIE 5
  if ((navigator.appVersion.indexOf('MSIE 5') != -1)
      && (navigator.platform.indexOf('Mac') != -1)
      && getStyleObject('blankDiv')) {
    window.onresize = explorerMacResizeFix;
  }
  resizeBlankDiv();
  // this next function creates a placeholder object for older browsers
  createFakeEventObj();
}

function createFakeEventObj() {
  // create a fake event object for older browsers to avoid errors in function call
  // when we need to pass the event object to functions
  if (!window.event) {
    window.event = false;
  }
} // createFakeEventObj

function resizeBlankDiv() {
  // resize blank placeholder div so IE 5 on mac will get all clicks in window
  if ((navigator.appVersion.indexOf('MSIE 5') != -1)
      && (navigator.platform.indexOf('Mac') != -1)
      && getStyleObject('blankDiv')) {
    getStyleObject('blankDiv').width = document.body.clientWidth - 20;
    getStyleObject('blankDiv').height = document.body.clientHeight - 20;
  }
}

function explorerMacResizeFix () {
  location.reload(false);
}

// ************************
// layer utility routines *
// ************************

function getStyleObject(objectId) {
  // cross-browser function to get an object's style object given its id
  if(document.getElementById && document.getElementById(objectId)) {
    // W3C DOM
    return document.getElementById(objectId).style;
  } else if (document.all && document.all(objectId)) {
    // MSIE 4 DOM
    return document.all(objectId).style;
  } else if (document.layers && document.layers[objectId]) {
    // NN 4 DOM.. note: this won't find nested layers
    return document.layers[objectId];
  } else {
    return false;
  }
} // getStyleObject

function changeObjectVisibility(objectId, newVisibility) {
  // get a reference to the cross-browser style object and make sure the object exists
  var styleObject = getStyleObject(objectId);
  if(styleObject) {
    styleObject.display = (newVisibility=="visible") ? "block" : "none";
    styleObject.visibility = newVisibility;
    return true;
  } else {
    // we couldn't find the object, so we can't change its visibility
    return false;
  }
} // changeObjectVisibility

function moveObject(objectId, newXCoordinate, newYCoordinate) {
  // get a reference to the cross-browser style object and make sure the object exists
  var styleObject = getStyleObject(objectId);
  if(styleObject) {
    styleObject.left = newXCoordinate;
    styleObject.top = newYCoordinate;
    return true;
  } else {
    // we couldn't find the object, so we can't very well move it
    return false;
  }
} // moveObject


/**
 * This array is used to remember mark status of rows in browse mode
 */
var marked_row = new Array;

/**
 * Sets/unsets the pointer and marker in browse mode
 *
 * @param   object    the table row
 * @param   interger  the row number
 * @param   string    the action calling this script (over, out or click)
 * @param   string    the default background color
 * @param   string    the color to use for mouseover
 * @param   string    the color to use for marking a row
 *
 * @return  boolean  whether pointer is set or not
 */
function setPointer(theRow, theRowNum, theAction, theDefaultColor, thePointerColor, theMarkColor)
{
    var theCells = null;

    // 1. Pointer and mark feature are disabled or the browser can't get the
    //    row -> exits
    if ((thePointerColor == '' && theMarkColor == '')
        || typeof(theRow.style) == 'undefined') {
        return false;
    }

    // 2. Gets the current row and exits if the browser can't get it
    if (typeof(document.getElementsByTagName) != 'undefined') {
        theCells = theRow.getElementsByTagName('td');
    }
    else if (typeof(theRow.cells) != 'undefined') {
        theCells = theRow.cells;
    }
    else {
        return false;
    }

    // 3. Gets the current color...
    var rowCellsCnt  = theCells.length;
    var domDetect    = null;
    var currentColor = null;
    var newColor     = null;
    // 3.1 ... with DOM compatible browsers except Opera that does not return
    //         valid values with "getAttribute"
    if (typeof(window.opera) == 'undefined'
        && typeof(theCells[0].getAttribute) != 'undefined') {
        currentColor = theCells[0].getAttribute('bgcolor');
        domDetect    = true;
    }
    // 3.2 ... with other browsers
    else {
        currentColor = theCells[0].style.backgroundColor;
        domDetect    = false;
    } // end 3

    // 3.3 ... Opera changes colors set via HTML to rgb(r,g,b) format so fix it
    if (currentColor.indexOf("rgb") >= 0)
    {
        var rgbStr = currentColor.slice(currentColor.indexOf('(') + 1,
                                     currentColor.indexOf(')'));
        var rgbValues = rgbStr.split(",");
        currentColor = "#";
        var hexChars = "0123456789ABCDEF";
        for (var i = 0; i < 3; i++)
        {
            var v = rgbValues[i].valueOf();
            currentColor += hexChars.charAt(v/16) + hexChars.charAt(v%16);
        }
    }

    // 4. Defines the new color
    // 4.1 Current color is the default one
    if (currentColor == ''
        || currentColor.toLowerCase() == theDefaultColor.toLowerCase()) {
        if (theAction == 'over' && thePointerColor != '') {
            newColor              = thePointerColor;
        }
        else if (theAction == 'click' && theMarkColor != '') {
            newColor              = theMarkColor;
            marked_row[theRowNum] = true;
            // Garvin: deactivated onclick marking of the checkbox because it's also executed
            // when an action (like edit/delete) on a single item is performed. Then the checkbox
            // would get deactived, even though we need it activated. Maybe there is a way
            // to detect if the row was clicked, and not an item therein...
            // document.getElementById('id_rows_to_delete' + theRowNum).checked = true;
        }
    }
    // 4.1.2 Current color is the pointer one
    else if (currentColor.toLowerCase() == thePointerColor.toLowerCase()
             && (typeof(marked_row[theRowNum]) == 'undefined' || !marked_row[theRowNum])) {
        if (theAction == 'out') {
            newColor              = theDefaultColor;
        }
        else if (theAction == 'click' && theMarkColor != '') {
            newColor              = theMarkColor;
            marked_row[theRowNum] = true;
            // document.getElementById('id_rows_to_delete' + theRowNum).checked = true;
        }
    }
    // 4.1.3 Current color is the marker one
    else if (currentColor.toLowerCase() == theMarkColor.toLowerCase()) {
        if (theAction == 'click') {
            newColor              = (thePointerColor != '')
                                  ? thePointerColor
                                  : theDefaultColor;
            marked_row[theRowNum] = (typeof(marked_row[theRowNum]) == 'undefined' || !marked_row[theRowNum])
                                  ? true
                                  : null;
            // document.getElementById('id_rows_to_delete' + theRowNum).checked = false;
        }
    } // end 4

    // 5. Sets the new color...
    if (newColor) {
        var c = null;
        // 5.1 ... with DOM compatible browsers except Opera
        if (domDetect) {
            for (c = 0; c < rowCellsCnt; c++) {
                theCells[c].setAttribute('bgcolor', newColor, 0);
            } // end for
        }
        // 5.2 ... with other browsers
        else {
            for (c = 0; c < rowCellsCnt; c++) {
                theCells[c].style.backgroundColor = newColor;
            }
        }
    } // end 5

    return true;
} // end of the 'setPointer()' function
