// Copyright 2007 Google Inc. All Rights Reserved.

function px(size) { return size + "px"; };
function em(size) { return size + "em"; };

function makeDiv(doc, style) { 
    var div = doc.createElement('div'); 
    if (!style) {
        // default stylle for divs.  This is probably a bad thing to do
        style = { position: 'absolute', left: px(0), top: px(0)};
    }
    for (var name in style) {
        div.style[name] = style[name];
    }
    return(div);
}


function makeImage(doc, src) {
    var img = document.createElement('img');
    img.src = src;
    return(img);
}



function getPosition(elem) {
    var offset = 0;
    var x = 0; y = 0;
    var w = elem.offsetWidth;
    var h = elem.offsetHeight;
    while (elem != null) {
        y += elem.offsetTop;
        x += elem.offsetLeft;
        elem = elem.offsetParent;
    }
    var out = { top: y, left: x, width: w, height: h};
    return(out);
}

// Remove  all of an DOM element's children
function removeChildren(element) {
    var t;
    var children = Array();
    while((t = element.lastChild) != null) {
        children.push(element.removeChild(t));
    }
    return(children);
}

function formatFloat(n,p) { 
    var txt = (""+n).split(".");
    return(txt.length == 1 ? n.toString() : txt[0] + "." + txt[1].substr(0,p));
}

function wrap(value, min, max) {
  while (value > max) {
    value -= (max - min);
  }
  while (value < min) {
    value += (max - min);
  }
  return value;
}

function toDeg(x) { return x*180/Math.PI; }

function getStyle(elem, name) {
    if (elem.currentStyle) 
        return(elem.currentStyle);
    else if (document.defaultView && document.defaultView.getComputedStyle)
        return(getComputedStyle(elem, name));
    else 
        return(null);
}

function htmlEscape(s) {
	s=s.replace(/&/g,'&amp;'); 
	s=s.replace(/>/g,'&gt;');
	s=s.replace(/</g,'&lt;');
	return s;
}


// /////////////////////////////////////////////////////////////////////
function $(id, doc) {
  if (!doc) doc = document;
  return doc.getElementById(id);
}

/*
** getDocumentFromFrame - Cross-browser code to find the document in an iframe
*/
function getDocumentFromFrame(frame) {
  var doc;
  if (frame.contentDocument) {
    doc = frame.contentDocument;
  } else if (frame.contentWindow) {
    doc = frame.contentWindow.document;
  } else {
    doc = window.frames[frame].document;
  }
  return(doc);
}

var Class = {
  create: function() {
    return function() {
      this.initialize.apply(this, arguments);
    }
  }
}
// method for extending a class
Object.extend = function(destination, source) {
  for (property in source) {
    destination[property] = source[property];
  }
  return destination;
}


/**
 * Call a function or evaluate an expression after a specified number of
 * milliseconds.
 *
 * Equivalent to the standard window.setTimeout function, but the given
 * function executes as a method of this instance. So the function passed to
 * objectSetTimeout can contain references to this.
 *    objectSetTimeout(this, function() { alert(this.x) }, 1000);
 *
**/

function objectSetTimeout(object, command, milliseconds) {
  return window.setTimeout(function() {
    command.call(object);
  }, milliseconds);
}



/**
 * Creates a text node with the given value.
 */
function createTextNode(value, owner) {
  var element = ownerDocument(owner).createTextNode(value);
  if (owner) {
    appendChild(owner, element);
  }
  return element;
}

/**
 * Returns the document owner of the given element. In particular,
 * returns window.document if node is null or the browser does not
 * support ownerDocument.  If the node is a document itself, returns
 * itself.
 */
var DOM_DOCUMENT_NODE = 9;
function ownerDocument(node) {
  if (!node) {
    return document;
  } else if (node.nodeType == DOM_DOCUMENT_NODE) {
    return (node);
  } else {
    return node.ownerDocument || document;
  }
}

function foreach(array, fn) {
  var I = array.length;
  for (var i = 0; i < I; ++i) {
    fn(array[i], i);
  }
}

function delegate(c1, c0) {
  var f0 = function() {};
  f0.prototype = c0.prototype;
  c1.prototype = new f0;
}

function map(list, func) {
  var newList = [];
  for (var i = 0 ; i < list.length ; i++) {
    newList.push(func(list[i]));
  }
  return(newList)
}

function getChildByClass(pElem, className) {
  var children = pElem.childNodes;
  var elements = new Array();

  for (var i = 0; i < children.length; i++) {
    var child = children[i];
	if (child.className) {
	  var classNames = child.className.split(' ');
      for (var j = 0; j < classNames.length; j++) {
        if (classNames[j] == className) {
          return (child);
        }
      }
	}
  }
  var rval;
  for (var i = 0 ; i < children.length ; i++) {
    var child = children[i];
    if (child.nodeType == 1 && (rval = getChildByClass(child, className)) != null) {
	  return(rval);
    }
  }
  return(null);
}

function grayOut(vis, options) {
  // Pass true to gray out screen, false to ungray
  // options are optional.  This is a JSON object with the following (optional)
  // properties
  // opacity:0-100         // Lower number = less grayout higher = more of a blackout 
  // zindex: #             // HTML elements with a higher zindex appear on top of the gray out
  // bgcolor: (#xxxxxx)    // Standard RGB Hex color code
  // grayOut(true, {'zindex':'50', 'bgcolor':'#0000FF', 'opacity':'70'});
  // Because options is JSON opacity/zindex/bgcolor are all optional and can appear
  // in any order.  Pass only the properties you need to set.
  var options = options || {}; 
  var zindex = options.zindex || 50;
  var opacity = options.opacity || 70;
  var opaque = (opacity / 100);
  var bgcolor = options.bgcolor || '#000000';
  var img = options.img;
  var dark=document.getElementById('darkenScreenObject');
  var msg = document.getElementById('darkenScreenMessage');
  if (!dark) {
    // The dark layer doesn't exist, it's never been created.  So we'll
    // create it here and apply some basic styles.
    // If you are getting errors in IE see:
    // http://support.microsoft.com/default.aspx/kb/927917
    var tbody = document.getElementsByTagName("body")[0];
    var tnode = document.createElement('div');           // Create the layer.
        tnode.style.position='absolute';                 // Position absolutely
        tnode.style.top='0px';                           // In the top
        tnode.style.left='0px';                          // Left corner of the page
        tnode.style.overflow='hidden';                   // Try to avoid making scroll bars            
        tnode.style.display='none';                      // Start out Hidden
        tnode.id='darkenScreenObject';                   // Name it so we can find it later
    tbody.appendChild(tnode);                            // Add it to the web page
    dark=document.getElementById('darkenScreenObject');  // Get the object.
    if (!options.noclick) dark.onclick = function(){ grayOut(false); }
  }
  if (options && options.message && !msg) {
      var msg = document.createElement('div');
      msg.style.position = "absolute";
      msg.style.top = px(getWindowHeight()/2 - 50);
      msg.style.left = px(getWindowWidth()/2 - 200);
      msg.style.padding = px(10);
      msg.style.width = px(400);
      msg.style.height = px(100);
      msg.style.zIndex = 1000;
      msg.style.backgroundColor = "#FFFFFF";
      msg.style.border = "3px inset #888888";
      msg.style.textAlign = "center";
      msg.style.fontFamily = "Arial, sans-serif";
      msg.innerHTML = options.message;
      msg.id = 'darkenScreenMessage';
      document.getElementsByTagName("body")[0].appendChild(msg);
      if (!options.noclick) msg.onclick = function(){ grayOut(false); }
  }      
  if (vis) {
    //set the shader to cover the entire page and make it visible.
    dark.style.opacity=opaque;                      
    dark.style.MozOpacity=opaque;                   
    dark.style.filter='alpha(opacity='+opacity+')'; 
    dark.style.zIndex=zindex;        
    dark.style.backgroundColor=bgcolor;  
    dark.style.width= px(getWindowWidth());
    dark.style.height= px(getWindowHeight());
    dark.style.display='block';                          
    if (img) {
      dark.style.backgroundImage = "url("+img+")";
      dark.style.backgroundRepeat = "repeat";
    }

    if (msg) {
      msg.style.width = px(400);
      msg.style.height = px(100);
      msg.style.display='block';                          
    }

  } else {
     if (msg) {
       msg.style.display='none';
       msg.style.width = 0;
       msg.style.height = 0;
     }
     dark.style.display='none';
  }
}
