/* ======================================================================
DESC: A collection of functions useful for code which has to be
browser-independent, including Netscape 6.
====================================================================== */

/* ======================================================================

New Ways to Reference Elements

(courtesy of Danny Goodman from "Getting Ready for the W3C DOM":
http://developer.iplanet.com/viewsource/goodman_cross/goodman_cross.htm)

Because Internet Explorer has until now been the only scriptable browser to
expose all HTML elements as objects, you may well be familiar with its syntax
for addressing an element by its id property using the document.all
array. For example, given the element 

<P ID="paragraph1">...</P> 

a script could reference that object with 

var elem = document.all.paragraph1 

As a shortcut, you can also omit the "document.all" part of the reference,
and go straight to the object: 

var elem = paragraph1 

The document.all array is not part of the W3C DOM. Instead, the
specification provides a document object method that lets you reference
any object in the document by its ID: 

var elem = document.getElementById("paragraph1") 

The required parameter of the getElementById() method is the ID of the
object (assigned to the element's ID attribute) as a string. This method is
supported in IE5. 

From a practical standpoint, I regard this method as a finger-twisting handful to
type repeatedly inside a script; the method name is case-sensitive, and you have
to remember to use a lowercase "d" as the last letter. But you can simulate
document.all even in a W3C DOM-compliant browser, such as the
NGLayout engine. Coming to our aid is a method of the Core DOM
document object: getElementsByTagName(). This method returns an
array of HTML element objects for a given tag name. You supply the tag
name as the sole parameter (in string form) to the method. Here's the neat
part: The DOM specification notes that the method accepts a wildcard
character ("*") parameter to fetch every tagged element in the document.
While IE5 supports this method, it doesn't support the wildcard parameter (it
will return an array of length zero) - but that's OK, because we can generate
a new property for the W3C DOM document object whenever IE isn't being
used: 

if (document.getElementsByTagName("*")) { 
   document.all = document.getElementsByTagName("*") 
} 

This document.all normalization trick preserves IE's own document.all
collection untouched, yet supplies the equivalent for fully W3C
DOM-compatible browsers. After that, you can reference objects with ID
values the same way in either browser: 

var elem = document.all.paragraph1 

You must exercise some caution, however. If your scripts add, delete, or replace
elements, the makeup of the artificial document.all array doesn't
automatically track the changes to the document's structure. You'll need to
update the document.all array prior to any script statements that refer to
objects. 

While we're on the subject of object references, DHTML authors will be happy to
learn that style sheet properties assigned to objects via inline STYLE attributes
are exposed the same way in IE as in the W3C DOM Level 2 (and
implemented in NGLayout). Style sheet properties are accessed through an
element's style property. For example, to set the font size of the paragraph
shown above, a single cross-browser reference does the job: 

document.all.paragraph1.style.fontSize = "14pt" 
====================================================================== */

var isNav4=false;
var isNav6=false;
var isIE4=false;
var isIE40=false;
/*
 * Browser version snooper; determines your browser
 * (Navigator 4, Navigator 6, or Internet Explorer 4/5)
 */
function setBrowser()
{
	if ((navigator.appVersion.indexOf("MSIE 4") >= 0) && (navigator.appName.indexOf("Explorer") >= 0))
	{
		isIE40 = true;
	}
	else {
	    if (navigator.appVersion.charAt(0) == "4")
		{
			if (navigator.appName.indexOf("Explorer") >= 0)
			{
			isIE4 = true;
			}
			else
			{
				isNav4 = true;
			}
		}
		else if (navigator.appVersion.charAt(0) > "4")
		{
			isNav6 = true;
		}
	}
}

/*
 *
 * Given a selector string, return a style object
 * by searching through stylesheets. Return null if
 * none found
 *
 */
function getStyleBySelector( selector )
{
    if (!isNav6)
    {
        return null;
    }
    var sheetList = document.styleSheets;
    var ruleList;
    var i, j;

    /* look through stylesheets in reverse order that
       they appear in the document */
    for (i=sheetList.length-1; i >= 0; i--)
    {
        ruleList = sheetList[i].cssRules;
        for (j=0; j<ruleList.length; j++)
        {
            if (ruleList[j].type == CSSRule.STYLE_RULE &&
                ruleList[j].selectorText == selector)
            {
                return ruleList[j].style;
            }   
        }
    }
    return null;
}

/*
 *
 * Given an id and a property (as strings), return
 * the given property of that id.  Navigator 6 will
 * first look for the property in a tag; if not found,
 * it will look through the stylesheet.
 *
 * Note: do not precede the id with a # -- it will be
 * prepended when searching the stylesheets
 *
 */
function getIdProperty( id, property )
{
    if (isNav6)
    {
        var styleObject = document.getElementById( id );
        if (styleObject != null)
        {
            styleObject = styleObject.style;
            if (styleObject[property])
            {
                return styleObject[ property ];
            }
        }
        styleObject = getStyleBySelector( "#" + id );
        return (styleObject != null) ?
            styleObject[property] :
            null;
    }
    else if (isNav4)
    {
        return document[id][property];
    }
    else
    {
        return document.all[id].style[property];
    }
}

/*
 *
 * Given an id and a property (as strings), set
 * the given property of that id to the value provided.
 *
 * The property is set directly on the tag, not in the
 * stylesheet.
 *
 */
function setIdProperty( id, property, value )
{
    if (isNav6)
    {
        var styleObject = document.getElementById( id );
        if (styleObject != null)
        {
            styleObject = styleObject.style;
            styleObject[ property ] = value;
        }
        
        /*
        styleObject = getStyleBySelector( "#" + id );
        if (styleObject != null)
        {
            styleObject[property] = value;
        }
        */
    }
    else if (isNav4)
    {
        document[id][property] = value;
    }
    else if (isIE4)
    {
         document.all[id].style[property] = value;
    }
}

/*
 *
 * Move a given id.  If additive is true,
 * then move it by xValue dots horizontally and
 * yValue units vertically.  If additive is
 * false, then move it to (xValue, yValue)
 *
 * Note: do not precede the id with a # -- it will be
 * appended when searching the stylesheets
 *
 * Note also: length units are preserved in Navigator 6
 * and Internet Explorer. That is, if left is 2cm and
 * top is 3cm, and you move to (4, 5), the left will
 * become 4cm and the top 5cm.
 *
 */
function generic_move( id, xValue, yValue, additive )
{
    var left = getIdProperty(id, "left");
    var top = getIdProperty(id, "top");
    var leftMatch, topMatch;

    if (isNav4)
    {
        leftMatch = new Array( 0, left, "");
        topMatch = new Array( 0, top, "");
    }
    else if (isNav6 || isIE4 )
    {
        var splitexp = /([-0-9.]+)(\w+)/;
        leftMatch = splitexp.exec( left );
        topMatch = splitexp.exec( top );
        if (leftMatch == null || topMatch == null)
        {
            leftMatch = new Array(0, 0, "px");
            topMatch = new Array(0, 0, "px");
        }
    }
    left = ((additive) ? parseFloat( leftMatch[1] ) : 0) + xValue;
    top = ((additive) ? parseFloat( topMatch[1] ) : 0) + yValue;
    setIdProperty( id, "left", left + leftMatch[2] );
    setIdProperty( id, "top", top + topMatch[2] );
}

/*
 *
 * Move a given id to position (xValue, yValue)
 *
 */
function moveTo( id, x, y )
{
    generic_move( id, x, y, false );
}

/*
 *
 * Move a given id to (currentX + xValue, currentY + yValue)
 *
 */
function moveBy( id, x, y)
{
    generic_move( id, x, y, true );
}

/*
 *
 * Function used when converting rgb format colors
 * from Navigator 6 to a hex format
 *
 */ 
function hex( n )
{
    var hexdigits = "0123456789abcdef";
    return ( hexdigits.charAt(n >> 4) + hexdigits.charAt(n & 0x0f) );
}

/*
 *
 * Retrieve background color for a given id.
 * The value returned will be in hex format (#rrggbb)
 *
 */ 
function getBackgroundColor( id )
{
    var color;

    if (isNav4)
    {
        color = document[id].bgColor;
    }
    else if (isNav6)
    {
        var parseExp = /rgb.(\d+),(\d+),(\d+)./;
        var rgbvals;
        color = getIdProperty( id, "backgroundColor" );
        if (color)
        {
            rgbvals = parseExp.exec( color );
            if (rgbvals)
            {
                color = "#" + hex( rgbvals[1] ) + hex( rgbvals[2] ) +
                    hex( rgbvals[3] );
            }
        }
        return color;
    }
    else if (isIE4)
    {
        return document.all[id].backgroundColor;
    }
    return "";
}

/*
 *
 * Return a division's document
 * 
 */
function getDocument( divName )
{
    var doc;

    if (isNav4)
    {
        doc = window.document[divName].document;
    }
    else if (isNav6)
    {
        doc = document;
    }
    else if (isIE4)
    {
        doc = document;
    }
    return doc;
}


function elementById( elementString ) { 
  if( document.all ) 
    return eval( "document.all." + elementString + ".style" ); 
  if( document.layers ) 
    return eval( "document.layers." + elementString ); 
  if( document.getElementById ) 
    return document.getElementById( elementString ).style; 
}  

function MoveTo(obj,x,y) 
{ 
     if (parseInt(navigator.appVersion) >= 5 || navigator.appVersion.indexOf["MSIE 5"] != -1) 
     { 
         obj.style.position = "absolute";
         var units = (MoveTo.arguments.length > 3) ? MoveTo.arguments[3] : "px";
         obj.style.left = x + units; 
         obj.style.top = y + units; 
     } 
} 

function MoveBy(obj,x,y) 
{ 
     if (parseInt(navigator.appVersion) >= 5 || navigator.appVersion.indexOf["MSIE 5"] != -1) 
     { 
         obj.style.left = parseInt(obj.style.left) + x; 
         obj.style.top = parseInt(obj.style.top) + y; 
     } 
} 

function HideShow(obj) 
{ 
    if (parseInt(navigator.appVersion) >= 5 || navigator.appVersion.indexOf["MSIE 5"] != -1) 
    {
        if (obj.style.display=="none") 
             obj.style.display="";
        else
             obj.style.display="none";
    }
} 

function dynamiccontentNS6(elementid,content){
	if (document.getElementById){
	rng = document.createRange();
	el = document.getElementById(elementid);
	rng.setStartBefore(el);
	htmlFrag = rng.createContextualFragment(content);
	while (el.hasChildNodes())
		el.removeChild(el.lastChild);
		el.appendChild(htmlFrag);
	}
}

