var DetailInfo = {
    STYLE_POSITION: 1,
    COUNT_DELIM: "_",
    STATE_AWAKE: 0,
    STATE_ASLEEP: 1,
    displayFlag: false,
    autodidifyLinks: true,	//set to false to prevent did from didifying links on DOM ready
    mCache: {}, //cache for returned detail info
    initialize: function(){
        this.readyState = DetailInfo.STATE_AWAKE;
        var oThis = this;
        var mouseoverHandler = function(){
            if(oThis.hideTimer){
                clearTimeout(oThis.hideTimer);
                oThis.hideTimer = null;
            }
        };
        var keydownHandler =  function(evt){
            evt = evt || window.event;
            if(evt.keycode){
                if(evt.keyCode == 33 || evt.keyCode == 34){
                    oThis.currentScroll = document.body.scrollTop;
                }
            }
        };
        var keyupHandler = function(evt){
            evt = evt || window.event;
            if(evt.keycode){
                if(evt.keyCode == 33 || evt.keyCode == 34){
                    if(document.body.scrollTop != oThis.currentScroll){
                        oThis.hide();
                    }
                }
            }
        };
        Event.observe(document,"keydown",keydownHandler);
        Event.observe(document,"keyup",keyupHandler);
        Event.observe("did", "mouseover", this.hide.bindAsEventListener(this))
    },
    setReadyState: function(state){
        this.readyState = state;
        if(this.readyState == DetailInfo.STATE_ASLEEP){
            this.hide();
            this.detach();
        }
    },
    didify: function(container, id){
    	Event.observe(container, "mouseover", this.dB.bindAsEventListener(this, container, id));
    },
    getURLParams: function(){
    	var tagName = this.triggerElement.tagName.toLowerCase();
        if(this.triggerElement.movieid){
            var params = {
                pos: 0,
                ds: "b"
            };
            params.linkCtr = tagName == "a" ? DetailInfo.LINKCTR_TEXT_NEAR_BOXSHOT : DetailInfo.LINKCTR_MINIQ;
        } else {
            var params = {
                pos: this.triggerElement.id.substring(this.triggerElement.id.indexOf(DetailInfo.COUNT_DELIM)+1),
                ds: this.triggerElement.id.charAt(DetailInfo.STYLE_POSITION)
            };
            params.linkCtr = tagName == "a" ? DetailInfo.LINKCTR_TEXT : DetailInfo.LINKCTR_BOXSHOT;
        }
        return params;
    },
    display: function(detailID){
        this.displayFlag = true;
        if(this.mCache[detailID]){
        	DetailInfoContentHandler.display(this.mCache[detailID]);
        	DetailInfoPositioner.setPosition(this.triggerElement,this.mouseCoord);
	        $("did").style.visibility = "visible";
        } else {
	        var oThis = this;
	        var displayCallbackFunction = function(ajaxRequest){
	        	oThis.showdidTimer = null;
	            if(!DetailInfo.displayFlag){
	                return;
	            }
	            var s = ajaxRequest.responseText;
	            oThis.mCache[detailID] = s;
	            DetailInfoContentHandler.display(s);
	            DetailInfoPositioner.setPosition(oThis.triggerElement,oThis.mouseCoord);
	            $("did").style.visibility = "visible";
	        };
	        new Ajax.Request("function_get_detail.php?topic=" + detailID,{onComplete:displayCallbackFunction});
        }
    },
    detach: function(){
        if(this.triggerElement){
            if (this.triggerElement.did_eid){
                EventDispatcher.removeEvent(this.triggerElement,"mouseout",this.triggerElement.did_eid);
                this.triggerElement.did_eid = null;
            }
            this.triggerElement = null;
        }
    },
    attach: function(){
        Event.observe(this.triggerElement,"mouseout",this.hide.bindAsEventListener(this));
        Event.observe(this.triggerElement,"click", this.hide.bindAsEventListener(this));
    },
    dB: function(evt,trigger, detailID){
        if(this.hideTimer && this.triggerElement && this.triggerElement == trigger){
            clearTimeout(this.hideTimer);
            this.hideTimer = null;
            return;
        }
        this.mouseCoord = {x:Event.pointerX(evt), y:Event.pointerY(evt)};
        this.detach();
        this.triggerElement = trigger;
        this.attach();
        if(!detailID){detailID = this.getDetailID()};
        var oThis = this;
        var displayFunction = function(){
            oThis.display(detailID);
        };
        this.showdidTimer = setTimeout(displayFunction,700);
    },
    getDetailID: function(){
        var id = this.triggerElement.id;
		if(id.substring(0,1) == "q"){
			var s = id.substring(1,2);
		} else {
			var s = id.substring(0,1);
		}
		s+= id.match(/\d+/)[0];
		return s;
    },
    hide: function(){
    	if(this.readyState != DetailInfo.STATE_AWAKE){
            return;
        }
        this.displayFlag = false;
        if(this.showdidTimer){
            clearTimeout(this.showdidTimer);
            this.showdidTimer = null;
            return;
        }
        var oThis = this;
        var hideFunction = function(){
        	oThis.hideTimer = null;
            $("did").style.visibility = "hidden";
            if(oThis.triggerElement && oThis.triggerElement.altbackup){
                oThis.triggerElement.alt = oThis.triggerElement.altbackup;
            }
        };
        this.hideTimer = setTimeout(hideFunction, 3);
    },
    destroy: function(){
        this.triggerElement && (this.triggerElement = null);
    }
}
function dB(event, elem, detailId){
	DetailInfo.dB(event, elem, detailId);
}
var fspan;
var DetailInfoPositioner = {
    TOP_SHADOW_OFFSET: -10,
    BOX_WIDTH: 290,
    INFO_SPACER: 10,
    ARROW_HEIGHT: 101,
    ARROW_HEIGHT_NO_SHADOW: 70,
    TEXT_LINK_BUFFER_WIDTH: 20,
    POSITION_LEFT: 0,
    POSITION_RIGHT: 1,
    MAX_PAGE_LEFT_OFFSET: 490,
    didId: 'did',
    arrowId: 'didarrow',
    arrowImageIds: {
            UL: 'didarrowulimg',
            UR: 'didarrowurimg',
            LL: 'didarrowllimg',
            LR: 'didarrowlrimg'
    },
    setPosition: function(triggerElement,mouseCoord){
        this.didPosition = DetailInfoPositioner.POSITION_RIGHT;
        this.triggerElement = triggerElement;
        this.mouseCoordX = mouseCoord.x;
        this.mouseCoordY = mouseCoord.y;
        this.setTop();
        this.setLeft();
        //this.positionArrow();
    },
    getStyle: function(el, propName){
		if (document.defaultView && document.defaultView.getComputedStyle) {
		    return document.defaultView.getComputedStyle(el, null).getPropertyValue(propName);
		} else if (el.currentStyle) {
		    return el.currentStyle[propName];
		} else {
		    return null;
		}
    },
    setTop: function(){
    	var topPosition = this.mouseCoordY + DetailInfoPositioner.TOP_SHADOW_OFFSET - (parseInt(Element.getStyle(this.didId,"height")) / 4);
        $(this.didId).style.top = topPosition + "px";
        this.correctForYOverrun(topPosition);
    },
    correctForYOverrun: function(currentTop){
        var overrun = 0;
        var b = $(this.didId);
        var didTop = Element.getStyle(b,"top") - DetailInfoPositioner.TOP_SHADOW_OFFSET - MyPosition.scrollTop();
        var vpHeight = MyPosition.viewportH();

        var didBottom = didTop + Element.getStyle(b,"height");
        if (didBottom > vpHeight) { overrun = didBottom - vpHeight - 30; }
        if (didTop - overrun < 1) { overrun = didTop; }
        b.style.top = (currentTop - overrun) + "px";
    },
    getTriggerTop: function(){
        return this.mouseCoordY;
    },
    setLeft: function(){
        var leftPosition = 0;
        var tagName = this.triggerElement.tagName.toLowerCase();
        fspan = this.triggerElement;
        leftPosition = Math.max(this.mouseCoordX,0) + DetailInfoPositioner.TEXT_LINK_BUFFER_WIDTH;
        if(leftPosition > this.maxLeftPosition()){
        	leftPosition -= (DetailInfoPositioner.BOX_WIDTH + DetailInfoPositioner.INFO_SPACER + (1.5 * DetailInfoPositioner.TEXT_LINK_BUFFER_WIDTH));
            this.didPosition = DetailInfoPositioner.POSITION_LEFT;
        }
        $(this.didId).style.left = leftPosition + "px";
    },
    maxLeftPosition: function(){
        return DetailInfoPositioner.MAX_PAGE_LEFT_OFFSET;
    },
    positionArrow: function(){
        var pointedUp = false;
        var didEw = $$(this.didId);
        var arrowTop = this.getTriggerTop() - parseInt(Element.getStyle(this.didId, "top"));
        var didHeight = parseInt(Element.getStyle(this.didId, "height"));
        if(arrowTop < (didHeight / 2)){
            pointedUp = true;
        } else {
            arrowTop -= DetailInfoPositioner.ARROW_HEIGHT_NO_SHADOW;
        }
        if(arrowTop + DetailInfoPositioner.ARROW_HEIGHT + 10 > didHeight) {
            arrowTop -= 10;
        }
        if(arrowTop < 10){
            arrowTop = 10;
        }
        Element.setStyle(this.arrowId,{
        	top: arrowTop + "px",
        	left: (this.didPosition == DetailInfoPositioner.POSITION_LEFT) ? "268px" : "-42px"
        });
        var imgKey = pointedUp ? "U" : "L";
        imgKey += (this.didPosition == DetailInfoPositioner.POSITION_LEFT) ? "R": "L";
        for(var key in this.arrowImageIds){
        	$(this.arrowImageIds[key]).style.display = (key == imgKey) ? "block" : "none";
        }
    }
};
var DetailInfoContentHandler = {
	display: function(html){
		var s = html.split("|");
		Element.update("didtitle",s[0]);
		Element.update("didcontent",s[1]);
	}
};
var MyPosition =
{
	// self.innerWidth || document.body.clientWidth || document.body.offsetWidth)
	viewportW: function() { return this.getVPVal("clientWidth") || this.getVPVal("offsetWidth");  },
	viewportH: function() { return self.innerHeight || this.getVPVal("clientHeight") || this.getVPVal("offsetHeight"); },

	scrollLeft: function() { return self.pageXOffset || this.getVPVal("scrollLeft"); },
	scrollTop: function() { return self.pageYOffset || this.getVPVal("scrollTop"); },

	// document.documentElement.scrollHeight gives the viewport height in quirks mode, so we don't include that as a detected alternative. If we ever switch to standards mode, change this to document.documentElement.
	pageH: function() { return document.body.scrollHeight; },
	pageW: function() { return document.body.scrollWidth; },

	mouseX: function(e) { e = e || window.event; return e.pageX || e.clientX + Position.scrollLeft(); },
	mouseY: function(e) { e = e || window.event; return e.pageY || e.clientY + Position.scrollTop(); },

	getVPVal: function(prop)
	{
		var de = document.documentElement;
		var db = document.body;

		if (de && de[prop]) return de[prop];
		else if (db && db[prop]) return db[prop];
		return 0;
	}
};