function debug(element,nonNull,nofuncs) {
  for(var i in element) {
    if(nonNull && !element[i])
      continue;
    if(nofuncs && typeof(element[i]) == 'function')
      continue;
    if(!confirm(i+" "+element[i])) break;
  }
}

function pipe(f1,f2) {
  if(!f2) return f1;
  if(!f1) return f2;
  return function(evt) {
           f1(evt);
           return f2(evt);
  }
}

function getElement(id) {
  if(document.layers)
    return document.layers[id];
  else if(document.getElementById)
    return document.getElementById(id);
  else if(document.all)
    return document.all[id];
  return null; 
}

function getWindowSize() {
  var myWidth = 0, myHeight = 0;
  if( typeof( window.innerWidth ) == 'number' ) {
    //Non-IE
    myWidth = window.innerWidth;
    myHeight = window.innerHeight;
    // alert(1+" "+myWidth+" "+myHeight);
  } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
    //IE 6+ in 'standards compliant mode'
    myWidth = document.documentElement.clientWidth;
    myHeight = document.documentElement.clientHeight;
  } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
    //IE 4 compatible
    myWidth = document.body.clientWidth;
    myHeight = document.body.clientHeight;
  }
  var width = myWidth;
  var height =  myHeight;
  if(document.body.scrollWidth > myWidth)
    height -= 20;
  if(document.body.scrollHeight > myHeight)
    width -= 20;
  var size = new Array(2);
  size[0] = width;
  size[1] = height;
  return size;
}

function getScrollXY(win) {
  if(!win)
    win = window;
  var document = window.document;
  var scrOfX = 0, scrOfY = 0;
  if( typeof( win.pageYOffset ) == 'number' ) {
    //Netscape compliant
    scrOfY = win.pageYOffset;
    scrOfX = win.pageXOffset;
  } else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
    //DOM compliant
    scrOfY = document.body.scrollTop;
    scrOfX = document.body.scrollLeft;
  } else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
    //IE6 standards compliant mode
    scrOfY = document.documentElement.scrollTop;
    scrOfX = document.documentElement.scrollLeft;
  }
  this.x = scrOfX;
  this.y = scrOfY;
  return this;
}

function showLayer(layer,show) {
  var display = show ? 'block' : 'none';
  if(document.layers) {
    var visibility = show ? 'show' : 'hide';
    layer.visibility = visibility;
    layer.display = display;
  }
  else {
    var visibility =  show ? 'visible'	: 'hidden';
    layer.style.visibility = visibility;
    layer.style.display = display;
  }
}

function toggleShow(id) {
  var layer = getElement(id);
  if(layer == null) return;
  if(document.layers) {
    showLayer(layer,!(layer.visibility == 'show'));
  }
  else {
    showLayer(layer,!(layer.style.visibility == 'visible'));
  }
}

function setShow(id,show) {
  var layer = getElement(id);
  showLayer(layer,show);
  return false;
}

function setCSSClass(layer,cssClass) {
  layer.setAttribute("class",cssClass);
  layer.setAttribute("className",cssClass);
}

function getCSSClass(layer) { 
  if(layer.getAttribute) {
    var cls = layer.getAttribute("class");
    if(cls == null)
      cls = layer.getAttribute("className");
    return cls;
  }
  return null;
}

function setClass(id,cssClass) {
  var layer = getElement(id);
  setCSSClass(layer,cssClass);
}

function showCSSForms() {
  var styleSheet = document.styleSheets[0];
  var cssFormButtonStyle;
  if(styleSheet.cssRules)
    cssFormButtonStyle = styleSheet.cssRules[0].style;
  else if(styleSheet.rules)
    cssFormButtonStyle = styleSheet.rules[0].style;
  cssFormButtonStyle.display = 'inline';
  cssFormButtonStyle.visibility = 'visible';
}

function getEvent(event) {
  if (!event) 
    event = window.event;
  return event;
}

function getEventSource(event) {
  event = getEvent(event);
  var target;
  if(event.target)
    target = event.target;
  else if(event.srcElement)
    target = event.srcElement;
  if (target.nodeType == 3) // defeat Safari bug
    target = target.parentNode;
  return target;
}

function getElementLeft(elm) {
  if (elm.pageX)
    return elm.pageX;
  else {
    var xPos = elm.offsetLeft;
    var parent = elm.offsetParent;
    while (parent != null) {
      xPos += parent.offsetLeft;
      parent = parent.offsetParent;
    }
    return xPos;
  }
}

function getElementTop(elm) {
  if (elm.pageY)
    return elm.pageY;
  else {
    var yPos = elm.offsetTop;
    var parent = elm.offsetParent;
    while (parent != null) {
      yPos += parent.offsetTop;
      parent = parent.offsetParent;
    }
    return yPos;
  }
}

function getElementHeight(elm) {
  return elm.offsetHeight;
}

function getElementWidth(elm) {
  return elm.offsetWidth;
}

function maxDimension(elm) {
  var width = elm.offsetWidth;
  var height = elm.offsetHeight;
  for(var i=0;i<elm.childNodes.length;i++) {
    var maxd = maxDimension(elm.childNodes[i]);
    if(maxd[0] > width) width = maxd[0];
    if(maxd[1] > height) height = maxd[1];
  }
  var maxd = new Array(2);
  maxd[0] = width;
  maxd[1] = height;
  return maxd;
}

function displayElement(event,id,overlay,syncWidth,scrollable,nearmouse) {
  var element = getElement(id);
  var source = getEventSource(event);
  if(source && source.style.display == 'none') return;
  showLayer(element,true);
  var event = getEvent(event);
  var leftx = getElementLeft(source);
  var smaxd = maxDimension(source);
  if(smaxd[0] <= 16)
    leftx += smaxd[0]/2;
  var topy = getElementTop(source);
  displayElementXY(element,leftx,topy,source,overlay,syncWidth,scrollable,event,nearmouse);
}

function displayElementXY(element,leftx,topy,source,overlay,syncWidth,scrollable,event,nearmouse) {
  var eheight = 0;
  var win = window;
  if(source)
    eheight = getElementHeight(source);
  else {
    win = window.frameElement.parentNode.ownerDocument.defaultView;
  }
  if(nearmouse) {
    var scrolls = getScrollXY();
    leftx = event.clientX+12+scrolls.x;
    topy = event.clientY+15+scrolls.y;
  }
  else {
    if(!overlay)
      topy += eheight;
  }
  if(syncWidth)
    source.style.width = element.offsetWidth;
  var maxd = maxDimension(element);
  var wind = getWindowSize();
  var scroll = getScrollXY(win);
  var width = maxd[0];
  var height = maxd[1];
  var document = element.ownerDocument;
  var availX = document.body.clientWidth-(leftx-scroll.x);
  var availY = document.body.clientHeight-(topy-scroll.y);
  element.actualpx = leftx;
  element.actualpy = topy;
  if(width>availX) {
    if(scrollable) {
      if(availX >= wind[0]/2) {
        element.style.width = (availX-20)+"px";
        element.style.left = leftx+"px";
      }
      else {
        var maxleftx = leftx + source.offsetWidth;
        if(maxleftx > document.body.clientWidth)
	  maxleftx = document.body.clientWidth;
        if(width > maxleftx) {
	  width = maxleftx;
          element.style.width = width+"px";
	}
        element.style.left = (maxleftx - width)+"px";
      }
    }
    else {
      if(leftx>(width-availX))
        element.style.left = (leftx-(width-availX))+"px";
      else {
        element.style.left = (document.body.clientWidth-width)+"px";
      }
    }
  }
  else
    element.style.left = leftx+"px";

  if(height>availY) {
    if(scrollable) {
      if(availY >= wind[1]/2) {
        element.style.height = (availY-20)+"px";
        element.style.top = topy+"px";
      }
      else {
        var eh = eheight;
	if(overlay) eheight = 0;
        if(height > (topy-eheight-scroll.y)) {
	  height = topy-eheight-scroll.y;
          element.style.height = height+"px";
	}
        element.style.top = (topy - height - eheight)+"px";
      }
    }
    else {
      if(topy>(height-availY))
        element.style.top = (topy-(height-availY))+"px";
      else
        element.style.top = (document.body.clientHeight-height)+"px";
    }
  }
  else
    element.style.top = topy+"px";
}

function positionElement(element,source,overlay) {
  var leftx = getElementLeft(source);
  var topy = getElementTop(source);
  if(!overlay)
    topy += getElementHeight(source);
  element.style.left = leftx;
  element.style.top = topy;
}

var currentElement;
var currentEvent;
function closeCurrentElement() {
  if(currentElement != null) {
    setShow(currentElement,false);
    currentElement = null;
  }
}

document.onmouseup = pipe(function (evt) {
            var source = getEventSource(evt);
	    var p = source;
	    if(p.nodeName == "HTML") return; // for scrollbar
	    var curElement = getElement(currentElement);
	    while(p != document && p != curElement) {
	      p = p.parentNode;
	    }
	    if(p == document)
              closeCurrentElement();
          },document.onmouseup);

function showPopup(event,id,scrollable,nearmouse) {
  if(scrollable == null) scrollable = true;
  closeCurrentElement();
  currentElement = id;
  currentEvent = event;
  displayElement(event,id,false,false,scrollable,nearmouse);
  return false;
}

function showInline(event,id,singleton) {
  if(singleton) {
    closeCurrentElement();
    currentElement = id;
  }
  displayElement(event,id,true,false);
  return false;
}

function verifySelection(field,message) {
  if(field.length) {
    for(var counter = 0; counter < field.length; counter++) {
      if(field[counter].checked)
        return true;
    }
  }
  else if(field) {
    if(field.checked)
      return true;
  }
  alert(message);
  return false;
}

function confirmAndNavigate(message,url) {
  if(confirm(message)) {
    window.location.href = url;
  }
  return false;
}

function confirmAndSubmit(message,form) {
  if(confirm(message))
    form.submit();
}

function getParent(node,parentTag) {
  var parent = node.parentNode;
  while(parent != null && parent.nodeName != parentTag)
    parent = parent.parentNode;
  return parent;
}

function setRowClass(evt,clas) { // private
  var src = getEventSource(evt);
  var tr = getParent(src,"TR");
  var table = getParent(src,"TABLE");
  var rows = table.getElementsByTagName("tr");
  var i;
  for(i=0;i<rows.length;i++)
    if(rows[i] == tr) break;
  var cls = getCSSClass(tr);
  for(var j=i-1;j>=0;j--) {
    if(getCSSClass(rows[j]) == cls)
      setCSSClass(rows[j],clas);
    else break;
  }
  for(var j=i;j<rows.length;j++) {
    if(getCSSClass(rows[j]) == cls)
      setCSSClass(rows[j],clas);
    else break;
  }
}

function setTableClasses(tableId,headerClass,oddClass,evenClass,highlightClass,headerSpan,rowspan) {
  var mouseOver = function(evt) {
    setRowClass(evt,highlightClass);
  }
  var mouseOutOdd = function(evt) {
    setRowClass(evt,oddClass);
  }
  var mouseOutEven = function(evt) {
    setRowClass(evt,evenClass);
  }
  var table = document.getElementById(tableId);
  if(rowspan == null) rowspan = 1;
  if(table == null) return;
  var rows = table.getElementsByTagName("tr");
  var i = 0;
  if(headerClass != null) {
    if(headerSpan == null)
      headerSpan = 1;
    for(;i<headerSpan;i++)
      setCSSClass(rows[i],headerClass);
  }
  var odd = true;
  var cssClass;
  for(;i<rows.length;i+=rowspan) {
    if(odd) {
      odd = false;
      cssClass = oddClass;
    }
    else {
      odd = true;
      cssClass = evenClass;
    }
    for(var j=0;j<rowspan;j++) {
      var row = rows[i+j];
      var tds = row.getElementsByTagName("td");
      var maxRowspan = 1;
      for(var d=0;d<tds.length;d++) {
        var tdrowspan = tds[d].getAttribute("rowspan");
        if(tdrowspan > maxRowspan)
	  maxRowspan = tdrowspan;
      }
      for(var r=0;r<maxRowspan;r++) {
        row = rows[i+j+r];
        setCSSClass(row,cssClass);
        row.onmouseover = mouseOver;
        row.onmouseout = (cssClass == oddClass) ? mouseOutOdd : mouseOutEven;
      }
      i += (maxRowspan-1);
    }
    if(rows.length > headerSpan) {
      var tds = rows[0].getElementsByTagName("th");
      if(tds.length == 0)
        tds = rows[0].getElementsByTagName("td");
      if(tds.length > 0) {
        if(tds.length == 1) {
          setCSSClass(tds[0],"tlrrb");
	}
	else {
          setCSSClass(tds[0],"tlb");
          setCSSClass(tds[tds.length-1],"trb");
	}
      }
      tds = rows[rows.length-1].getElementsByTagName("td");
      if(tds.length > 0) {
        if(tds.length == 1) {
          setCSSClass(tds[0],"blrrb");
	}
	else {
          setCSSClass(tds[0],"blb");
          setCSSClass(tds[tds.length-1],"brb");
	}
      }
    }
  }
}

function newValue(oval,nval,append,operator) {
  if(nval == "") return oval;
  if(nval.indexOf(' ') >= 0)
    nval = "\""+nval+"\"";
  var val = nval;
  if(append) {
    if(operator == null) {
      if(oval.length > 0)
        val = oval+" "+nval;
    } else {
      if(oval.length > 0)
        val = oval+" "+operator+" "+nval;
    }  
  }
  return val;
}

function setEventField(event,append,duplicate,operator,casesensitive) {
  var source = getEventSource(event);
  var svalue;
  if(source.options)
    svalue = source.options[source.selectedIndex].value;
  else
    svalue = source.value;
  var form = source.form;
  var fhname = source.name;
  var fname = fhname.substr(0,fhname.length-7);
  setField(form,fname,svalue,append,duplicate,operator,casesensitive);
}

function setField(form,fname,svalue,append,duplicate,operator,casesensitive) {
  var fvalue = form[fname].value;
  if(duplicate)
    form[fname].value = newValue(fvalue,svalue,append,operator);
  else {
    var oval;
    var nval;
    if(!casesensitive) {
      oval = fvalue.toLowerCase();
      nval = svalue.toLowerCase();
    }
    var present = false;
    if(oval == nval)
      present = true;
    else if(oval.length > nval.length) { 
      if(oval.substr(0,nval.length+1) == (nval+" "))
        present = true;
      else if(oval.substr(oval.length-nval.length-1,nval.length+1) == (" "+nval))
        present = true;
      else if(oval.indexOf(" "+nval+" ") >= 0)
        present = true;
    }
    if(!present)
      form[fname].value = newValue(fvalue,svalue,append,operator);
  }
}

function clearForm(event) {
  var source = getEventSource(event);
  var form = source.form;
  var elements = form.elements;
  for(var i=0;i<elements.length;i++) {
    var element = elements[i];
    var type = element.type;
    if(type == "text" || type == "textarea")
      element.value = "";
    else if(type == "select-one")
      element.selectedIndex = 0;
    else if(type == "checkbox")
      element.checked = false;
    // TODO: radio and checkbox
  }
}

function setSelection(item,start,length) {
  if(item.createTextRange) {
    var range = item.createTextRange();
    range.moveStart("character",start);
    range.moveEnd("character",length);
    range.select();
  } else if (item.setSelectionRange) {
    item.setSelectionRange(start,start+length);
  }
}

function hosturl() {
  return location.protocol +"//"+location.host;
}

function writePopupFrame(id,width,height) {
  if(width == null) width = 500;
  if(height == null) height = 200;
  document.write("<div width='"+width+"' height='"+height+"' id='"+id+"' style='z-index:1000; display:none; visibility: hidden; position: absolute; background-color: #ffffff; margin: 0px; padding:0px; border: 0px solid #666666'><table><tr><td><input type='button' onClick='setShow(\""+id+"\",false);brightPage();return false' value='Close'><input type='button' onClick='javascript:"+id+".print();' value='Print'></td></tr></table><iframe style='border: 0px; margin:0px;' name='"+id+"'></iframe></div>");
}

function showPopupFrame(event,id,doc,fullPage) {
  frames[id].location.href = doc;
  displayElement(event,id,true);
  if(fullPage) {
    var element = getElement(id);
    element.style.left = (document.body ? document.body.scrollLeft : window.pageXOffset);
    element.style.top = (document.body ? document.body.scrollTop : window.pageYOffset);
    var size = getWindowSize();
    element.style.width = size[0]-20;
    element.style.height = size[1]-20;
    var iframe = element.getElementsByTagName("iframe")[0];
    iframe.style.width = element.style.width;
    iframe.style.height = element.style.height;
    blurPage();
  }
  return false;
}

function writeBlurWindow() {
  document.write("<div id='blurdiv' style='position:absolute;z-index:100;display:none;visibility:hidden;width:100%;background:#eeeeee;opacity:0.8;margin:0px;padding:0px;border:0px;'></div>");
  var body = document.getElementsByTagName("body")[0];
  var syncBlurWindow = function() {
    var blurdiv = getElement("blurdiv");
    blurdiv.style.width = body.scrollWidth;
    blurdiv.style.height = body.scrollHeight;
  }
  if(window.onresize) {
    // TODO
  }
  else
    window.onresize = syncBlurWindow;
}

function blurPage() {
  var body = document.getElementsByTagName("body")[0];
  var blurdiv = getElement("blurdiv");
  showLayer(blurdiv,true);
  blurdiv.style.width = body.scrollWidth;
  blurdiv.style.height = body.scrollHeight;
}

function brightPage() {
  var body = document.getElementsByTagName("body")[0];
  var blurdiv = getElement("blurdiv");
  showLayer(blurdiv,false);
}

function initButtons() {
  var btn;
  var downbtnf = function(evt) {
                   btn = getEventSource(evt);
                   setCSSClass(btn,"downbtn");
                 };
  var upbtnf = function(evt) {
                 if(btn != null) {
                   setCSSClass(btn,"btn");
		   btn = null;
		 }
               };

  document.onmouseup = pipe(upbtnf,document.onmouseup);

  var buttons = document.getElementsByTagName("button");
  for(var i=0;i<buttons.length;i++) {
    buttons[i].onmousedown = downbtnf;
  }

  buttons = document.getElementsByTagName("a");
  for(var i=0;i<buttons.length;i++) {
    if(getCSSClass(buttons[i]) == "btn") {
      buttons[i].onmousedown = downbtnf;
      buttons[i].onmouseup = upbtnf;
    }
  }
}

function showTab(tabs,tabId) {
  for(var i in tabs) {
    var tabbutton = document.getElementById(i);
    if(i==tabId) {
      setShow(tabs[i],true);
      setCSSClass(tabbutton,"atabbutton");
    }
    else {
      setShow(tabs[i],false);
      setCSSClass(tabbutton,"itabbutton");
    }
  }
}

function text(e) {
  if(e.nodeName && e.nodeName.toLowerCase() == "br") return "\n";
  if(e.nodeValue) {
    return e.nodeValue;
  }
  else {
    var str = "";
    for(var c in e.childNodes) {
      str += text(e.childNodes[c]);
    }
    return str;
  }
}

function ancestor(e,aname) {
  while(e && e.nodeName != aname)
    e = e.parentNode;
  return e;
}

function select(form,field,value) {
  var field = document.forms[form][field];
  var options = field.options;
  if(options) {
    for(var i=0;i<options.length;i++) {
      if(options[i].value == value)
        field.selectedIndex = i;
    }
  }
  else if(field.length) {
    for(var i=0;i<field.length;i++) {
      if(field[i].value == value) {
        field[i].checked = true;
      }
    }
  }
  else if(field.value == value) {
    field.checked = true;
  }
}

function loaded() {
  setCSSClass(document.body,"normal");
  var win = window;
  var iframe = win.frameElement;
  if(!iframe) return;
  // var sh = document.documentElement ? document.documentElement.scrollHeight : document.body.scrollHeight;
  var sh = document.body.scrollHeight;
  var sw = document.documentElement ? document.documentElement.scrollWidth : document.body.scrollWidth;
  iframe.style.height = sh+"px";
  iframe.style.width = sw+"px";
  var div = iframe.parentNode;
  div.style.height = getElementHeight(iframe)+"px";
  div.style.width = getElementWidth(iframe)+"px";
  if(div.actualpx) {
    displayElementXY(div,div.actualpx,div.actualpy,null,false,false,false);
  }
}

function html2txt(elem) {
  var html;
  var elm = elem;
  if(typeof(elem) == 'string') {
    elm = getElement(elem);
  }
  if(elm) {
    html = elm.innerHTML;
  }
  else {
    html = elem;
  }
  html = html.replace(/</g,'&lt;');
  return html;
}

function getCSSClassByName(cssClass) {
  cssClass = cssClass.toLowerCase();
  var cssRules;
  if (document.all)
    cssRules = 'rules';
  else if (document.getElementById)
    cssRules = 'cssRules';
  for (var s = 0; s < document.styleSheets.length; s++) {
    var ss = document.styleSheets[s];
    var ssCSSRules = ss[cssRules];
    for (var r = 0; r < ssCSSRules.length; r++) {
      var seltxt = ssCSSRules[r].selectorText;
      seltxt = seltxt.toLowerCase();
      if (seltxt == cssClass) {
        return ssCSSRules[r];
      }
    }
  }
}

function getCSSByFile(file) {
  for (var s = 0; s < document.styleSheets.length; s++) {
    var ss = document.styleSheets[s];
    if(ss.href && ss.href.match(".*"+file+"$"))
      return ss;
  }
}

function setcssprop(cssClass,property,value) {
  var css = getCSSClassByName(cssClass);
  css.style[property] = value;
}

function getcssprop(cssClass,property) {
  var css = getCSSClassByName(cssClass);
  var val = css.style[property];
  if(property.match(/color/i)) {
    if(val.match(/rgb.*/)) {
      var rgb = val.substring(4,val.length);
      rgb = rgb.split(", ");
      for(var i=0;i<rgb.length;i++) rgb[i] = parseInt(rgb[i]);
      val = "#";
      for(var i=0;i<rgb.length;i++) {
        if(rgb[i] < 16) val += "0";
        val += rgb[i].toString(16);
      }
    }
  }
  return val;
}

function getCSSClassCode(cls) {
  var css;
  if(typeof(cls) == 'string')
    css = getCSSClassByName(cls);
  else
    css = cls;
  if(css.cssText)
    return css.cssText;
  else if(css.style.cssText)
    return css.style.cssText ;
}

function getCSSCode(file) {
  var ss = getCSSByFile(file);
  var cssRules;
  if (document.all)
    cssRules = 'rules';
  else if (document.getElementById)
    cssRules = 'cssRules';
  var ssCSSRules = ss[cssRules];
  var html = "<style type='text/css'>";
  for (var r = 0; r < ssCSSRules.length; r++) {
    html += "\n"+getCSSClassCode(ssCSSRules[r]);
  }
  html += "\n</style>";
  return html;
}

function createCookie(name,value,days) {
  if(days) {
    var date = new Date();
    date.setTime(date.getTime()+(days*24*60*60*1000));
    var expires = "; expires="+date.toGMTString();
  }
  else var expires = "";
  document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name) {
  var nameEQ = name + "=";
  var ca = document.cookie.split(';');
  for(var i=0;i < ca.length;i++) {
    var c = ca[i];
    while (c.charAt(0)==' ') c = c.substring(1,c.length);
    if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
  }
  return null;
}

function eraseCookie(name) {
  createCookie(name,"",-1);
}
