/*
Copyright (c) 2006, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
*/
/**
 Exported from YUI Framework
*/

var ua = navigator.userAgent.toLowerCase(),
	isOpera = (ua.indexOf('opera') > -1),
	isSafari = (ua.indexOf('safari') > -1),
	isGecko = (!isOpera && !isSafari && ua.indexOf('gecko') > -1),
	isIE = (!isOpera && ua.indexOf('msie') > -1); 

var YAHOO = YAHOO || {};
YAHOO.util = YAHOO.util || {};

YAHOO.util.Dom = YAHOO.util.Dom || {
  /**
       * Returns the current height of the viewport.
       * @return {Int} The height of the viewable area of the page (excludes scrollbars).
       */
      getViewportHeight: function() {
         var height = -1;
         var mode = document.compatMode;

         if ( (mode || isIE) && !isOpera ) {
            switch (mode) { // (IE, Gecko)
               case 'CSS1Compat': // Standards mode
                  height = document.documentElement.clientHeight;
                  break;

               default: // Quirks
                  height = document.body.clientHeight;
            }
         } else { // Safari, Opera
            height = self.innerHeight;
         }

         return height;
      },

      /**
       * Returns the current width of the viewport.
       * @return {Int} The width of the viewable area of the page (excludes scrollbars).
       */

      getViewportWidth: function() {
         var width = -1;
         var mode = document.compatMode;

         if (mode || isIE) { // (IE, Gecko, Opera)
            switch (mode) {
            case 'CSS1Compat': // Standards mode
               width = document.documentElement.clientWidth;
               break;

            default: // Quirks
               width = document.body.clientWidth;
            }
         } else { // Safari
            width = self.innerWidth;
         }
         return width;
      },
  /**
       * Returns the height of the document.
       * @return {Int} The height of the actual document (which includes the body and its margin).
       */
      getDocumentHeight: function() {
         var scrollHeight=-1,windowHeight=-1,bodyHeight=-1;
         var marginTop = parseInt((document.body.style.marginTop || 0), 10);
         var marginBottom = parseInt((document.body.style.marginBottom || 0), 10);
         
         var mode = document.compatMode;

         if ( (mode || isIE) && !isOpera ) { // (IE, Gecko)
            switch (mode) {
               case 'CSS1Compat': // Standards mode
                  scrollHeight = ((window.innerHeight && window.scrollMaxY) ?  window.innerHeight+window.scrollMaxY : -1);
                  if(scrollHeight == -1)
                  {
                  	  if (document.documentElement.scrollHeight > 0)
                  	  {
                  	  	  scrollHeight = document.documentElement.scrollHeight;
                  	  }
                  }
                  windowHeight = [document.documentElement.clientHeight,self.innerHeight||-1].sort(function(a, b){return(a-b);})[1];
                  bodyHeight = document.body.offsetHeight + marginTop + marginBottom;
                  break;

               default: // Quirks
                  scrollHeight = document.body.scrollHeight;
                  bodyHeight = document.body.clientHeight;
            }
         } else { // Safari & Opera
            scrollHeight = document.documentElement.scrollHeight;
            windowHeight = self.innerHeight;
            bodyHeight = document.documentElement.clientHeight;
         }

         var h = [scrollHeight,windowHeight,bodyHeight].sort(function(a, b){return(a-b);});
         return h[2];
      },

      /**
       * Returns the width of the document.
       * @return {Int} The width of the actual document (which includes the body and its margin).
       */
      getDocumentWidth: function() {
         var docWidth=-1,bodyWidth=-1,winWidth=-1;
         var marginRight = parseInt((document.body.style.marginRight || 0), 10);
         var marginLeft = parseInt((document.body.style.marginLeft || 0), 10);

         var mode = document.compatMode;

         if (mode || isIE) { // (IE, Gecko, Opera)
            switch (mode) {
               case 'CSS1Compat': // Standards mode
                  docWidth = document.documentElement.clientWidth;
                  bodyWidth = document.body.offsetWidth + marginLeft + marginRight;
				  var scrollWidth = document.documentElement.scrollWidth;
				  if(scrollWidth > docWidth)
				  {
				  	 docWidth = scrollWidth;
				  }
                  break;

               default: // Quirks
                  bodyWidth = document.body.clientWidth;
                  docWidth = document.body.scrollWidth;
                  break;
            }
         } else { // Safari
            docWidth = document.documentElement.clientWidth;
            bodyWidth = document.body.offsetWidth + marginLeft + marginRight;
         }

         var w = Math.max(docWidth, bodyWidth);
         return w;
      },
      

	  isAncestor: function(haystack, needle) {
		    haystack = $(haystack);
		    if (!haystack || !needle) { return false; }
		    
	        if (haystack.contains && !isSafari) { // safari "contains" is broken
	            return haystack.contains(needle);
	        }
	        else if ( haystack.compareDocumentPosition ) {
	            return !!(haystack.compareDocumentPosition(needle) & 16);
	        }
	        else { // loop up and test each parent
	            var parent = needle.parentNode;
	            
	            while (parent) {
	                if (parent == haystack) {
	                    return true;
	                }
	                else if (!parent.tagName || parent.tagName.toUpperCase() == 'HTML') {
	                    return false;
	                }
	                
	                parent = parent.parentNode;
	            }
	            return false;
	        }
	  },
	  
	  inDocument: function(el) {
           return this.isAncestor(document.documentElement, el);
	  },
	  
	  getXY : function(el){
		
		// has to be part of document to have pageXY
		    if (el.parentNode === null || el.offsetParent === null ||
		            el.style.display == 'none') {
		        return false;
		    }
		    
		    var parentNode = null;
		    var pos = [];
		    var box;
		    
		    if (false && el.getBoundingClientRect) { // IE
		        box = el.getBoundingClientRect();
		        var doc = document;
		        if ( !this.inDocument(el) && parent.document != document) {// might be in a frame, need to get its scroll
		            doc = parent.document;
		
		            if ( !this.isAncestor(doc.documentElement, el) ) {
		                return false;                      
		            }
		
		        }
		
		        var scrollTop = Math.max(doc.documentElement.scrollTop, doc.body.scrollTop);
		        var scrollLeft = Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft);
		        return [box.left + scrollLeft, box.top + scrollTop];
		    }
		    else { // safari, opera, & gecko
		        pos = [el.offsetLeft, el.offsetTop];
		        parentNode = el.offsetParent;
		        var haveFixed = false;
		        if (parentNode != el) {
		            while (parentNode) {
		                if(parentNode.style.position == 'fixed')
		                {
		                	haveFixed = true;
		                }
		                pos[0] += parentNode.offsetLeft;
		                pos[1] += parentNode.offsetTop;
		                parentNode = parentNode.offsetParent;
		            }
		        }
		        if ((isGecko || isOpera) && haveFixed)
		        {
		        	pos[1] += document.body.scrollTop;
		        	pos[0] += document.body.scrollLeft;
		        }
		        if (isSafari && el.style.position == 'absolute' ) { // safari doubles in some cases
		            pos[0] -= document.body.offsetLeft;
		            pos[1] -= document.body.offsetTop;
		        }
		    }
		    
		    if (el.parentNode) { parentNode = el.parentNode; }
		    else { parentNode = null; }
		
		    while (!isOpera && parentNode && parentNode.tagName.toUpperCase() != 'BODY' && parentNode.tagName.toUpperCase() != 'HTML') 
		    { // account for any scrolled ancestors
		        if (parentNode.style.display != 'inline') { // work around opera inline scrollLeft/Top bug
		            pos[0] -= parentNode.scrollLeft;
		            pos[1] -= parentNode.scrollTop;
		        }
		        
		        if (parentNode.parentNode) {
		            parentNode = parentNode.parentNode; 
		        } else { parentNode = null; }
		    }
		    
		    return pos;
	}
}