
// instantiate DHTML library namespace
if(typeof DHTML == 'undefined') {
	var DHTML = {};
}

// get general style named property
DHTML.getStyle = function( elem, name ) {
    // If the property exists in style[], then it's been set recently (and is current)
    if (elem.style[name]) {
        return elem.style[name];
    }
    // Otherwise, try to use IE's method
    else if (elem.currentStyle) {
        return elem.currentStyle[name];
    }
    // Or the W3C's method, if it exists
    else if (document.defaultView && document.defaultView.getComputedStyle) {
        // It uses the traditional "text-align" style of rule writing, instead of textAlign
        name = name.replace(/([A-Z])/g,"-$1");
        name = name.toLowerCase();

        // Get the style object and get the value of the property (if it exists)
        var s = document.defaultView.getComputedStyle(elem,"");
        return s && s.getPropertyValue(name);

    // Otherwise, we're using some other browser
    } else {
        return null;
	}
}

// Find the X (Horizontal, Left) position of an element
DHTML.pageX = function(elem) {
    var p = 0;

    // We need to add up all of the offsets for every parent
    while ( elem.offsetParent ) {
        // Add the offset to the current count
        p += elem.offsetLeft;

        // and continue on to the next parent
        elem = elem.offsetParent;
    }

    return p;
}

// Find the Y (Vertical, Top) position of an element
DHTML.pageY = function(elem) {
    var p = 0;

    // We need to add up all the offsets for every parent
    while ( elem.offsetParent ) {
        // Add the offset to the current count
        p += elem.offsetTop;

        // and continue on to the next parent
        elem = elem.offsetParent;
    }

    return p;
}

// Find the horizontal positioning of an element within its parent
DHTML.parentX = function(elem) {
	// If the offsetParent is the element's parent, break early
	return elem.parentNode == elem.offsetParent ?
	elem.offsetLeft :
	// Otherwise, we need to find the position relative to the entire
	// page for both elements, and find the difference
	this.pageX( elem ) - this.pageX( elem.parentNode );
}

// Find the vertical positioning of an element within its parent
DHTML.parentY = function(elem) {
	// If the offsetParent is the element's parent, break early
	return elem.parentNode == elem.offsetParent ?
	elem.offsetTop :
	// Otherwise, we need to find the position relative to the entire
	// page for both elements, and find the difference
	this.pageY( elem ) - this.pageY( elem.parentNode );
}

// Find the left position of an element
DHTML.posX = function(elem) {
    // Get the computed style and get the number out of the value
    return parseInt( this.getStyle( elem, "left" ) );
}

// Find the top position of an element
DHTML.posY = function(elem) {
    // Get the computed style and get the number out of the value
    return parseInt( this.getStyle( elem, "top" ) );
}

// A function for setting the horizontal position of an element
DHTML.setX = function(elem, pos) {
	// Set the 'left' CSS property, using pixel units
	elem.style.left = pos + "px";
}

// A function for setting the vertical position of an element
DHTML.setY = function(elem, pos) {
	// Set the 'left' CSS property, using pixel units
	elem.style.top = pos + "px";
}

// A function for adding a number of pixels to the horizontal
// position of an element 
DHTML.addX = function(elem,pos) {
    // Get the current horz. position and add the offset to it.
    this.setX(this.posX(elem) + pos );
}

// A function that can be used to add a number of pixels to the
// vertical position of an element
DHTML.addY = function(elem,pos) {
    // Get the current vertical position and add the offset to it
    this.setY(this.posY(elem) + pos );
}

// Get the actual height (using the computed CSS) of an element
DHTML.getHeight = function( elem ) {
	// Gets the computed CSS value and parses out a usable number
	return parseInt( this.getStyle( elem, 'height' ) );
}

// Get the actual width (using the computed CSS) of an element
DHTML.getWidth = function( elem ) {
	// Gets the computed CSS value and parses out a usable number
	return parseInt( this.getStyle( elem, 'width' ) );
}

// Find the full, possible, height of an element (not the actual,
// current, height)
DHTML.fullHeight = function( elem ) {
    // If the element is being displayed, then offsetHeight
    // should do the trick, barring that, getHeight() will work
    if ( this.getStyle( elem, 'display' ) != 'none' )
        return elem.offsetHeight || this.getHeight( elem );

    // Otherwise, we have to deal with an element with a display
    // of none, so we need to reset its CSS properties to get a more
    // accurate reading
    var old = resetCSS( elem, {
        display: '',
        visibility: 'hidden',
        position: 'absolute'
    });

    // Figure out what the full height of the element is, using clientHeight
    // and if that doesn’t work, use getHeight
    var h = elem.clientHeight || this.getHeight( elem );

    // Finally, restore the CSS properties back to what they were
    this.restoreCSS( elem, old );

    // and return the full height of the element
    return h;
}

// Find the full, possible, width of an element (not the actual,
// current, width)
DHTML.fullWidth = function( elem ) {
    // If the element is being displayed, then offsetWidth
    // should do the trick, barring that, getWidth() will work
    if ( this.getStyle( elem, 'display' ) != 'none' )
        return elem.offsetWidth || this.getWidth( elem );

    // Otherwise, we have to deal with an element with a display
    // of none, so we need to reset its CSS properties to get a more
    // accurate reading
    var old = resetCSS( elem, {
        display: '',
        visibility: 'hidden',
        position: 'absolute'
    });

    // Figure out what the full width of the element is, using clientWidth
    // and if that doesn’t work, use getWidth
    var w = elem.clientWidth || this.getWidth( elem );

    // Finally, restore the CSS properties back to what they were
    this.restoreCSS( elem, old );

    // and return the full width of the element
    return w;
}

// A function used for setting a set of CSS properties, which
// can then be restored back again later
DHTML.resetCSS = function( elem, prop ) {
    var old = {};

    // Go through each of the properties
    for ( var i in prop ) {
        // Remember the old property value
        old[ i ] = elem.style[ i ];

        // And set the new value
        elem.style[ i ] = prop[i];
    }

    // Retun the set of changed values, to be used by restoreCSS
    return old;
}

// A function for restoring the side effects of the resetCSS function
DHTML.restoreCSS = function( elem, prop ) {
    // Reset all the properties back to their original values
    for ( var i in prop )
        elem.style[ i ] = prop[ i ];
}

// A function for hiding (using display) an element
DHTML.hide = function( elem ) {
    // Find out what it's current display state is
    var curDisplay = this.getStyle( elem, 'display' );

    //  Remember its display state for later
    if ( curDisplay != 'none' )
        elem.$oldDisplay = curDisplay;

    // Set the display to none (hiding the element)
    elem.style.display = 'none';
}

// A function for showing (using display) an element
DHTML.show = function( elem ) {
    // Set the display property back to what it use to be, or use
    // 'block', if no previous display had been saved
    elem.style.display = elem.$oldDisplay || 'block';
}

// Set an opacity level for an element
// (where level is a number 0-100)
DHTML.setOpacity = function( elem, level ) {
    // If filters exist, then this is IE, so set the Alpha filter
    if ( elem.filters && elem.filters.alpha ) {
        elem.filters.alpha.opacity = level;
    }
    // Otherwise use the W3C opacity property
    else {
        elem.style.opacity = level / 100;
    }
}

//A Function for Slowly Revealing a Hidden Element by Increasing Its Height Over a Matter of One Second
DHTML.slideDown = function( elem ) {
	// Start the slide down at 0
	elem.style.height = '0px';
	// Show the element (but you can see it, since the height is 0)
	show( elem );
	// Find the full, potential, height of the element
	var h = this.fullHeight( elem );
	// We're going to do a 20 'frame' animation that takes
	// place over one second
	for ( var i = 0; i <= 100; i += 5 ) {
		// A closure to make sure that we have the right 'i'
		(function(){
			var pos = i;
			// Set the timeout to occur at the specified time in the future
			setTimeout(function(){
				// Set the new height of the element
				elem.style.height = (( pos / 100 ) * h ) + "px";
			}, ( pos + 1 ) * 10 );
		})();
	}
}

// A Function for Slowly Revealing a Hidden Element by Increasing Its Opacity Over a Matter of One Second
DHTML.fadeIn = function( elem ) {
    // Start the opacity at  0
    this.setOpacity( elem, 0 );

    // Show the element (but you can see it, since the opacity is 0)
    this.show( elem );

    var _this = this;
    // We're going to do a 20 'frame' animation that takes
    // place over one second
    for ( var i = 0; i <= 100; i += 5 ) {
        // A closure to make sure that we have the right 'i'
        (function(){
            var pos = i; 

            // Set the timeout to occur at the specified time in the future
            setTimeout(function(){

                // Set the new opacity of the element
                _this.setOpacity( elem, pos );

            }, ( pos + 1 ) * 10 );
        })();
    }
}

// A Function for Slowly Hiding an Element by Decreasing Its Opacity Over a Matter of One Second
DHTML.fadeOut = function( elem ) {
    // Start with the opacity at  100
    this.setOpacity( elem, 100 );

    var _this = this;
    // We're going to do a 20 'frame' animation that takes
    // place over one second
    for ( var i = 0; i <= 100; i += 5 ) {
        // A closure to make sure that we have the right 'i'
        (function(){
            var pos = i; 

            // Set the timeout to occur at the specified time in the future
            setTimeout(function(){

                // Set the new opacity of the element
                _this.setOpacity( elem, 100-pos );

            }, (pos + 1) * 10 )
        })();
    }
    // Hide the element (but you can see it, since the opacity is 0)
    setTimeout(function() { _this.hide( elem ); }, 750); 

}

// Find the horizontal position of the cursor
DHTML.getX = function( e ) {
    // Normalize the event object
    e = e || window.event;

    // Check for the non-IE position, then the IE position, and finally return 0
    return e.pageX || e.clientX + document.body.scrollLeft || 0;
}

// Find the vertical position of the cursor
DHTML.getY = function( e ) {
    // Normalize the event object
    e = e || window.event;

    // Check for the non-IE position, then the IE position, and finally return 0
    return e.pageY || e.clientY + document.body.scrollTop || 0;
}

// Get the X position of the mouse relative to the element target
// used in event object 'e'
DHTML.getElementX = function( e ) {
	// Find the appropriate element offset
	return ( e && e.layerX ) || window.event.offsetX;
}

// Get the Y position of the mouse relative to the element target
// used in event object 'e'
DHTML.getElementY = function( e ) {
	// Find the appropriate element offset
	return ( e && e.layerY ) || window.event.offsetY;
}

// Returns the height of the web page
// (could change if new content is added to the page)
DHTML.pageHeight = function () {
	return document.body.scrollHeight;
}

// Returns the width of the web page
DHTML.pageWidth = function () {
	return document.body.scrollWidth;
}

// A function for determining how far horizontally the browser is scrolled
DHTML.scrollX = function () {
    // A shortcut, in case we're using Internet Explorer 6 in Strict Mode
    var de = document.documentElement;

    // If the pageXOffset of the browser is available, use that
    return self.pageXOffset ||

        // Otherwise, try to get the scroll left off of the root node
        ( de && de.scrollLeft ) ||

        // Finally, try to get the scroll left off of the body element
        document.body.scrollLeft;
}

// A function for determining how far vertically the browser is scrolled
DHTML.scrollY = function () {
    // A shortcut, in case we're using Internet Explorer 6 in Strict Mode
    var de = document.documentElement;

    // If the pageYOffset of the browser is available, use that
    return self.pageYOffset ||

        // Otherwise, try to get the scroll top off of the root node
        ( de && de.scrollTop ) ||

        // Finally, try to get the scroll top off of the body element
        document.body.scrollTop;
}

// Find the height of the viewport
DHTML.windowHeight = function () {
    // A shortcut, in case we're using Internet Explorer 6 in Strict Mode
    var de = document.documentElement;

    // If the innerHeight of the browser is available, use that
    return self.innerHeight ||

        // Otherwise, try to get the height off of the root node
        ( de && de.clientHeight ) ||

        // Finally, try to get the height off of the body element
        document.body.clientHeight;
}

// Find the width of the viewport
DHTML.windowWidth = function () {
    // A shortcut, in case we're using Internet Explorer 6 in Strict Mode
    var de = document.documentElement;

    // If the innerWidth of the browser is available, use that
    return self.innerWidth ||

        // Otherwise, try to get the width off of the root node
        ( de && de.clientWidth ) ||

        // Finally, try to get the width off of the body element
        document.body.clientWidth;
}
