var globals = new Array;
var gBrowser = new Browsers();

window.onload = function(){ gBrowser.LaunchInits(); };

function Point ( pX, pY )
{
    this.x = pX;
    this.y = pY;
    
    return this;
}

function Bounds ( pLeft, pRight, pTop, pBottom )
{
    this.left = pLeft;
    this.right = pRight;
    this.top = pTop;
    this.bottom = pBottom;
    this.CoordsInBounds = CoordsInBounds;
    
    function CoordsInBounds ( pX, pY )
    {
        return ( pX < this.left || pX > this.right || pY < this.top || pY > this.bottom ) ? false : true;
    }
}

function Browsers ()
{
    this.onloads = new Array();
    this.LaunchInits = LaunchInits;
    this.Init_OnLoad = Init_OnLoad;
    this.documentWidth = documentWidth;
    this.getElementsByAttr = getElementsByAttr;
    this.getElementsByClassName = getElementsByClassName;
    this.getElementByID = getElementByID;
    this.getElementStyle = getElementStyle;
    this.setElementStyle = setElementStyle;
    this.getElementOpacity = getElementOpacity;
    this.setElementOpacity = setElementOpacity;
    
    function LaunchInits ()
    {
        for ( var xInit = 0; xInit < this.onloads.length; xInit++ )
        {
            this.onloads[xInit]();
        }
    }
    
    function Init_OnLoad ( pInitFunction )
    {
        this.onloads[this.onloads.length] = pInitFunction;
    }
    
    function documentWidth ()
    {
        return document.width ? parseInt(document.width) : parseInt(document.body.clientWidth);
    }
    
    function getElementsByAttr ( pAttr, pValue, pTag, pParent )
    {
        if ( ! pTag ) { pTag = '*'; }
        if ( ! pParent ) { pParent = document; }
        var xValue = new RegExp("(^|\\\\s)" + pValue + "(\\\\s|$)");
        if ( pParent.all && pTag == '*' )
        {
            xElements = pParent.all;
        }
        else
        {
            xElements = pParent.getElementsByTagName(pTag);
        }
        var xMatches = [];
        var xNumElements = xElements.length;
        for ( var xElement = 0; xElement < xNumElements; xElement++ )
        {
            if ( xValue.test(xElements[xElement][pAttr]))
            {
                xMatches.push(xElements[xElement]);
            }
        }
        return xMatches;
    }
    
    function getElementsByClassName ( pClassName, pTag, pParent )
    {
        if ( ! pTag ) { pTag = '*'; }
        if ( ! pParent ) { pParent = document; }
        var xClassName = new RegExp("(^|\\\\s)" + pClassName + "(\\\\s|$)");
        if ( pParent.all && pTag == '*' )
        {
            xElements = pParent.all;
        }
        else
        {
            xElements = pParent.getElementsByTagName(pTag);
        }
        var xMatches = [];
        var xNumElements = xElements.length;
        for ( var xElement = 0; xElement < xNumElements; xElement++ )
        {
            if ( xClassName.test(xElements[xElement].className))
            {
                xMatches.push(xElements[xElement]);
            }
        }
        return xMatches;
    }
    
    function getElementByID ( pID, pTag, pParent )
    {
        var xElements = getElementsByAttr('id', pID, pTag, pParent);
        if ( xElements.length > 0 ) { return xElements[0]; }
        return null;
    }
    
    function getElementStyle ( pElement, pStyleAttr )
    {
        if ( ! pElement ) { return ''; }
        if ( document.defaultView && document.defaultView.getComputedStyle )
        {
        	var xElementStyle = document.defaultView.getComputedStyle(pElement, null);
        	//	Safari will literally hang if getComputedStyle returns null.
        	if ( xElementStyle == null ) { return ''; }
        	if ( ! xElementStyle[pStyleAttr] ) { return ''; }
            return document.defaultView.getComputedStyle(pElement, null)[pStyleAttr];
        }
        else if ( pElement.currentStyle )
        {
            //  *sigh* Internet Explorer is horrible. Really wish people didn't use it.
            while ( pStyleAttr.match(/(-[a-zA-Z])/) != null )
            {
                pStyleAttr = pStyleAttr.replace(pStyleAttr[1], pStyleAttr[1].toUpperCase().substring(1));
            }
            //  Have I mentioned how horrible IE is?
            //  It doesn't return correct values for some properties; for example,
            //  if you haven't specified a hard width for your element in your stylesheet,
            //  then IE will return its width as 'auto' ... not terribly helpful.
            if ( pStyleAttr == 'width' )
            {
                return pElement.offsetWidth;
            }
            else if ( pStyleAttr == 'left' )
            {
                return pElement.offsetLeft;
            }
            else
            {
                return pElement.currentStyle[pStyleAttr];
            }
        }
        return '';
    }
    
    function setElementStyle ( pElement, pStyleAttr, pValue )
    {
        if ( pElement.currentStyle )
        {
            //  See IE-hating above.
            while ( pStyleAttr.match(/(-[a-zA-Z])/) != null )
            {
                pStyleAttr = pStyleAttr.replace(pStyleAttr[1], pStyleAttr[1].toUpperCase().substring(1));
            }
        }
        pElement.style[pStyleAttr] = pValue;
    }
    
    function getElementOpacity ( pElement )
    {
        if ( pElement.style )
        {
            if ( pElement.style.MozOpacity != null )
            {
                return pElement.style.MozOpacity;
            }
            else if ( pElement.style.opacity != null )
            {
                return pElement.style.opacity;
            }
            else if ( pElement.style.filter != null )
            {
                return (parseInt(pElement.style.filter.match(/([0-9]+)/)) / 100);
            }
        }
    }

    function setElementOpacity ( pElement, pOpacity )
    {
        if ( pElement.style )
        {
            if ( pElement.style.MozOpacity != null )
            {
                pElement.style.MozOpacity = pOpacity;
            }
            else if ( pElement.style.opacity != null )
            {
                pElement.style.opacity = pOpacity;
            }
            else if ( pElement.style.filter != null )
            {
                pOpacity = pOpacity * 100;
                pElement.style.filter = "alpha(opacity=" + pOpacity + ")";
            }
        }
    }
}

var gEventMaster = null;

function Mouse ()
{
    //  Class properties.
    this.x = 0;
    this.y = 0;
    this.callback = false;
    //  Class methods.
    this.Update = Update;
    this.Start = Start;
    this.Stop = Stop;
    
    function Update ( pEvent )
    {
        if ( ! pEvent ) { pEvent = window.event; }
        if ( pEvent.pageX || pEvent.pageY )
        {
            gEventMaster.x = pEvent.pageX;
            gEventMaster.y = pEvent.pageY;
        }
        else if ( pEvent.clientX || pEvent.clientY )
        {
            gEventMaster.x = pEvent.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
            gEventMaster.y = pEvent.clientY + document.body.scrollTop + document.documentElement.scrollTop;
        }
        if ( gEventMaster.callback ) { gEventMaster.callback; }
    }
    
    function Start ()
    {
        this.callback = document.onmousemove;
        if ( window.captureEvents ) { window.captureEvents(Event.MOUSEMOVE); }
        document.onmousemove = this.Update;
        gEventMaster = this;
    }
    
    function Stop ()
    {
        if ( this.callback )
        {
            document.onmousemove = this.callback;
        }
        else
        {
            if ( window.captureEvents ) { window.releaseEvents(Event.MOUSEMOVE); }
            document.onmousemove = null;
        }
        gEventMaster = null;
    }
}
