(function(){

	var Dom = YAHOO.util.Dom;
  	var Evt = YAHOO.util.Event;
  	var Yuc = YAHOO.util.Connect;
    YAHOO.namespace("map");
	
	var VIDEO_LINK_TEXT = 'Play Video';
	var MORE_LINK_TEXT = 'More';
	
	var timeoutInterval = 250, openTimeout, closeTimeout;
	

	function ce(tag){return document.createElement(tag);}
	function div(){return ce("div");}
	function a(){return ce("a");}
	function img(src){var img = ce("img"); img.src = src; return img;}
	
	function getFirstValue(obj, name, length){
		var value = (obj.getElementsByTagName(name) == null || obj.getElementsByTagName(name).length == 0) ? "" : 
			(obj.getElementsByTagName(name)[0].firstChild == null) ? "" : obj.getElementsByTagName(name)[0].firstChild.nodeValue;
		if(length){ value = value.substring(0, length) + "...";}
		return value;			
	}
	
	function convertToArray(collection){
		var array = [];
		for(var i = 0; i < collection.length; i++){
			array.push(collection[i]);
		}
		return array;
	}
	
	var shorexLnk = function(shorex, innerHTML){
		var lnk = a();
		lnk.href = getFirstValue(shorex, "link");
		lnk.innerHTML = innerHTML; 
		return lnk;
	}
	
	var imgUrl = function(shorex){
		return '<img width="86" height="62" alt="' + getFirstValue(shorex, "name") + '" title="' + 
			getFirstValue(shorex, "name") + '" src="' + getFirstValue(shorex, "featuredImageUrl") +'"/>';
	}
	
    YAHOO.map.bubble = function(panel, portObj){
		var VERTICAL_ARROW_OFFSET = 20, HORIZONTAL_ARROW_OFFSET = 30;
		var marker = {}, maxHeight = 0, maxWidth = 0, tooHigh = false;
		var popupMarkerdiv = ce("div");
		var shorexes;
		var panelHeight;
				
        function renderSingleShorex(shorex){
	        var body = div(), left = div(), right = div(), 
				imageLnk = shorexLnk(shorex, imgUrl(shorex)),
				shorexName = ce("h3"), 
				shorexBody = ce("p"),
				moreLnk = shorexLnk(shorex, MORE_LINK_TEXT);
			
			Dom.addClass(shorexName, "shorex_name");	
			var shorexNameLink = shorexLnk(shorex, getFirstValue(shorex, "name"));
			shorexName.appendChild(shorexNameLink);
			
			shorexBody.innerHTML = getFirstValue(shorex, "description", 180);			
			Dom.addClass(body, "feat_excursion");
			
			Dom.setStyle(left, "float", "left");
			Dom.setStyle(left, "width", "86px");
			Dom.setStyle(right, "margin-left", "100px");
			Dom.setStyle(right, "width", "315px");
			
			body.appendChild(left);
			body.appendChild(right);
			right.appendChild(shorexName);
			right.appendChild(shorexBody);
			right.appendChild(moreLnk);
			Dom.addClass(moreLnk, "more_link");
			Dom.addClass(moreLnk, "nav_link");

			left.appendChild(imageLnk);
				        
		   	if (getFirstValue(shorex, "movie") != "") {
		   		Dom.addClass(moreLnk, "left");
				var videoLnk = shorexLnk(shorex, VIDEO_LINK_TEXT);
				Dom.addClass(videoLnk, "video_link");
				Dom.addClass(videoLnk, "nav_link");
				Evt.addListener(videoLnk, "click", function(e){
					Evt.preventDefault(e);
					changeBodyandRender(videoLayout(shorex));
				});
                right.appendChild(videoLnk);
			}
			
			if((findCurrentIndex(shorexes, shorex) + 1) != shorexes.length ){
				var border = div();
				Dom.addClass(border, "border");
				body.appendChild(border);
			}
			return body;
		}
		
		function findCurrentIndex(array, curObj){
			for(var i = 0; i < array.length; i++){
				if(array[i] == curObj){return i;}
			}
			return null;
		}
		
		function populateWindow(port){
	    	var body = div();
			var popTitle = div();
			var list = ce("ul");
			var title = ce("h2");
			var header = ce("h1");
			Dom.addClass(title, "featured_excursion_title");
			header.innerHTML = getFirstValue(portObj,"name");
			Dom.addClass(list, "port_feature_list");
			Dom.addClass(popTitle, "pop_title");
			popTitle.appendChild(list);
			title.innerHTML = getFirstValue(port, "message");
			
			for (var x = 0, highlights = port.getElementsByTagName("highlight"); x < highlights.length; x++) {
				var li = ce('li');
				li.innerHTML = "<span>" + highlights[x].firstChild.nodeValue + "</span>";
				list.appendChild(li);
			}
			
			body.appendChild(header);
			body.appendChild(popTitle);
			body.appendChild(title);
			if(shorexes){
				for(var x = 0; x < shorexes.length; x++){
					body.appendChild(renderSingleShorex(shorexes[x]));
				}
			}
			return body;
		}
		
		function videoLayout(obj){
			
			var nextObj, prevObj;
			var objs = convertToArray(portObj.getElementsByTagName("shorex"));
			var currentIndex = findCurrentIndex(objs, obj);
			var container = div();
			var el = {body: div(), next: div(), prev: div()};
			var header = ce("h1"), lnk = ce("h2");
			var backLink = div(), detailsLink = shorexLnk(obj, "Details");
			var prevImg = ce("img"), nextImg = ce("img");
			var centerImg = div();
			
			header.innerHTML = getFirstValue(portObj,"name");
			
			Dom.addClass(container, 'shorexVideo');			
			Dom.addClass(el.prev, 'left');
			Dom.addClass(el.body, 'body');
			Dom.addClass(el.next, 'right');
			Dom.addClass(backLink, "clickable");
			Dom.addClass(backLink, "orange");
			Dom.addClass(detailsLink, "clickable");
			Dom.addClass(detailsLink, "orange");
			nextObj = objs[currentIndex + 1];
			prevObj = objs[currentIndex - 1];
			if((nextObj != undefined) && (getFirstValue(nextObj, "movie") != '')){
				nextImg.src = "../images/icons/destinationVideo/video_next_arrow.gif";
				Dom.addClass(nextImg, "clickable");
				Evt.on(nextImg, "click", function(){
						changeBodyandRender(videoLayout(nextObj));
					   });
			}else{
				nextImg.src = "../images/icons/destinationVideo/video_next_arrow_fade.gif";
			}
			
			if((prevObj != undefined) && (getFirstValue(prevObj, "movie") != '')){
				prevImg.src = "../images/icons/destinationVideo/video_back_arrow.gif" ;
				Dom.addClass(prevImg, "clickable");
				Evt.on(prevImg, "click", function(){
						changeBodyandRender(videoLayout(prevObj));
					   });
			}else{
				prevImg.src = "../images/icons/destinationVideo/video_back_arrow_fade.gif";
			}
			
			var table = function(arrObjs){
				var t = ce("table");
				var tb = ce("tbody");
				
				t.setAttribute("width", "100%");
				var tr = ce("tr");
				t.appendChild(tb);
				tb.appendChild(tr);
				
				for(var obj in arrObjs){
					var td = ce("td");
					if(obj == 0){
						td.setAttribute("align", "left");
					}else if(obj == (arrObjs.length - 1)){
						td.setAttribute("align", "right");
					}else{
						td.setAttribute("align", "center");
					}
                    
                    if(arrObjs[obj].tagName != null){
                        td.appendChild(arrObjs[obj]);
                        tr.appendChild(td);
                    }
				}
				return t;
			}
			
			Evt.on(backLink, "click", function(){showMainWindow();});
			
			el.prev.appendChild(prevImg);
			el.next.appendChild(nextImg);
			
			centerImg.innerHTML = 	'<embed width="320" height="240" flashvars="width=320&height=240&file=' + 
									getFirstValue(obj, "movie") + '&image=' + getFirstValue(obj, "movieIntroImage") + '" ' + 
									'allowfullscreen="true" quality="high" name="mediaplayer" id="mediaplayer" style="" ' + 
									'src="../images/flash/mediaplayer.swf" type="application/x-shockwave-flash"/>';
			
			el.body.appendChild( header );
			el.body.appendChild( lnk );
			el.body.appendChild( centerImg );
			lnk.appendChild( shorexLnk(obj, getFirstValue(obj, "name")) );
			backLink.innerHTML = "Back";
			el.body.appendChild( table([backLink, detailsLink]) );
			container.appendChild(table([el.prev, el.body, el.next]));
			return container;
		}
		
		function createMarker(){
			popupMarkerdiv.id = "popupMarker";
			var markerImg = ce("img");
			popupMarkerdiv.img = markerImg;
			popupMarkerdiv.appendChild(markerImg);
			popupMarkerdiv.length = 30;
			if(!Dom.get("popupMarker")){
				panel.element.appendChild(popupMarkerdiv);
				Dom.setStyle(popupMarkerdiv, "position", "absolute");
				Dom.setStyle(popupMarkerdiv, "z-index", "11000");
			}else{
				popupMarkerdiv = Dom.get("popupMarker");
			}
		}
		
		function markerImagePath(position){
			return "../images/icons/destinationVideo/popup_" + position + "_pointer.gif"; 
		}
		
		function _setMarkerToTheLeft(){
			popupMarkerdiv.img.src = markerImagePath("left");
			Dom.setY(popupMarkerdiv, marker.y - 19);
			Dom.setX(popupMarkerdiv, marker.x + 3);
		}
		
		function _setMarkerToTheTop(){
			popupMarkerdiv.img.src = markerImagePath("top");
			Dom.setY(popupMarkerdiv, marker.y);
			Dom.setX(popupMarkerdiv, marker.x);
		}
		
		function _setMarkerToTheBottom(){
			popupMarkerdiv.img.src = markerImagePath("bottom");
			Dom.setY(popupMarkerdiv, marker.y - popupMarkerdiv.length);
			Dom.setX(popupMarkerdiv, marker.x);
		}
		
		
		function removeMarker(){
			if(Dom.inDocument("popupMarker")){
				panel.element.removeChild(popupMarkerdiv);
			}
		}
		
		function relativeYPosition(){
			return marker.y - Dom.getDocumentScrollTop();
		}
		
		function panelCanFitAboveMarker(){
			return (relativeYPosition() - 
				   (panelHeight + popupMarkerdiv.length) >= 0);
		}
		
		function panelCanFitBelowMarker(){
			return (relativeYPosition() + 
				   (panelHeight + popupMarkerdiv.length) <= Dom.getViewportHeight());
		}
		
		function panelFitsInViewport(yInsertion, height){
			return (Dom.getViewportHeight() - (yInsertion + height - Dom.getDocumentScrollTop()) >= 0);
		}
		
		function _setPanelToTheRightOfTheMarker(){
			var topAligned = Dom.getDocumentScrollTop();
			var bottomAligned = (Dom.getDocumentScrollTop() + Dom.getViewportHeight() - panelHeight) - 1;
			var offsetTop = marker.y - 60;
			
			if(offsetTop > bottomAligned){
				offsetTop = bottomAligned;
			}else if(offsetTop < topAligned){
				offsetTop = topAligned;
			}
			panel.moveTo((marker.x + popupMarkerdiv.length), offsetTop);
		}
		
		function _setPanelAboveTheMarker(){
            var xPos = (marker.x - 40); // + 460) > 530) ? (marker.x - 420) : (marker.x - 40);
			panel.moveTo(xPos, (marker.y -
								  (panelHeight + popupMarkerdiv.length - 2)));
            
		}
		
		function _setPanelBelowTheMarker(){
			panel.moveTo((marker.x - 40), (marker.y + popupMarkerdiv.length - 3));
		}
		
		function resetPosition(evt){
			if(panelCanFitAboveMarker()){
				_setPanelAboveTheMarker();
				_setMarkerToTheBottom();
			}else if(panelCanFitBelowMarker()){
				_setPanelBelowTheMarker();
				_setMarkerToTheTop();
			}else{
				_setPanelToTheRightOfTheMarker();
				_setMarkerToTheLeft();
			}
		}
		
		function changeBodyandRender(newBody, evt){
			panel.setBody(newBody);
			panel.render();
            panelHeight = Dom.getRegion(panel.body).bottom - Dom.getRegion(panel.body).top;
            resetPosition(evt);
		}

		function showMainWindow(evt){
			changeBodyandRender(populateWindow(portObj), evt);
		}
		
		function init(evt){
			shorexes = portObj.getElementsByTagName("shorex");
			createMarker();
			showMainWindow(evt);
		}
		
        return {
                    show: function(evt){
						init(evt);
                        panel.show();
                        Dom.setStyle(panel.iframe, "width", "466px");
                        Dom.setStyle(panel.iframe, "height", (panelHeight + 6) + "px");
                    },
                    hide: function(){
                        panel.hide();
                        removeMarker();
                    },
                    setX: function(x){
                    	marker.x = x;
                    },
                    setY: function(y){
                    	marker.y = y;
                    }
                };
    }

	function initializeMap(){
	var p = YAHOO.map;
	var objs = Dom.getFirstChildBy(Dom.get('imageMap'), function(o){return o.tagName == "MAP"});
	var image = Dom.getFirstChildBy(Dom.get('imageMap'), function(o){return o.tagName == "IMG"});
	var curDestination = objs.areas[0].href.match(/destinationCode=([A-Z0-9%\s/]+)/)[1];

	var cfg = {width: '460px',  visible:false, draggable: false, zIndex: 10000, iframe: true};
	
	p.panel = new YAHOO.widget.Panel("onlyPanelOnPage", cfg);

  	p.panel.render(document.body);
  	
  	var videoIcon = function(root, node){
		var icon = document.createElement("img");
		icon.src = '../images/icons/destinationVideo/video_icon_blk.gif';
		function purgeValue(val){
			if(isNaN(parseInt(val))) return 0;
			return parseInt(val); 
		}
		Dom.get("imageMap").appendChild(icon);
		Dom.setStyle(icon, "position", "absolute");
		Dom.setX(icon, (node.info.left + purgeValue(node.info.iconOffsetX)) + (Dom.getX(root) - 2) );
		Dom.setY(icon, (node.info.top + purgeValue(node.info.iconOffsetY))  + (Dom.getY(root) + 2) );
		return icon;
  	};
	
	for(var i = 0; i < objs.areas.length; i++){
		var href = objs.areas[i].href;
		var portCode = href.match(/portCode=([A-Z]{3,6})/)[1];
		var hasVideo = href.match(/video=Yes/);
		var coords = objs.areas[i].getAttribute('coords').split(',');
		var offset = href.match(/&offset=([\d-]*),([\d-]*)/) ? href.match(/&offset=([\d-]*),([\d-]*)/) : [0,0,0];
		offset.shift();
		objs.areas[i].info = {portcode: portCode,
							  top: parseInt(coords[1]), left: parseInt(coords[0]),
							  midX: (parseInt(coords[0]) + parseInt(coords[2]))/2,
							  midY: (parseInt(coords[1]) + parseInt(coords[3]))/2,
							  iconOffsetX: parseInt(offset[0]),
							  iconOffsetY: parseInt(offset[1])};
		
		if(hasVideo != null){ videoIcon(image, objs.areas[i]); }
		
	}
	
	var PanelManager = function(){
		var cache = {}, lastOrigin, currentAreaMap;
		
		function setCurrentAreaMap(areaMap){
			currentAreaMap = areaMap;
			return currentAreaMap;
		}
		
		function url(areaMap){
	  		return 'portFeaturedShorex.html?dispatch=featuredShorex&destinationCode=' + 
	  				curDestination + '&destinationPortCode=' + areaMap.info.portcode;
	  	}
	  	
	  	function setLastOrigin(xy){
	  		lastOrigin = xy;
	  		return lastOrigin;
	  	}
	  	
		function responseIsInCache(areaMap){
			return (cache[areaMap.href] != null);
		}
		
		function showCachedObj(areaMap){
			var curObj = areaMap || currentAreaMap;
			var root = cache[curObj.href].responseXML.documentElement;
			
		  	var bubble = new YAHOO.map.bubble(p.panel, root);
			bubble.setX(lastOrigin[0]);
		  	bubble.setY(lastOrigin[1]);
		  	Evt.on(p.panel.element, "mousemove", function(e){
		  			clearTimeout(openTimeout);
		  			clearTimeout(closeTimeout);
		  		});

		  	/* Evt.on(p.panel.element, "mouseout", function(e){
		  			console.log("mousing out");
		  			closeTimeout = window.setTimeout(function(){p.panel.hide();}, timeoutInterval * 5)
		  			console.log("closeTimeout: " + closeTimeout);
		  		});
		  	*/
		  	return bubble.show();
		}
		
		function getFreshResponseAndShow(areaMap){
			var curObj = areaMap || currentAreaMap;
			Yuc.asyncRequest('GET', url(curObj), { 
								  	success: function(objs){
											cache[curObj.href] = objs;
											return showCachedObj(curObj);
									  	}, 
										failure: function(){ return false; } 
							}); // end of asyncRequest
		}
		
		function getMiddleCoords(root, area){
			return [area.info.midX + Dom.getX(root), area.info.midY + Dom.getY(root)];
		}
		
		function showBubble(areaMap){
			var curObj = areaMap || currentAreaMap;
			if(responseIsInCache(curObj)){
				return showCachedObj(curObj);
			}else{
				return getFreshResponseAndShow(curObj);
			}
			return false;
		}
		
		return {
			show: function(areaMap){
				clearTimeout(openTimeout);
				openTimeout = window.setTimeout(function(){
					lastOrigin = getMiddleCoords(image, areaMap);
					showBubble(areaMap);
					}, timeoutInterval);
				return true;
			},
			hide: function(areaMap){
				p.panel.hide();
				clearTimeout(openTimeout);
			}
		};
	}();
	
	Evt.on('imageMap', 'click', function(e){
						  		Evt.preventDefault(e);
						  		var target = Evt.getTarget(e)
						  		if(target.tagName == "AREA"){
									PanelManager.show(target);
						  		}else{
						  			PanelManager.hide(target);
						  			clearTimeout(openTimeout);
						  		}
						  	});
}

Evt.addListener(window, "load", initializeMap);    
    

})();
