(function() {

        var ToolTips = window.ToolTips = function( settings ) {
                return new ToolTips.prototype.init( settings );
        }

        var _aEls = new Array();
        var _bActive = _bUseShadow = false;
        var _nMouseX = _nMouseY = _nOffsetX = _nOffsetY = _nScrollX = _nScrollY = _nViewH = _nViewW = 0;
        var _sHtml = '';
        var _oEl = _oTip = _oShadow = Object;

        function getCursorXY(e) {
                if(!e) var e = window.event;
                if(e.pageX || e.pageY) {
                        _nMouseX = e.pageX;
                        _nMouseY = e.pageY;
                } else if(e.clientX || e.clientY) {
                        _nMouseX = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
                        _nMouseY = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
                }
        };

        function getScrollXY() {
                if(typeof(window.pageYOffset) == 'number') {
                        _nScrollX = window.pageXOffset;
                        _nScrollY = window.pageYOffset;
                } else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop )) {
                        _nScrollX = document.documentElement.scrollLeft;
                        _nScrollY = document.documentElement.scrollTop;
                } else if(document.body && ( document.body.scrollLeft || document.body.scrollTop )) {
                        _nScrollX = document.body.scrollLeft;
                        _nScrollY = document.body.scrollTop;
                }
        };

        function getViewWH() {
                if(typeof(window.innerWidth) == 'number') {
                        _nViewH = window.innerHeight;
                        _nViewW = window.innerWidth;
                } else if(document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight )) {
                        _nViewH = document.documentElement.clientHeight;
                        _nViewW = document.documentElement.clientWidth;
                } else if(document.body && ( document.body.clientWidth || document.body.clientHeight )) {
                        _nViewH = document.body.clientHeight;
                        _nViewW = document.body.clientWidth;
                }
        };

        function setTipXY(e) {
                getCursorXY(e);
                getViewWH();
                getScrollXY();

                if((_nMouseX + _nOffsetX + _oTip.offsetWidth) > (_nViewW + _nScrollX)) {
                        _oTip.style.left = (_nMouseX - _nOffsetX - _oTip.offsetWidth) + "px";
                } else {
                        _oTip.style.left = (_nMouseX + _nOffsetX) + "px";
                }

                if((_nMouseY + _nOffsetY + _oTip.offsetHeight) > (_nViewH + _nScrollY)) {
                        _oTip.style.top = (_nMouseY - _nOffsetY - _oTip.offsetHeight) + "px";
                } else {
                        _oTip.style.top = (_nMouseY + _nOffsetY) + "px";
                }
        };

        function setTipHTML(obj) {
                var aMatches = _sHtml.match(/(?:{)(\w)+(?:})/g);
                var sHtmlOut = _sHtml;
                var nMatchesLen = aMatches.length;
                for(var i=0; i<nMatchesLen; i++) {
                        var sText = aMatches[i];
                        var sAtt = obj.getAttribute('tip'+sText.replace(/^.|.$/g,''));
                        sHtmlOut = sHtmlOut.replace(sText,sAtt);
                }

		_oTip.innerHTML = sHtmlOut;

		if(_bUseShadow) {
			_oShadow = (_oShadow.nodeType == 1) ? _oShadow : document.createElement('div');
			_oShadow.style.backgroundColor = '#000';
			_oShadow.style.filter = 'alpha(opacity=25)';
			_oShadow.style.height = _oTip.offsetHeight + 'px';
			_oShadow.style.left = '5px';
			_oShadow.style.position = 'absolute';
			_oShadow.style.opacity = .25;
			_oShadow.style.top = '5px';
			_oShadow.style.width = _oTip.offsetWidth + 'px';
			_oShadow.style.zIndex = _oTip.style.zIndex - 1 ;
			_oTip.appendChild(_oShadow);
		}

        };

        function onHover(e, obj, fn) {
                var p = (e.relatedTarget) ? e.relatedTarget : ((e.type == 'mouseover') ? e.fromElement : e.toElement);
                while( p && p != obj ) try { p = p.parentNode; } catch(err) { p = obj; };
                if(p == obj) return false;
                fn();
        };

        function showTip(e) {
                _oEl = this;
                onHover(e, this, function() {
                        setTipHTML(_oEl);
                        setTipXY(e);
                        _bActive = true;
                        _oTip.style.visibility = 'visible';
                });
        };

        function hideTip(e) {
                onHover(e, this, function() {
                        _bActive = false;
                        _oTip.style.visibility = 'hidden';
                        _oTip.innerHTML = '';
                });
        };

        ToolTips.prototype = {
                init: function( settings ) {
                        if (!document.getElementById || !document.createElement || !document.getElementsByTagName) { return; }

                        if ( !!settings.byClass ) { _aEls = byClass( settings.byClass ); }
                        else if ( !!settings.byIds ) { _aEls = byIds( settings.byIds ); }
                        else if ( !!settings.byTag ) { _aEls = byTag( settings.byTag ); }
                        else { _aEls = settings.byCustom; }

			_bUseShadow = settings.useShadow || false;
                        _nOffsetX = settings.xOffset || 25;
                        _nOffsetY = settings.yOffset || 25;

                        _sHtml = settings.html;

                        _oTip  = document.createElement('div');
                        _oTip.id = settings.tipId || 'toolTip';

                        document.getElementsByTagName('body')[0].appendChild(_oTip);

                        _oTip.style.left = '0px';
                        _oTip.style.top = '0px';
                        _oTip.style.visibility = 'hidden';

                        var oTipLen = _aEls.length;
                        for(var i=0; i<oTipLen; i++) {
                                var aData = _aEls[i].title.split("|");
                                _aEls[i].removeAttribute('title');
                                for(x in aData) {
                                        var aField = aData[x].split("=");
                                        _aEls[i].setAttribute('tip'+aField[0], aField[1]);
                                }
                                Events.add(_aEls[i], 'mouseover', showTip);
                                Events.add(_aEls[i], 'mouseout', hideTip);
                        }
                        Events.add(document, 'mousemove', setTipXY);
                }
        }

})();

