//*****************************************************************************************
// get a run-time style value of an element
//************************************************************ util_getCurrentStyleAttrib()
function util_getCurrentStyleAttrib(el, what)
{
if (ldr_microsoft) return el.runtimeStyle[what];
var css=document.defaultView.getComputedStyle(el, null);
return css.getPropertyValue(what);
}

//****************************************************************************************
// walks up the tree hierarchy adding all parent nodes offsetParent pixels to reach
// the "absolute" offset top of an element
//******************************************************************* util_calcOffsetTop()
function util_calcOffsetTop(node)
{
if (!node) return -1;
var result=0;
var msg="";
while (node.offsetParent) 
  {  
  //msg+="offset top+="+node.offsetTop+" of "+node.tagName+" "+node.className+" "+node.id+"\n";
  result+=node.offsetTop; node=node.offsetParent; 
  }
if (msg) alert(msg);
return result;
}

//****************************************************************************************
// walks up the tree hierarchy adding all parent nodes offsetParent pixels to reach
// the "absolute" offset left of an element
//****************************************************************** util_calcOffsetLeft()
function util_calcOffsetLeft(node)
{
if (!node) return -1;
var result=0, cntLevels=0; 
while (node.offsetParent)
  { 
  result+=node.offsetLeft;  
  //alert("added "+node.offsetLeft+" because of ::"+node.tagName+" "+node.id);
  node=node.offsetParent;  cntLevels++;
  }
return result;
}

//****************************************************************************************
// get the value of a parameter appearing in the query string
//**************************************************************** util_extractParameter()
function util_extractParameter(paramName, href)
{
if (!(paramName && href)) return null;
var reStr="[?&]+"+paramName+"=([^&$]+)[&$]?";
var matches=new RegExp(reStr, "i").exec(href);
if ((matches==null) || (matches.length<2)) return null;
return matches[1]; //0th element is the entire string
}

//*****************************************************************************************
// a utility function, mimicking the the basename cmdline program
//************************************************************************* util_basename()
function util_basename(filePath)
{
var result=filePath.replace(/\\/g, '/');
var pos=result.lastIndexOf('/');
if (pos!=-1) result=result.substring(pos+1);
return result;
}

//*****************************************************************************************
// gets e.g "/scripts" and returns "file:///d:/projects/html/cosmoModel/scripts", if the 
// currentprotocol is "file:". Else returns argument unchanged
//********************************************************************* util_absoluteFile()
function util_absoluteFile(ref)
{
if (document.location.protocol!="file:") return ref;
if (ref.charAt(0)!='\/') return ref;   // not-absolute path; can't handle
var path=document.location.href.replace(/\\/g, '/');
var pos=path.indexOf(ldr_rootFile);
return path.substr(0, pos+ldr_rootFile.length-1)+ref;
}

//***************************************************************************
// returns all declared css files as a comma separated list of absolute paths
//***************************************************** util_getStyleSheets()
function util_getStyleSheets()
{
var result="";
var css, pos;
for (var i=0; i<document.styleSheets.length; i++)
  {
  pos=-1;
  css=document.styleSheets.item(i).href;
  if (css)pos=css.lastIndexOf("/styles");
  if (pos>=0) result+=((i)?",":"")+util_absoluteFile(css.substr(pos));
  }
return result;
}

//*****************************************************************************************
// returns the current date in a human readable format (e.g. for "last update" text)
//*************************************************************************** util_getDate()
function util_getDate()
{
var months=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]; 
var date=new Date();
return date.getDate()+" "+months[date.getMonth()]+" "+date.getFullYear();
}

//*****************************************************************************************
// accepts a float and returns a string trying to avoid X.YZ99999999999991 displays
//**************************************************************************** util_float()
function util_float(value, maxDecimals)
{
var multiplier=Math.pow(10, maxDecimals);
var intValue=Math.round(value*multiplier);
var result=intValue/multiplier;
return (result+"").replace(/00{4,}[^0]$/,"");
}

//*****************************************************************************************
// returns the nearest element after elem with the requested tagName
//*************************************************************************** util_getNext()
function util_getNext(fromElem, tag)
{
var srchTag=(tag)?tag:fromElem.tagName; srchTag=srchTag.toLowerCase();
var result=fromElem;
while (true)
  {
  result=result.nextSibling;
  if (!result) return null; if (result.nodeType!=1) continue;  // 1=ELEMENT_NODE
  if (result.tagName.toLowerCase()==srchTag) return result;
  }
}
//*****************************************************************************************
// returns the nearest element before elem with the requested tagName
//*************************************************************************** util_getNext()
function util_getPrev(fromElem, tag)
{
var srchTag=(tag)?tag:fromElem.tagName; srchTag=srchTag.toLowerCase();
var result=fromElem;
while (true)
  {
  result=result.previousSibling;
  if (!result) return null; if (result.nodeType!=1) continue;  // 1=ELEMENT_NODE
  if (result.tagName.toLowerCase()==srchTag) return result;
  }
}

//*****************************************************************************************
// tries to locate the "nearest" parent containing elem, of a requested tag-type  
//************************************************************************* util_getParent()
function util_getParent(elem, parentTagName)
{
var parent=elem; parentTagName=parentTagName.toUpperCase();
while (parent.tagName.toUpperCase()!=parentTagName)
  {
  if (parent==document.documentElement) return null;
  parent=parent.parentNode;
  }
return parent;
}

//*****************************************************************************************
// gets an element and returns (text) only the "wanted" attributes of all its attributes 
//**************************************************i******************** util_getAttribs()
function util_getAttribs(elem, wantedAttrs)
{
var result="";
for (var i=0; i<wantedAttrs.length; i++)
  {
  var val=elem.getAttribute(wantedAttrs[i]);
  if (val) result+=" "+wantedAttrs[i]+"=\""+val+"\"";
  }
return result;
}

//*****************************************************************************************
// it will try first to load a new window with a given link. If this fails (e.g. if
// browser configuration blocks it), it will change the location of the current window 
//*********************************************************************** util_openWindow()
function util_openWindow(link, title)
{
var hwin=window.open(link, title, "");   
if (!hwin) window.location=link; else hwin.focus();
}

//*****************************************************************************************
// a workaround IE's inability to do tbody.innerHTML=msg;
//*********************************************************************** util_ieTBodySet()
function util_ieTBodySet(tbody, msg)
{
var div=document.createElement("div"); 
div.innerHTML="<table><tbody>\n"+msg+"\n</tbody></table>";
var rows=div.getElementsByTagName("tbody").item(0).getElementsByTagName("tr");
for (var i=0; i<rows.length; i++) tbody.appendChild(rows[i].cloneNode(true)); 
delete div;
}


