// ===========================================================================
// take a DOM object and determine its absolute top/left/width/height
// geometry relative to the browser window (body).
function get_abs_geometry(_dObj){
    var jCoords = -1; // assume failure
    var nDeltaX, nDeltaY;
    var t;

    // make sure we're not dealing with null, undefined, or empty string
    if(_dObj != null && _dObj != void(0) && _dObj != ''){
        // if the object has a tagname, then we're most likely working with a DOM object
        if(_dObj.tagName){
            jCoords = new Object();
            jCoords.x = jCoords.y = jCoords.w = jCoords.h = 0;

            // get the DOM object's width and height
            jCoords.w += (_dObj.offsetWidth) ? _dObj.offsetWidth : 0;
            jCoords.h += (_dObj.offsetHeight) ? _dObj.offsetHeight : 0;

            // always count the x,y geometry of the object passed in
            nDeltaX = nDeltaY = 0;
            nDeltaX = (_dObj.offsetLeft) ? _dObj.offsetLeft : 0;
            nDeltaY = (_dObj.offsetTop) ? _dObj.offsetTop: 0;

            // update our coordinates
            jCoords.x += nDeltaX;
            jCoords.y += nDeltaY;

            // look at this DOM object's parent for the next calculation
            _dObj = (_dObj.offsetParent) ? _dObj.offsetParent : _dObj.parentNode;

            // calculate it's position relative to top left corner of browser body
            while(1){
                // if our current object is the body or has no parent, we are done calculating
                if(!_dObj.parentNode || _dObj.tagName.toUpperCase() == 'BODY'){ break; }

                nDeltaX = nDeltaY = 0;
                // ignore poisonous tag geometry.
                // TR's geometry is already taken into account by the TD geometry
                // B, I, U, FONT, CENTER tags geometry should be ignored

                t = _dObj.tagName.toUpperCase();
                if(t!='TR' && t!='TBODY' && t!='B' && t!='I' && t!='U' && t!='FONT' && t!='CENTER' && t!='A'){
                    // continue summing/calculating our rendered position
                    nDeltaX = (_dObj.offsetLeft) ? _dObj.offsetLeft : 0;
                    nDeltaY = (_dObj.offsetTop) ? _dObj.offsetTop: 0;
                }

                jCoords.x += nDeltaX;
                jCoords.y += nDeltaY;

                // look at this DOM object's parent for the next calculation
            	_dObj = (_dObj.offsetParent) ? _dObj.offsetParent : _dObj.parentNode;
            }
        }
    }
    // return our coordinate object (-1 on failure)
    return jCoords;
}
// ===========================================================================
// This function implements the recursive quick sort algorithm. The function
// operates on an array. The low and high indexes specify which portion of the
// array you wish to sort. The compare function is used to determine the sorting
// behavior and must return either a -1,0,1 indicating the result of comparing
// to pieces of data in the array. -1 for less than, 0 for equals, 1 for greater
// than
function qsort_array(_aInputArray, _nLowIdx, _nHighIdx, _fCompareFunction){
    var i, j, dTempVal;

    while(_nHighIdx > _nLowIdx){
        i = _nLowIdx;
        j = _nHighIdx;
        dTempVal = _aInputArray[_nLowIdx];
        while(i < j){
            while(_fCompareFunction(_aInputArray[j], dTempVal) > 0){ j -= 1; }
            _aInputArray[i] = _aInputArray[j];
            while((i < j) && (_fCompareFunction(_aInputArray[i], dTempVal) <= 0)){ i++; }
            _aInputArray[j] = _aInputArray[i];
        }
        _aInputArray[i] = dTempVal;
        if(i - _nLowIdx < _nHighIdx - i){
            qsort_array(_aInputArray, _nLowIdx, i-1, _fCompareFunction);
            _nLowIdx = i + 1;
        }
        else{
            qsort_array(_aInputArray, i+1, _nHighIdx, _fCompareFunction);
            _nHighIdx = i - 1;
        }
    }

    return _aInputArray;
}
//============================================================================================
//|||||||||||||||||||||||||||||||||| STANDARDIZE ARRAYS ||||||||||||||||||||||||||||||||||||||
//============================================================================================
if(!Array.prototype.pop){
	Array.prototype.pop = function(){
		var last_val = this[this.length-1];
		this.length = Math.max(this.length-1,0);
		return last_val;
	}
}
//--------------------------------------------------------------------------------------------
if(Array.prototype.push && ([0].push(true)==true)){ Array.prototype.push = null; }
if(!Array.prototype.push){
	Array.prototype.push = function(){
		for(var i = 0; i < arguments.length; i++){
			this[this.length] = arguments[i];
		}
		return this.length;
	}
}
//============================================================================================
