if(typeof jQuery.fn.hieroFormat == "undefined") (function(){

    function Hint() {
        var self = this;

        this.htElem = document.createElement("DIV");
        this.elem = $(this.htElem).addClass("hintWindow").hide();
        $(document.body).append(this.elem);

        var timer = null;

        var TRANS_TIME = 200;
        var SHOW_TIME = 1000;

        this.elem.hover(
            function() { self.resetTimer(); },
            function() { self.startHide(); }
        );

        $("body").blur(function() { self.fastHide(); });

        this.visible = false;
        this.currentLink = null;

        this.reposition = function() {
            var off = { x: 6, y: 6};
            var mp = $.mousePosition;
            var win = $.winSizes();

            if(!this.visible) this.elem.css("opacity", 0).show();
            var hintWidth   = this.elem.get(0).offsetWidth;
            var hintHeight  = this.elem.get(0).offsetHeight;
            if(!this.visible) this.elem.hide();

            if(mp.x + off.x + hintWidth <= win.width + win.scrollLeft - 20) {
                this.elem.css("left", (mp.x + off.x) + "px");
            } else {
                this.elem.css("left", (mp.x - off.x - hintWidth) + "px");
            }

            if(mp.y + off.y + hintHeight <= win.height + win.scrollTop) {
                this.elem.css("top", (mp.y + off.y)+ "px");
            } else {
                this.elem.css("top", (mp.y - off.y - hintHeight) + "px");
            }
        };

        this.resetTimer = function() {
            window.clearTimeout(timer);
        };

        this.startHide = function() {
            this.resetTimer();
            timer = window.setTimeout(function() { self.hide(); }, TRANS_TIME); 
        };

        this.hide = function() {
            var self = this;
            if(self.visible)
                this.elem.css("opacity", 1).animate({opacity: 0}, "fast", function() {
                    self.elem.hide();
                    self.visible = false;
                    self.currentLink = null;
                    //console.debug("hide");
                });
        };
        this.show = function() {
            var self = this;
            this.reposition();
            this.elem.css("opacity", 0).show().animate({opacity: 1}, "fast", function() {
                self.visible = true;
            });
        };

        this.fastHide = function() {
            this.resetTimer();
            this.elem.hide();
            this.visible = false;
            this.currentLink = null;
            //console.debug("fastHide");
        };


        var dataCache = {};
        this.showAndLoad = function(link, serviceUrl) {
            if(this.visible) this.fastHide(); // сброс
            var href = link.href;
            var rel  = link.rel;

            if(typeof dataCache[href] != "undefined") {
                this.elem.html(dataCache[href]);
            } else {
                this.elem.html("<i>загрузка…</i>")
                    .load(serviceUrl, {href: href, rel: rel}, function(data) {
                        dataCache[href] = data; 
                        self.reposition();
                    });
            }
            self.currentLink = link; 
            timer = window.setTimeout(function() { if(self.currentLink) self.show(); }, SHOW_TIME);
        }

    }

    var HintObj = null;

    jQuery.fn.hieroLinkHint = function(serviceUrl) {
        return $(this).each(function() {
            var self = this;
            $(this).hover(
                function() {
                    if(!HintObj) HintObj = new Hint();
                    if(HintObj.visible && HintObj.currentLink == self) { HintObj.resetTimer(); return; }
                    HintObj.showAndLoad(self, serviceUrl);
                    return false;
                },
                function() { if(HintObj) HintObj.startHide(); }
            );
        });
    };


    jQuery.fn.hieroFormat = function(context) {
        return $(context).each(function() {
            $("a[@rel ^= 'hiero:']", this).hieroLinkHint("/hiero-format-service");
        });
    };


    $(function() {
        if(jQuery.browser.msie) window.setTimeout(function() { $(document.body).hieroFormat(); }, 2000);
        else $(document.body).hieroFormat();

        $(document.body).mouseover(function(e) {  return;
            var p = e.fromElement || e.relatedTarget;
//            console.debug("p", p, HintObj, HintObj ? HintObj.currentLink : null); 
            if(!HintObj || !HintObj.currentLink) return;
            //console.debug("hde 1", p.tagName);
			// Traverse up the tree
			while ( p && p != HintObj.currentLink && p != HintObj.htElem) try { p = p.parentNode } catch(e) { p = HintObj.currentLink; };
            //console.debug("hde 2", p ? p.tagName : null);
            if(p != HintObj.currentLink && p != HintObj.htElem) { 
  //              console.debug("cl", HintObj.currentLink);
    //            console.debug("p", p);
      //          console.debug("hde");
                HintObj.fastHide();
            }
        });
    });

})();

