
/*
    This contains all html ui related functions that need to be cross browser compatible
*/

    
////////////////////////////////////////////////////////////////

// xGetElementById r2, Copyright 2001-2007 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL
function xGetElementById(e)
{
  if(typeof(e)=='string') {
    if(document.getElementById) e=document.getElementById(e);
    else if(document.all) e=document.all[e];
    else e=null;
  }
  return e;
}

/*  hides an element  */
function xHide (id) {
  var div = this.xGetElementById(id);
  if (div!=null) div.style.display = "none";
}

/*  shows an element  */
function xShow (id) {
  var div = this.xGetElementById(id);
  if (div!=null) div.style.display = "inline";

}

/*  gets an elements inner text  */
function xGetInnerText(id) {
    var element = xGetElementById(id);
    if (element==null) return null;
        
    if(document.all)
        return element.innerText;
    else
        return element.textContent;
}

/*  sets an elements inner text  */
function xSetInnerText(id, value) {
    var element = xGetElementById(id);
    if (element==null) return;
    
    if(document.all)
        element.innerText = value;
    else
        element.textContent = value;
}


/*  determines if all arguments are 'defined'*/
function xDef() {
	for(var i=0; i<arguments.length; ++i){if(typeof(arguments[i])=='undefined') return false;}
	return true;
}

/*  returns the the inner height of the window not including any scrollbar */
function xClientHeight() {
	var v=0,d=document,w=window;
	if((!d.compatMode || d.compatMode == 'CSS1Compat') && !w.opera && d.documentElement && d.documentElement.clientHeight) {
		v=d.documentElement.clientHeight;
	} else if(d.body && d.body.clientHeight) {
		v=d.body.clientHeight;
	} else if(xDef(w.innerWidth,w.innerHeight,d.width)) {
		v=w.innerHeight;
		if (d.width>w.innerWidth) v-=16;
	}
	return v;
}

/*  The inner width of the window not including any scrollbar.  */
function xClientWidth() {
  var v=0,d=document,w=window;
  if((!d.compatMode || d.compatMode == 'CSS1Compat') && !w.opera && d.documentElement && d.documentElement.clientWidth)
    {v=d.documentElement.clientWidth;}
  else if(d.body && d.body.clientWidth)
    {v=d.body.clientWidth;}
  else if(xDef(w.innerWidth,w.innerHeight,d.height)) {
    v=w.innerWidth;
    if(d.height>w.innerHeight) v-=16;
  }
  return v;
}

/*  Return and optionally set the element's height. It attempts to return and/or set the equivalent of 'offsetHeight'.  */
function xHeight(e,h)
{
  if(!(e=xGetElementById(e))) return 0;
  if (xNum(h)) {
    if (h<0) h = 0;
    else h=Math.round(h);
  }
  else h=-1;
  var css=xDef(e.style);
  if (e == document || e.tagName.toLowerCase() == 'html' || e.tagName.toLowerCase() == 'body') {
    h = xClientHeight();
  }
  else if(css && xDef(e.offsetHeight) && xStr(e.style.height)) {
    if(h>=0) {
      var pt=0,pb=0,bt=0,bb=0;
      if (document.compatMode=='CSS1Compat') {
        var gcs = xGetComputedStyle;
        pt=gcs(e,'padding-top',1);
        if (pt !== null) {
          pb=gcs(e,'padding-bottom',1);
          bt=gcs(e,'border-top-width',1);
          bb=gcs(e,'border-bottom-width',1);
        }
        // Should we try this as a last resort?
        // At this point getComputedStyle and currentStyle do not exist.
        else if(xDef(e.offsetHeight,e.style.height)){
          e.style.height=h+'px';
          pt=e.offsetHeight-h;
        }
      }
      h-=(pt+pb+bt+bb);
      if(isNaN(h)||h<0) return;
      else e.style.height=h+'px';
    }
    h=e.offsetHeight;
  }
  else if(css && xDef(e.style.pixelHeight)) {
    if(h>=0) e.style.pixelHeight=h;
    h=e.style.pixelHeight;
  }
  return h;
}

/*  Determine if the arguments are of type Number  */
function xNum()
{
  for(var i=0; i<arguments.length; ++i){if(isNaN(arguments[i]) || typeof(arguments[i])!='number') return false;}
  return true;
}

/* Determine if all arguments are of type 'string'. */
function xStr(s)
{
  for(var i=0; i<arguments.length; ++i){if(typeof(arguments[i])!='string') return false;}
  return true;
}

/*  A safe wrapper for getComputedStyle and currentStyle.  */
function xGetComputedStyle(e, p, i)
{
  if(!(e=xGetElementById(e))) return null;
  var s, v = 'undefined', dv = document.defaultView;
  if(dv && dv.getComputedStyle){
    s = dv.getComputedStyle(e,'');
    if (s) v = s.getPropertyValue(p);
  }
  else if(e.currentStyle) {
    v = e.currentStyle[xCamelize(p)];
  }
  else return null;
  return i ? (parseInt(v) || 0) : v;
}

/*  Converts a CSS property name string (dash-separated) to a camel-cased string (style object property name).  */
function xCamelize(cssPropStr)
{
  var i, c, a = cssPropStr.split('-');
  var s = a[0];
  for (i=1; i<a.length; ++i) {
    c = a[i].charAt(0);
    s += a[i].replace(c, c.toUpperCase());
  }
  return s;
}

/*
    Returns an array of elements which are descendants of parentEle and have tagName and clsName. 
    If parentEle is null or not present, document will be used. If tagName is null or not present, "*" will be used.
    
    Parameters
        c   ClsName        String           
        p   ParentEle      Element reference
        t   TagName        String
        f   Callback       Callback function, iterates thru the returned list. Is passed a reference to each Element object found.
    Return
        Always returns an array but it may have zero length.
*/
function xGetElementsByClassName(c,p,t,f)
{
  var r = new Array();
  var re = new RegExp("(^|\\s)"+c+"(\\s|$)");
//  var e = p.getElementsByTagName(t);
  var e = xGetElementsByTagName(t,p); // See xml comments.
  for (var i = 0; i < e.length; ++i) {
    if (re.test(e[i].className)) {
      r[r.length] = e[i];
      if (f) f(e[i]);
    }
  }
  return r;
}


/*
    Returns an array of elements which are descendants of parent and have tagName. 
    If parent is null or not present, document will be used. If tagName is null or not present, "*" will be used.
    
    Parameters
        t   tagName  string
        p   parent  ID string or element reference
    
    Return
        a, possibly empty, node list
*/
function xGetElementsByTagName(t,p)
{
  var list = null;
  t = t || '*';
  p = xGetElementById(p) || document;
  if (typeof p.getElementsByTagName != 'undefined') { // DOM1
    list = p.getElementsByTagName(t);
    if (t=='*' && (!list || !list.length)) list = p.all; // IE5 '*' bug
  }
  else { // IE4 object model
    if (t=='*') list = p.all;
    else if (p.all && p.all.tags) list = p.all.tags(t);
  }
  return list || [];
}










