/*
 Util is a javascript singleton that you can use to do stuff
*/
function Util(){

}

/**
 Browser snifer
**/
var ua           = navigator.userAgent.toLowerCase();
Util.isIE         = ((ua.indexOf("msie") != -1) && (ua.indexOf("opera") == -1) && (ua.indexOf("webtv") == -1));
Util.isIE7P       = (Util.isIE && (window.XMLHttpRequest != null)); // IE7+
Util.isGecko      = (ua.indexOf("gecko") != -1);
Util.isSafari     = (ua.indexOf("safari") != -1);
Util.isKonqueror  = (ua.indexOf("konqueror") != -1);
Util.isFirefox     = (ua.indexOf("firefox") != -1);

/**
 * If an element is a string look it up as the elements id.
 */
Util.getElement = function(element) {
    return (typeof(element) == "string") ? document.getElementById(element) : element;
}

/*
 Gets  the number  of elements  in an associative  array
*/
Util.getArrayLength = function (arr){
  var len=0;
  for (var a in arr) {len++}
  return  len;
}

/*
 Given a  node name  goes ahead and deletes it
 */
Util.deleteNode = function (nodeName){
  var toDelete;
  try {
  toDelete = document.getElementById(nodeName);
  } catch(e) {
    alert("I am  trying to delete this node "+nodeName+" but i could not find it");
  }
  papa = toDelete.parentNode;
  try {
    papa.removeChild(toDelete);

  } catch (e){
      alert(e);
  }
}

/*
 Display an element if it's  hidden and hide it if it's displayed
 Optional second param is desired display type if displayed
*/
Util.toggleDisplay = function (objId,displayType) {
  if (typeof displayType == "undefined") {
      displayType = ""; // will clear to default for the element
  }
  var obj = Util.getElement(objId);
  if (obj.style.display != "none"){
      try{
        obj.style.display = "none";
      } catch (e){
         alert("I did not find this  obj"+objId);
      }
  }
  else {
     obj.style.display = displayType;
  }
}

/*
 Wrapper functions for toggleDisplay
*/
Util.toggleDisplayBlock = function (objId) {
    Util.toggleDisplay(objId, "block");
}
Util.toggleDisplayInline = function (objId) {
    Util.toggleDisplay(objId, "inline");
}

/*
 Executed on the KeyPress event of a textbox,
 counts  the line breaks  and makes
 textbox grow  accordingly.

 For  things  to  look  nice, when  defining  your textarea
 use style="overflow:hidden", that  prevents  scrollbars
 from appearing.

 If  the  size is  over  maxNumberRows  lines, scrollbars appear.
*/
Util.adjustRows = function (textarea,initialNumberOfRows){
  var maxNumberRows= 20;
  var rgLines = textarea.value.split('\n');
  var nRows = 1;

  nRows += rgLines.length;
  if ( nRows >  initialNumberOfRows ){  textarea.rows = Math.min(nRows, maxNumberRows);}

  if (nRows >maxNumberRows) {
       textarea.style.overflowY="scroll";
  } else if (nRows <maxNumberRows) {
       textarea.style.overflowY="hidden";
  }
}


/*
 Return  false  if we catch  enter
 Handy to avoid accidental form submission of FF
 (if you are in a form element,
 hiting enter subsmits  events  on FF)
*/
 Util.checkKey = function ( event ) {
    var key;
    if ( window.event ) {
             key = event.keyCode;
    }
    else  {
             key = event.which;
    }

    return !( key == 13 );
 }


Util.makeVisible = function(objId){
  try{
      document.getElementById(objId).style.display="block";
      } catch (e){
        alert("I did not find this  obj"+objId);
      }
}

Util.makeVisibleInline = function (objId){
  try{
        document.getElementById(objId).style.display="inline";
      } catch (e){
         alert("I did not find this  obj"+objId);
      }
}

Util.makeInvisible =  function (objId){
  try{
        document.getElementById(objId).style.display="none";
      } catch (e){
        alert("I did not find this  obj"+objId);
      }
}


/*
 Positions  an  obj  kind  of like  in the center  of  the screen
 */
Util.positionInCenter = function (obj){

  var  ybuffer =70; // the  client width  has  some  kind  of  offset
  var  x0 = window.document.body.clientWidth/2;
  var  y0 = window.document.body.clientHeight/2; //I think this is the whole browser window

  var deltax = obj.style.width;
  var deltay = obj.style.height;

  deltax = deltax.replace("px", "");
  deltay = deltay.replace("px", "");

  deltax = parseInt(deltax)/2;
  deltay = parseInt(deltay)/2;

  var  x = x0-deltax;
  var  y = y0-deltay+window.document.body.scrollTop-ybuffer;
  obj.style.left=x+"px"
  obj.style.top=y+"px";

}


Util.clearForm =  function (theForm) {


    // Reset select boxes
    theForm.reset();

    // Clear the values of input boxes and textarea
    for (i = 0; i < theForm.elements.length; i++) {
        if (theForm.elements[i].type == 'text' || theForm.elements[i].type == 'textarea') {
            theForm.elements[i].value = '';
        }
    }
}


/*
 Encapsulating the madness arround js  undefined
*/
Util.isDefined =  function (variable) {
  if (variable== undefined || variable == "undefined" || variable=="" || variable==null){
     return  false;
  } else {
    return  true;
  }

}


/*
 Unchecks a textbox
*/
Util.uncheck =  function (id){
 if (document.getElementById(id).checked)  {

     document.getElementById(id).checked = false;
 }
}


/*
   Unchecks/checks all checkboxes with a given prefix
   if prefix is  "cart" it would look for  cart0, cart1, car2, cart3...etc
   You call it like:

   Util.setAllCheckedValue("cart", true);
   This  will check all textboxes cart0, cart1, car2, cart3...cartn

   Util.setAllCheckedValue("cart", false);
   This  will uncheck all textboxes cart0, cart1, car2, cart3...cartn

   See Util.checkAll and Util.uncheckAll for  shortcuts to this  function
*/
Util.setAllCheckedValue = function (prefix, status){
  var count = 0;
  var element = document.getElementById(prefix+count++);
  if (element == null) { // allow for elements starting at 1
     element = document.getElementById(prefix+count++);
  }
  while (element!=null){
     element.checked = status;
     element = document.getElementById(prefix+count++);
  }
}


Util.checkAll = function (prefix)  {
    Util.setAllChecked(prefix, true);
}

Util.uncheckAll = function (prefix)  {
    Util.setAllChecked(prefix, false);
}

/*
 Add event handlers, code  for FF and IE
*/
Util.addEvent =  function (obj, evType, fn){
 if (obj.addEventListener){
   obj.addEventListener(evType, fn, false);
   return true;
 } else if (obj.attachEvent){
   var r = obj.attachEvent("on"+evType, fn);
   return r;
 } else {
   return false;
 }
}

/*
 Remove  event handlers, code  for FF and IE
*/
Util.removeEvent =  function (obj,evType,fn){
   if (obj.addEventListener){
     obj.removeEventListener(evType, fn, false);
     return true;

 } else if (obj.attachEvent){
     var r = obj.detachEvent("on"+evType, fn);
     return r;
 } else {
   return false;
 }

}

/*
 * Get dimensions for the window and the page.
 * (If the window is bigger than the page for an attribute, those values will be returned instead.)
 *
 * @return An object with the following attributes:
 *   window.width  - The width of the window
 *   window.height - The height of the window
 *   page.width    - The width of the page
 *   page.height   - The height of the page.
 */
Util.getWindowSize =  function () {
    var xScroll;
    var yScroll;
    var windowWidth;
    var windowHeight;
    var pageHeight;
    var pageWidth;

    // This code lifted from lightbox

    if (window.innerHeight && window.scrollMaxY) {
        xScroll = document.body.scrollWidth;
        yScroll = window.innerHeight + window.scrollMaxY;
    }
    else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
        xScroll = document.body.scrollWidth;
        yScroll = document.body.scrollHeight;
    }
    else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
        xScroll = document.body.offsetWidth;
        yScroll = document.body.offsetHeight;
    }

    if (self.innerHeight) { // all except Explorer
        windowWidth = self.innerWidth;
        windowHeight = self.innerHeight;
    }
    else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
        windowWidth = document.documentElement.clientWidth;
        windowHeight = document.documentElement.clientHeight;
    }
    else if (document.body) { // other Explorers
        windowWidth = document.body.clientWidth;
        windowHeight = document.body.clientHeight;
    }

    pageHeight = (yScroll < windowHeight) ? windowHeight : yScroll;
    pageWidth = (xScroll < windowWidth) ? windowWidth : xScroll;

    return {
        page:   { width: pageWidth,   height: pageHeight },
        window: { width: windowWidth, height: windowHeight }
    };
}

/*
 Encodes a value as a string and escapes HTML entities.
 */
Util.encodeHTML =  function (value) {
    var str = String(value);
    var sb = new StringBuffer();
    for (var i=0; i<str.length; i++) {
        var ch = str.charAt(i);
        switch (ch) {
            case '<':
                sb.append("&lt;");
                break;
            case '>':
                sb.append("&gt;");
                break;
            case '&':
                sb.append("&amp;");
                break;
            case '"':
                sb.append("&quot;");
                break;
            case '\'':
                sb.append("&#39;");
                break;
            default:
                sb.append(ch);
        }
    }
    return sb.toString();
}


/*
 Returns  true if input is  a positive  or negative numeric field, false otherwise
*/

Util.isNumeric =  function (input){
    if (!Util.isDefined(input)){
       return false;
    }
    var pattern1 = /^-?\d+\.\d+$/ ;
    var pattern2 =  /^-?\.\d+$/;
    var pattern3 =/^-?\d+$/;
    if (input.match(pattern1)!=null ||
        input.match(pattern2)!=null ||
        input.match(pattern3)!=null
    ){
      return  true;

    }
    return false;
}

/*
 Returns  true  if the input  is  just a whitepsace field, false otherwise
*/
Util.isWhiteSpaceOnlyOrEmpty= function (input){
    var pattern=/^\s+$/;

    if (input.match(pattern)!=null || input=="" || !Util.isDefined(input)){
       return true;
    }
    return false;
}

/*
 Offsets  the  position of an element by  the  given amount of pixels
 If element position is  too close to bottom , top, left or
 right of browser window offset by offset amount

  For this  to work the  element has to have  position:absolute
  This  function is  meant to be  used when  you position an  element
  with some  other  utility and later you want to make sure it's  not
  too close to the window  border.
*/

Util.bounceOnWindowBorder = function (element, offset){
   element = Util.getElement(element);
   if (!Util.isDefined(offset)){offset = 50;}
   var windowSize = getWindowSize();
   var y0 = element.style.top;
   var x0 = element.style.left;

    if (!Util.isDefined(x0) || !Util.isDefined(y0)){
      //get  positioning some other way
      var position = Util.getPosition(element);
      xo = position.x;
      y0 = position.y;
    }
    x0 = x0.replace("px", "");
    y0 = y0.replace("px", "");

   // mmm , now  deal  with the borders
   /* x0, y0  position of upperleft corner
      x0, y1: position of lower left corner
      x1,y1;  position of lower right corner
   */
   var deltax = element.style.width;
   var deltay = element.style.height;
   deltax = deltax.replace("px", "");
   deltay = deltay.replace("px", "");

   x1 = x0 + deltax;
   y1 = y0 + deltay;

   if (windowSize.window.width-offset-x1 < offset ){
      // too close to the right, move  left
      x0 = x0 - offset;

   } else if (x0 < offset){
     //too close to left , move  right
     x0 = x0 +offset;

   }
    if (windowSize.window.height-offset-y1 < offset ){
      // too close to the bottom, move  up
      y0 = y1 - offset;

   } else if (y0 < offset){
     //too close to the top , move  down
     y0 = y0 +offset;

   }
   element.style.top  = y0+"px";
   element.style.left = x0+"px";
}



Util.positionLeft = function (objId,x){
   var element = Util.getElement(objId);
   element.style.left=x+"px";
}


Util.positionTop= function (objId,y){
   var element = Util.getElement(objId);
   element.style.top=y+"px";
}

/*
  Get  a position for  an element
  that does not  have  a css left/top  properties defined
*/
Util.getPosition = function (objId){
   var element  = Util.getElement(objId);
   var position = {x:0, y:0};
   while (element){
     position.x += element.offsetLeft;
     position.y += element.offsetTop;
     element = element.offsetParent;
   }
   return  position;
}

/*
 Checks a textbox
*/
Util.check = function(id) {
 if (!document.getElementById(id).checked)  {
     document.getElementById(id).checked = true;
 }
}

/*
 To  use the return obj   of  this  function
 to position another element, do:
     obj.style.top=posObj.y;
     obj.style.left=posObj.x;
  obj must have position absolute
*/
Util.getMousePosition =  function(e){
    var posx = 0;
    var posy = 0;
    if (!e) var e = window.event;
    if (e.pageX || e.pageY)     {
        posx = e.pageX;
        posy = e.pageY;
    }
    else if (e.clientX || e.clientY)    {
        posx = e.clientX + document.body.scrollLeft
            + document.documentElement.scrollLeft;
        posy = e.clientY + document.body.scrollTop
            + document.documentElement.scrollTop;
    }

  var posObj ={  "x": posx,  "y":posy }
  return posObj;
}

/*
 The  top  right  corner  of  the  object  would  be positioned
 where the  mouse click  happened
 For  this  to work  the  css position property of  the obj moved
 has  to be  'absolute'

 Call this function like
 onclick=Util.positionwhereMouseIs(event, objId);
 Js populates event for you
 */
 Util.positionWhereMouseIs = function(e,objId) {
    var obj = Util.getElement(objId);
    var posObj = Util.getMousePosition(e);
    //add px or bad thins  happen
    obj.style.top=posObj.y+"px";
    obj.style.left=posObj.x+"px";
}

/*
    StringBuffer below
     to use
     var  s = new Stringbuffer();
     s.append("hello");
     alert(s.tostring());
*/
function  StringBuffer(){this.buffer=[];}

StringBuffer.prototype.append = function(string){
  this.buffer.push(string);
  return  this;
}

StringBuffer.prototype.toString = function() {
  return this.buffer.join("");
}

