/* Constants */
var AXIS_X = 0;
var AXIS_Y = 1;

/* shortcut to getElementById */
function getNode(node) {
	return document.getElementById(node);
}


/* Destroy a node with the Death Star */
function killNode(nodeID) {
	var node = getNode(nodeID);
	var nodeParent = node.parentElement;
	if (typeof nodeParent != "undefined") {
		nodeParent.removeChild(node);
	} else {
		node.style.display = "none";
	}
}

/* Replace text in a node. */
function swapTextNode(parentObject, newText) {
    parentObject.replaceChild(document.createTextNode(newText), parentObject.firstChild);
}

/* Replace text in a node. Has more protection than the previous version and will fall back on non-DOM techniques if it can't pick out the childNodes */
function replaceInnerText(node, text) {
	//	replacement for node.innerHTML = text; which is apparently broken in Safari 1.2.4
	if (typeof node.childNodes != "undefined" && node.childNodes.length > 0) {
		var newnode = document.createTextNode(text);
		node.replaceChild(newnode, node.firstChild);
	} else {
		// fall back on the old school just in case
		node.innerHTML = text;
	}
}

/* Cross browser solution to DOM getComputedStyle() (Safari doesn't currently support this) */
function grabComputedStyle(elementObject) {

    if (document.defaultView && document.defaultView.getComputedStyle ) {
        return  document.defaultView.getComputedStyle(elementObject, null);
     } else if  (elementObject.currentStyle) {
        return elementObject.currentStyle;
    } else  {
        return null;
    }

}

function grabComputedHeight(elementObject) {

    var height = grabComputedStyle(elementObject).height;
    
    if (height != null) {
        if (height.indexOf("px") != -1)
            height = height.substring(0, height.indexOf('px'));
        if (height == "auto") {
            if (elementObject.offsetHeight)
                height = elementObject.offsetHeight;
        }
    }
    
    return height;
    
}

/* Return the target node for an event. */
function getEventTarget(evt) {
	var tgt = evt.srcElement;
	if (!tgt)
		tgt = evt.target;
	return tgt;
}
function getWindowHeight() {
    var height = 0;
	if( typeof( window.innerWidth ) == 'number' ) {
	    height = window.innerHeight;
	} else if( document.documentElement && document.documentElement.clientHeight) {
	    height = document.documentElement.clientHeight;
	} else if( document.body && document.body.clientHeight) {
	    height = document.body.clientHeight;
	}
    return height;
}

/* Clear out any text that may have been selected (called "ranges") by dragging the mouse mid-click. */

function clearRanges(event) {
	if (isMacIE) { // Mac IE is blowing up
	} else if (isSafari) { // Avoid Safari 1.3 / 2.0 bugs with window.getSelection()
		event.stopPropagation();
	} else if (document.selection) { // IE 6
		document.selection.empty();
	} else if (window.getSelection()) { // NS 6
		window.getSelection().removeAllRanges();
	} else {
		event.stopPropagation();
	}
}

/* How much the document's been scrolled vertically. Needed for correcting position calculations. */
function getDocumentScrollAmount() {
	if (!isSafari) {
		return document.body.scrollTop;
	} else {
		return 0;
	}
}

/* Computes the total vertical offset of a node, the sum of the enclosing objects' vertical offset. */
function getElementOffsetY(element) {
	var totalOffset = 0;
	if (element.offsetTop != null) {
        totalOffset += element.offsetTop;
		while (element.offsetParent) {
			totalOffset += element.offsetParent.offsetTop;
			element = element.offsetParent;
		}
	}
	return totalOffset;
}

function getElementMouseCoordinate(evt, curEmt) {
var xC = -1;  
    if (!evt) var evt = window.event;
    
    if (evt.offsetX) {
        xC = evt.offsetX;
    } else if (curEmt.offsetX != null) {
        eXC = curEmt.offsetX;
        xC = evt.layerX - eXC;
    } else if (evt.layerX) {
        eXC = getElementOffsetX(curEmt);
        xC = evt.layerX - eXC;
        curEmt.offsetX = eXC;
    }
    return xC;
}

/* Computes the total horizontal offset of a node, the sum of the enclosing objects' horizontal offset. */
function getElementOffsetX(element) {
    var totalOffset = 0;
    if (element.offsetLeft != null) {
        totalOffset += element.offsetLeft;
        while (element.offsetParent) {
            totalOffset += element.offsetParent.offsetLeft;
            element = element.offsetParent;
        }
    }
    return totalOffset;
}

/* Gets the position of the top of a node. */
function getNodeTop(nodeId) {
	var itemOver = document.getElementById(nodeId);
	var itemOverTop = itemOver.style.top ? (itemOver.offsetTop - stripUnits(itemOver.style.top)) : itemOver.offsetTop;
	return itemOverTop;
}


/* Moves an object vertically. Pass in either the node or the node's ID. If amount is positive, move it down. Negative? Move it up. */
function moveNode(mover, amount) {
	if (typeof mover == "string")
		mover = getNode(mover);
	
	if (mover.style.top) {
		mover.style.top = stripUnits(mover.style.top) + amount + "px";
	} else {
		mover.style.top = (amount) + "px";
	}
}

/* Debug utility; displays all of the properties of an object in a popup */
function displayObject(obj) {
	var msg = "";
	for (var prop in obj) {
		msg += prop;
		msg += ": ";
		msg += prop.value;
		msg += "\n";
	}
	window.alert(msg);
}

function tokenizeString(inputString, token) {
    var output = new Array();
    var counter = 0;
    if (inputString) {
        while (inputString.indexOf(token) != -1) {
            var end = inputString.indexOf(token);
            var newStart = end + token.length;
            output[counter] = inputString.substring(0,end);
            inputString = inputString.substring(newStart);
            counter++;        
        }
        output[counter] = inputString;
    }
    return output;
}

function xmlRequest() {
	if (window.XMLHttpRequest) {
		req = new XMLHttpRequest();
		req.isDOM = true;
		return req;
	} else if (window.ActiveXObject) {
		req = new ActiveXObject("Microsoft.XMLHTTP");
		return req;
	} else 
		return null;
}

function isXMLReady(xmlObject) {
	return (xmlObject.readyState == 4 && xmlObject.status == 200);
}


function getElementHeightMidpoint(element, modifier) {
    
    var height = grabComputedHeight(element);  
    if (height == null) 
        return null;
    else  {
        var safeHeight = "" + height;
        if (safeHeight.indexOf('px') != -1) {
            height = safeHeight.substring(0, height.indexOf('px'));
            
        }
    }
    return height / 2;
}


function createNFTextNode(textString) {
    /* This function is incomplete */
    var safeString = tokenizeString(textString, "%%~p;");
    var textSpan = document.createElement("SPAN");
    
    for (var ii=0; ii < safeString.length; ii++) {
        textSpan.appendChild(document.createTextNode(safeString[ii]));
        if (ii+1 < safeString.length) {
            textSpan.appendChild(document.createElement("P"));
        }
    }
    return textSpan;
}
function getMouseCoordinates(e){
    var posx = 0;
    var posy = 0;
    if (!e) var e = window.event;
    if (e.pageX || e.pageY){
        posx = e.pageX;
        posy = e.pageY;
    } else if (e.clientX || e.clientY) {
        posx = e.clientX + document.body.scrollLeft;
        posy = e.clientY + document.body.scrollTop;
    }
    return {x:posx,y:posy};
}
var ServerConnectionFactory = {
    getConnection: function(){
        return new ServerConnection();
    }
}
function ServerConnection(){
    this.method = ServerConnection.METHOD_GET;
    this.returnType = ServerConnection.RETURN_TEXT;
    this.setTransport();
}
ServerConnection.METHOD_GET = "GET";
ServerConnection.METHOD_POST = "POST";
ServerConnection.RETURN_XML = "XML";
ServerConnection.RETURN_TEXT = "TEXT";

ServerConnection.prototype = {
    transportStates: ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'],
    setTransport: function(){
        this.transport = false;
        tryTransports = [];
        tryTransports.push(function(){return new ActiveXObject('Msxml2.XMLHTTP')});
        tryTransports.push(function(){return new ActiveXObject('Microsoft.XMLHTTP')});
        tryTransports.push(function(){return new XMLHttpRequest()});
        for(var i = 0; i < tryTransports.length; i++){
            try{
                this.transport = tryTransports[i]();
                break;
            }
            catch(e){}
        }
        if(this.transport){
            this.bindStateChangeHandler();
        }
    },
    bindStateChangeHandler: function(){
        var oThis = this;
        this.transport.onreadystatechange = function(){
            oThis.handleReadyStateChange();
        }
    },
    handleReadyStateChange: function(){
        if(this.transportStates[this.transport.readyState] == 'Complete'){
            if(this.transport.status == "200"){
                this.successCallback(this.returnType == ServerConnection.RETURN_XML ? this.transport.responseXML : this.transport.responseText);
            } else {
                this.failureCallback(this.transport.status,this.url);
            }
        }
    },
    execute: function(){
        this.transport.open(this.method,this.url,true);
        this.transport.send(null);
    },
    successCallback: function(){},
    failureCallback: function(status,url){}
}
function Movie(){}
Movie.prototype = {
    id: false,
    parentID: false,
    title: false,
    synopsis: false,
    rating: false,
    year: false,
    genreID: false,
    genre: false,
    CMURate: false,
    CMPred: false,
    CMWgtR: false,
    starring: [],
    director: false,
    friendRated: false,
    recommended: false,
    
    importFrom: function(importer){
        for(field in this){
            importer[field] && (this[field] = importer[field]());
            if(this[field] == "false"){
                this[field] = false;
            }
        }
    }
}
function Person(name,id){
    this.name = name;
    this.id = id;
}
MovieXMLImporter = function(xmlDoc){
    this.xmlDoc = xmlDoc;
    this.detailsNode = null;
    this.glyphNode = null;
    this.setDetailsNode();
    this.setGlyphNode();
}
MovieXMLImporter.prototype = {
    getAttribute: function(element,attr){
        try{
            var s = element.getAttribute(attr);
            if(s.length > 0){
                return s;
            }
        } 
        catch(e){}
        return false;
    },
    setDetailsNode: function(){
        try{
            this.detailsNode = this.xmlDoc.getElementsByTagName("DETAILS")[0];
        }
        catch(e){
        }
    },
    setGlyphNode: function(){
        try{
            this.glyphNode = this.xmlDoc.getElementsByTagName("GLYPH")[0];
        }
        catch(e){
        }
    },
    id: function(){
        return this.getAttribute(this.xmlDoc.getElementsByTagName("MOVIE")[0],"ID");
    },
    parentID: function(){
        return this.getAttribute(this.xmlDoc.getElementsByTagName("MOVIE")[0],"PARENTID");
    },
    title: function(){
        return this.xmlDoc.getElementsByTagName("TITLE")[0].firstChild.nodeValue;
    },
    synopsis: function(){
        return this.xmlDoc.getElementsByTagName("SYNOPSIS")[0].firstChild.nodeValue;
    },
    rating: function(){
        return this.getAttribute(this.detailsNode,"RATED");
    },
    year: function(){
        return this.getAttribute(this.detailsNode,"RELYEAR");
    },
    genreID: function(){
        return this.getAttribute(this.detailsNode,"GENREID");
    },
    genre: function(){
        return this.getAttribute(this.detailsNode,"GENRENAME");
    },
    CMURate: function(){
        return this.getAttribute(this.detailsNode,"CMURATE");
    },
    CMPred: function(){
        return this.getAttribute(this.detailsNode,"CMPRED");
    },
    CMWgtR: function(){
        return this.getAttribute(this.detailsNode,"CMWGTR");
    },
    starring: function(){
        stars = [];
        try{
            var actors = this.xmlDoc.getElementsByTagName("STARRING")[0].getElementsByTagName("PERSON");
            for(var i = 0; i < actors.length; i++){
                var actor = actors[i];
                stars.push(new Person(this.getAttribute(actor,"NAME"),this.getAttribute(actor,"ID")));
            }
        }
        catch(e){}
        return stars;
    },
    director: function(){
        try{
            var directorNode = this.xmlDoc.getElementsByTagName("DIRECTOR")[0].getElementsByTagName("PERSON")[0];
            return new Person(this.getAttribute(directorNode,"NAME"),this.getAttribute(directorNode,"ID"));
        }
        catch(e){}
    },
    friendRated: function(){
        return this.getAttribute(this.glyphNode,"FRND");
    },
    recommended: function(){
        return this.getAttribute(this.glyphNode,"REC");
    }
}
function BobTextHandler(id){
    this.element = this.addTextNodeTo(id);
}
BobTextHandler.prototype = {
    addTextNodeTo: function(id){
        var newNode = document.createTextNode("");
        $(id).appendChild(newNode);
        return newNode;
    },
    handle: function(s){
        this.setText(s);
    },
    setText: function(s){
        this.element.nodeValue = s;
    }
}
function BobCapHandler(id){
    this.element = $(id).firstChild;
}
BobCapHandler.prototype = BobTextHandler.prototype;
function BobSynopsisHandler(id){
    this.element = $(id);
    this.dummy = document.createElement("SPAN");
}
BobSynopsisHandler.prototype.handle = function(s){
    var paras = tokenizeString(s,"%%~p;");
    while(this.dummy.hasChildNodes()){
        this.dummy.removeChild(this.dummy.firstChild);
    }
    for(var i = 0; i < paras.length; i++){
    	if(i==0){
    		var newElement = "SPAN";
    	} else {
    		var newElement = "P";
    	}
        var para = this.dummy.appendChild(document.createElement(newElement));
        para.appendChild(document.createTextNode(paras[i]));
    }
    this.element.innerHTML = this.dummy.innerHTML;
};
function BobVisibilityHandler(id){
    this.element = $(id);
}
BobVisibilityHandler.prototype = {
    handle: function(s){
        this.setVisible(s);
    },
    setVisible: function(isVisible){
        this.element.style.visibility = (isVisible) ? "visible" : "hidden";
    }
}

var BobContentHandler = {
    initialized: false,
    shownFlag: false,
    initialize: function(){
        this.PARENTAL_RATING_ROOT = IMAGE_ROOT + "/pages/parental_ratings/rating_",
        this.canvas = $("bob");
        this.boxImg = $("bobimg");
        $("bobprating").src = IMAGE_ROOT + "labels/1px.gif";
        this.detailElements.initialize($('bobstarring').parentNode);
        this.textHandlers = {
            title: new BobCapHandler("bobtitle"),
            synopsis: new BobSynopsisHandler("bobsynopsis"),
            year: new BobCapHandler("bobyear"),
            starring: new BobTextHandler("bobactors"),
            director: new BobTextHandler("bobdirector"),
            genre: new BobTextHandler("bobgenre")
        };
        this.visibilityHandlers = {
            starring: new BobVisibilityHandler("bobstarring"),
            director: new BobVisibilityHandler("bobdirecting"),
            genre: new BobVisibilityHandler("bobgenretbl"),
            rating: new BobVisibilityHandler("bobprating"),
            friendRated: new BobVisibilityHandler("bobfrnd"),
            recommended: new BobVisibilityHandler("bobrec")
        };
        //override some default behaviors
        this.textHandlers.starring.handle = function(a){
            if(a.length > 0){
                var stars = "";
                for(var i=0;i<a.length-1;i++){
                    stars += a[i].name + ", ";
                }
                stars += a[i].name;
                this.setText(stars);
            }
        };
        this.textHandlers.director.handle = function(p){
            p && this.setText(p.name);
        };
        this.textHandlers.year.handle = function(s){
            this.setText(" (" + s + ")");
        };
        this.visibilityHandlers.starring.handle = function(a){
            this.setVisible(a.length > 0);
        };
        this.visibilityHandlers.starring.setVisible = function(isVisible){
			if(isVisible){
                if(this.rowRemoved){
                    BobContentHandler.detailElements.elements[this.element.id] = this.element;
                    this.rowRemoved = false;
                }
            } else {
                if(!this.tBody){
                    this.tBody = this.element.parentNode;
                }
                if(!this.rowRemoved){
                    this.tBody.removeChild(this.element);
                    BobContentHandler.detailElements.elements[this.element.id] = null;
                    this.rowRemoved = true;
                }
            }
		};
        this.visibilityHandlers.director.setVisible = this.visibilityHandlers.starring.setVisible;
        this.visibilityHandlers.genre.setVisible = this.visibilityHandlers.starring.setVisible;
        this.visibilityHandlers.director.handle = function(person){
            this.setVisible(person && person.name.length > 0);
        };
        this.visibilityHandlers.rating.handle = function(rating){
            if(rating){
                if(rating.indexOf("TV") != -1){
                    this.element.height = 32;
                } else {
                    this.element.height = 16;
                }
                this.element.src = BobContentHandler.PARENTAL_RATING_ROOT + rating + ".gif";
            }
            this.setVisible("rating",rating);
        };
        this.initialized = true;
    },
    display: function(movie, showBoxshot){
        if(!this.initialized){
            return false;
        }
        this.movieID = movie.id;
        this.parentID = movie.parentID;
        this.handleBoxshot(showBoxshot);
        for(field in movie){
            if(this.textHandlers[field]){
                this.textHandlers[field].handle(movie[field]);
            }
            if(this.visibilityHandlers[field]){
                this.visibilityHandlers[field].handle(movie[field]);
            }
        }
        this.detailElements.display();
        if(!this.shownFlag && isSafari){
            this.hideContent(movie,showBoxshot);
        }
    },
    handleBoxshot: function(showBoxshot){
        if(!showBoxshot){
            this.boxImg.style.display = "none";
        } else {
            this.boxImg.style.display = "inline";
            this.boxImg.src = IMAGE_ROOT + "boxshots/small/" + (this.parentID ? this.parentID : this.movieID) + ".jpg";
        }
    },
    preloadBoxshot: function(movieID){
    	if(!this.preloadBoxshot){
    		this.preloadBoxshot = new Image();
    	}
    	this.preloadBoxshot.src = IMAGE_ROOT + "boxshots/small/" + movieID + ".jpg";
    },
    hideContent: function(movie,showBoxshot){
        this.handleBoxshot(false);
        for(k in this.visibilityHandlers){
            this.visibilityHandlers[k].setVisible(false);
        }
        this.detailElements.clear();
        if(!this.shownFlag && isSafari){
	        var oThis = this;
	        var cycleVisibilityFunction = function(){
	            oThis.shownFlag = true;
	            oThis.display(movie,showBoxshot);
	        };
	        window.setTimeout(cycleVisibilityFunction,2);
        }
    }   
}
BobContentHandler.detailElements = {
    initialize: function(tBody){
        this.tBody = tBody;
    },
    elements: [],
    elementIDs: new Array("bobstarring","bobdirecting","bobgenretbl"),
    clear: function(){
        for(field in this.elements){
            this.elements[field] = null;
        }
    },
    display: function(){
        for(var i = 0; i < this.elementIDs.length; i++){
            if(this.elements[this.elementIDs[i]]){
                this.tBody.appendChild(this.elements[this.elementIDs[i]]);
            }
        }
    }
}
var XMLMovieFetcher = {
    cache: {},
    //callback function needed because retrieval is potentially asynchronous
    getMovie: function(id,callbackFunction,params){
        if(this.cache[id]){
            callbackFunction(this.cache[id]); //callback immediately
        } else {
            sc = ServerConnectionFactory.getConnection();
            sc.url = XML_ROOT + "MovieData?movieid=" + id;
            if(params){
                for(key in params){
                    sc.url += "&" + key + "=" + params[key];
                }
            }
            var oThis = this;
            sc.successCallback = function(movieXML){
                oThis.handleXMLReturn(movieXML,id,callbackFunction);
            };
            sc.execute();
        }
    },
    handleXMLReturn: function(movieXML,id,callbackFunction){
        var movieImporter = new MovieXMLImporter(movieXML);
        var movie = new Movie();
        movie.importFrom(movieImporter);
        this.cache[id] = movie;
        callbackFunction(movie);
    }
}
var BobManager = {
    STYLE_POSITION: 1,
    COUNT_DELIM: "_",
    BOXSHOT_STATE_DEFAULT: 0,
    BOXSHOT_STATE_NONE: 1,
    BOXSHOT_STATE_DISPLAY: 2,
    STATE_AWAKE: 0,
    STATE_ASLEEP: 1,
    LINKCTR_TEXT: "TXT",
    LINKCTR_BOXSHOT: "BOX",
    LINKCTR_TEXT_NEAR_BOXSHOT: "BTX",
    LINKCTR_MINIQ: "MQI",
    initialize: function(){
        this.readyState = BobManager.STATE_AWAKE;
        this.bob = $("bob");
        this.arrow = $("bobarrow");
        var oThis = this;
        this.arrow.onclick = function(){
            window.location.href = oThis.href;
        };
        this.arrow.onmouseout = function(){
            oThis.hideBob();
        };
        this.arrow.onmouseover = function(){
            if(oThis.hideBobTimer){
                clearTimeout(oThis.hideBobTimer);
                oThis.hideBobTimer = null;
            }
        };
        document.onkeydown = function(evt){
        	evt = evt || window.event;
	        if(evt.keycode){
	        	if(evt.keyCode == 33 || evt.keyCode == 34){
	        		oThis.currentScroll = document.body.scrollTop;
	        	}
	        }
        };
        document.onkeyup = function(evt){
        	evt = evt || window.event;
        	if(evt.keycode){
	        	if(evt.keyCode == 33 || evt.keyCode == 34){
	        		if(document.body.scrollTop != oThis.currentScroll){
	        			oThis.hideBob();
	        		}
	        	}
	        }
        };
        BobContentHandler.initialize();
        BobPositioner.initialize();
    },
    setReadyState: function(state){
        this.readyState = state;
        if(this.readyState == BobManager.STATE_ASLEEP){
            this.hideBob();
            this.detach();
        }
    },
    bobifyLinks: function(){
    	var root = $('page-content');
    	var imgs = root.getElementsByTagName("IMG");
    	var movieIDs = [];
    	var bobTest = /dB\(/
    	alert("Hello");
    	for(var i = 0; i < imgs.length; i++){
    		var img = imgs[i];
    		if(img.onmouseover){
    			if(bobTest.test(img.onmouseover.toString())){
    				countIndex = img.id.indexOf(BobManager.COUNT_DELIM);
    				movieIDs[movieIDs.length] = img.id.substring(2,countIndex);
    			}
    		}
    	}
    	if(movieIDs.length > 0){
    		var idExp = /MovieDisplay?.*movieid=(\d+)/;
    		var readMoreExp = /Read\s?More/;
            var whyRecommended = /^Why\s?is\s?this\s?movie/i;
    		var links = root.getElementsByTagName("A");
            linkloop:
    		for(var i = 0; i < links.length; i++){
    			var link = links[i];
    			if(link.onmouseover){continue;}
                if(link.hasChildNodes()){
                    var kids = link.childNodes;
                    for(var j = 0; j < kids.length; j++){
                        if(kids[j].tagName == "IMG"){
                            continue linkloop;
                         }
                     }
                }
				if(link.firstChild && link.firstChild.nodeValue){
                    var linkText = link.firstChild.nodeValue;
                    if(readMoreExp.test(linkText)){continue;}
                    if(whyRecommended.test(linkText)){continue;}
                }
                result = link.href.match(idExp);
    			if(result != null){
    				var id=result[1];
    				for(var j = 0; j < movieIDs.length; j++){
    					if(id == movieIDs[j]){
		    				link.movieid = id;
		    				link.onmouseover = function(event){
		    					event = event || window.event;
		    					BobManager.dB(event,this,BobManager.BOXSHOT_STATE_NONE);
		    				};
		    				continue;
		    			}
		    		}
    			}
    		}
    	}
    },
    bobifyMiniqueue: function(){
        var container = $('mqbox');
        if(container){
            var items = container.getElementsByTagName("DIV");
            for(var i = 0; i < items.length; i++){
                if(items[i].className.indexOf(CLASS_MINIQ_ROW) > -1){
                    items[i].setAttribute("persist_mouseout",1);
                    items[i].onmouseover = function(event){
                        event = event || window.event;
                        var position = getPositionFromElementId(this.id);
                        if(custq.getItem(position)){
                            this.movieid = custq.getItem(position).id;
                            BobManager.dB(event,this,BobManager.BOXSHOT_STATE_DISPLAY);
                        }
                     };
                     items[i].onmouseout = function(){
                        if(this.movieid){
                            BobManager.hideBob();
                        }
                     };
                     items[i].onmousedown = function(){
                        BobManager.setReadyState(BobManager.STATE_ASLEEP);
                     };
                     items[i].onmouseup = function(){
                        BobManager.setReadyState(BobManager.STATE_AWAKE);
                     };
                }
            }
        }
    },
    getURLParams: function(){
    	if(this.triggerElement.movieid){
    		var params = {
    			pos: 0,
    			ds: "b"
    		};
            params.linkCtr = this.triggerElement.tagName == "A" ? BobManager.LINKCTR_TEXT_NEAR_BOXSHOT : BobManager.LINKCTR_MINIQ;
    	} else {
    		var params = {
    			pos: this.triggerElement.id.substring(this.triggerElement.id.indexOf(BobManager.COUNT_DELIM)+1),
            	ds: this.triggerElement.id.charAt(BobManager.STYLE_POSITION)
            };
            params.linkCtr = this.triggerElement.tagName == "A" ? BobManager.LINKCTR_TEXT : BobManager.LINKCTR_BOXSHOT;
        }
        return params;
    },
    isShowBoxshot: function(){
    	if(this.boxshotState == BobManager.BOXSHOT_STATE_DEFAULT){
    		return this.triggerElement.tagName == "A" || this.triggerElement.tagName == "DIV";
    	} else {
    		return this.boxshotState == BobManager.BOXSHOT_STATE_DISPLAY;
    	}
    },
    display: function(movieID){
        if(movieID != this.getMovieID()){
            return;
        }
        this.displayFlag = true;
        var oThis = this;
        var showBoxshot = this.isShowBoxshot();
        var params = this.getURLParams();
        if(window.isQueue){
            params.linkCtr += "QUEUE";
        }
        if(this.triggerElement.alt){
            this.triggerElement.altbackup = this.triggerElement.alt;
            this.triggerElement.alt = "";
        }
        var displayCallbackFunction = function(movie){
        	oThis.showBobTimer = null;
            if(!oThis.displayFlag){
                return;
            }
            BobContentHandler.display(movie,showBoxshot);
            BobPositioner.setPosition(oThis.triggerElement,oThis.mouseCoord);
            if(isSafari && !oThis.shownFlag){
                window.setTimeout(function(){BobPositioner.setPosition(oThis.triggerElement,oThis.mouseCoord);oThis.shownFlag = true},5);
            }
            oThis.bob.style.visibility = "visible";
        };
        if(showBoxshot){
        	BobContentHandler.preloadBoxshot(movieID);
        }
        XMLMovieFetcher.getMovie(movieID,displayCallbackFunction,params);
    },
    detach: function(){
        if(this.triggerElement){
            if(!this.triggerElement.getAttribute("persist_mouseout")){
                this.triggerElement.onmouseout = null;
            }
            this.triggerElement = null;
        }
    },
    attach: function(){
        if(!this.triggerElement.onmouseout){
            var oThis = this;
	        this.triggerElement.onmouseout = function(){
	            oThis.hideBob();
	        };
        }
    },
    dB: function(evt,trigger,forceBoxshot){
        if(!window.d_bobMS || d_bobMS == -1 || this.readyState == BobManager.STATE_ASLEEP){
            return;
        }
        if(this.hideBobTimer && this.triggerElement && this.triggerElement == trigger){
            clearTimeout(this.hideBobTimer);
            this.hideBobTimer = null;
            return;
        }
        this.mouseCoord = getMouseCoordinates(evt);
        this.detach();
        this.triggerElement = trigger;
        this.href = trigger.href || trigger.parentNode.href;
        if(arguments.length == 3){
        	this.boxshotState = forceBoxshot;
        } else {
        	this.boxshotState = BobManager.BOXSHOT_STATE_DEFAULT;
        }
        this.attach();
        var movieID = this.getMovieID();
        var oThis = this;
        var displayFunction = function(){
            oThis.display(movieID);
        };
        this.showBobTimer = setTimeout(displayFunction,d_bobMS);
    },
    getMovieID: function(){
    	if(this.triggerElement.movieid){
    		return this.triggerElement.movieid;
    	} else {
	        var id = this.triggerElement.id;
	        var countIndex = id.indexOf(BobManager.COUNT_DELIM);
	        return id.substring(2,countIndex);
	    }
    },
    hideBob: function(){
        this.displayFlag = false;
    	if(this.showBobTimer){
    		clearTimeout(this.showBobTimer);
    		this.showBobTimer = null;
    		return;
    	}
        var oThis = this;
        var hideFunction = function(){
        	oThis.hideBobTimer = null;
            oThis.bob.style.visibility = "hidden";
            if(oThis.triggerElement && oThis.triggerElement.altbackup){
            	oThis.triggerElement.alt = oThis.triggerElement.altbackup;
            }
            BobContentHandler.hideContent();
        };
        this.hideBobTimer = setTimeout(hideFunction, 3);
    }
}
var BobPositioner = {
    TOP_SHADOW_OFFSET: -10,
    BOB_BOX_WIDTH: 290,
    MOVIE_TO_ARROW_SPACER: 25,
    DISPLAY_STYLE_DEFAULT: 0,
    DISPLAY_STYLE_LARGE_BOXSHOT: 1,
    DISPLAY_STYLE_TINY_BOXSHOT: 2,
    ARROW_HEIGHT: 101,
    ARROW_HEIGHT_NO_SHADOW: 70,
    LARGE_BOXSHOT_WIDTH: 110,
    MED_BOXSHOT_WIDTH: 65,
    TINY_BOXSHOT_WIDTH: 50,
    TEXT_LINK_BUFFER_WIDTH: 50,
    POSITION_LEFT: 0,
    POSITION_RIGHT: 1,
    MAX_PAGE_LEFT_OFFSET: 490,
    
    initialize: function(){
        this.bob = $('bob');
        this.arrow = $('bobarrow');
        this.arrowImages = {
            UL: $('bobarrowulimg'),
            UR: $('bobarrowurimg'),
            LL: $('bobarrowllimg'),
            LR: $('bobarrowlrimg')
        };
    },
    setPosition: function(triggerElement,mouseCoord){
        this.bobPosition = BobPositioner.POSITION_RIGHT;
        this.triggerElement = triggerElement;
        this.mouseCoordX = mouseCoord.x;
        this.mouseCoordY = mouseCoord.y;
        this.setTop();
        this.setLeft();
        this.positionArrow();
    },
    setTop: function(){
        var height = grabComputedHeight(this.bob);
        var quarterHeight = height/4;
        var topPosition = getElementOffsetY(this.triggerElement) + BobPositioner.TOP_SHADOW_OFFSET - quarterHeight;
        this.bob.style.top = topPosition + "px";
        this.correctForYOverrun(height,topPosition);
    },
    correctForYOverrun: function(height,currentTop){
        var overrun = 0;
        var winHeight = getWindowHeight();
        var scrollAmt = document.body.scrollTop;
        var top = getElementOffsetY(this.bob) - BobPositioner.TOP_SHADOW_OFFSET - scrollAmt;
        var bottom = (top * 1) + (height * 1);
        if(bottom > winHeight){
            overrun = bottom - winHeight - 30;
        }
        if(top - overrun < 1){
            overrun = top;
        }
        this.bob.style.top = (currentTop - overrun) + "px";
    },
    getTriggerTop: function(){
        return getElementOffsetY(this.triggerElement);
    },
    setLeft: function(){
        var leftPosition = 0;
        if(this.triggerElement.tagName == "A" || this.triggerElement.tagName == "DIV"){
            leftPosition = Math.max(this.mouseCoordX,0) + BobPositioner.TEXT_LINK_BUFFER_WIDTH;
            if(leftPosition > this.maxLeftPosition()){
                leftPosition -= (BobPositioner.BOB_BOX_WIDTH + BobPositioner.MOVIE_TO_ARROW_SPACER + (1.5 * BobPositioner.TEXT_LINK_BUFFER_WIDTH));
                this.bobPosition = BobPositioner.POSITION_LEFT;
            }
        } else {
            var activeAreaWidth = 0;
            var boxshotStyle = this.getBoxshotStyle();
            if(boxshotStyle == BobPositioner.DISPLAY_STYLE_LARGE_BOXSHOT){
                activeAreaWidth = BobPositioner.LARGE_BOXSHOT_WIDTH;
            } else if(boxshotStyle == BobPositioner.DISPLAY_STYLE_TINY_BOXSHOT){
                activeAreaWidth = BobPositioner.TINY_BOXSHOT_WIDTH;
            }
            else {
                activeAreaWidth = BobPositioner.MED_BOXSHOT_WIDTH;
            }
            var elementOffsetX = getElementOffsetX(this.triggerElement);
            leftPosition = elementOffsetX + BobPositioner.MOVIE_TO_ARROW_SPACER + activeAreaWidth;
            if(leftPosition > this.maxLeftPosition()){
                leftPosition -= (BobPositioner.BOB_BOX_WIDTH + BobPositioner.MOVIE_TO_ARROW_SPACER + activeAreaWidth);
                this.bobPosition = BobPositioner.POSITION_LEFT;
            }
        }
        this.bob.style.left = leftPosition + "px";
    },
    maxLeftPosition: function(){
        return getElementOffsetX($('page-content')) + BobPositioner.MAX_PAGE_LEFT_OFFSET;
    },
    positionArrow: function(){
        var pointedUp = false;
        var arrowTop = this.getTriggerTop() - getElementOffsetY(this.bob);
        var bobHeight = grabComputedHeight(this.bob)
        if(arrowTop < (bobHeight / 2)){
            pointedUp = true;
        } else {
            arrowTop -= BobPositioner.ARROW_HEIGHT_NO_SHADOW;
        }
        if(arrowTop + BobPositioner.ARROW_HEIGHT + 10 > bobHeight){
            arrowTop -= 10;
        }
        if(arrowTop < 10){
            arrowTop = 10;
        }
        this.arrow.style.top = arrowTop + "px";
        if(this.bobPosition == BobPositioner.POSITION_LEFT){
            this.arrow.style.left = "268px";
        } else {
            this.arrow.style.left = "-42px";
        }
        var imgKey = pointedUp ? "U" : "L";
        imgKey += (this.bobPosition == BobPositioner.POSITION_LEFT) ? "R": "L";
        for(key in this.arrowImages){
            this.arrowImages[key].style.display = (key == imgKey) ? "block" : "none";
        }
    },
    getBoxshotStyle: function(){
        return this.triggerElement.id.substring(1,2);
    }
}

function primeBOB(){
    BobManager.initialize();
    callOnWindowLoad(BobManager.bobifyLinks);
    callOnWindowLoad(BobManager.bobifyMiniqueue);
}
function dB(evt,link){
    BobManager.dB(evt,link);
}
function $(element){
    if (typeof element == 'string'){
        element = document.getElementById(element);
    }
    return element;
}
