/*
	File : google_map.js
	Author : Bear
	Created : Oct, 2007 - Updated to use .NET 2.0;
	Purpose : Generic clientside JS functions used by the ASP.NET VH MapControl.
*/

// -- "Zolv Marker Manager" - add, render and clear markers

var ZolvMarkerManager = 
{
	markers : new Array(),
	
	init : function() { },
	
	addMarker : function ( marker ){
		this.markers[this.markers.length]=marker;
	},
	
	renderMarkers : function() {
		var len = this.markers.length;
		for (var i=0;i<len;i++) {
			var marker = this.markers[i]
			GMAP_OBJ.addOverlay(this.markers[i]);
		}
		
	},
	
	clearMarkers : function() {
		var len = this.markers.length;
		for (var i=0;i<len;i++) {
			GMAP_OBJ.removeOverlay(this.markers[i]);
		}
		this.markers=null;
		this.markers=new Array(); 
		
	}	
} 

// -- "PopUp" for opening Key and Custom FAQ

var PopUp = 
{
	keyUrl : "/info/about/destination_map/map_key_popup.aspx",
	faqUrl : "/info/about/destination_map/map_faq_popup.aspx",
	
	init : function ( p_GMapID ) {
		var el = document.getElementById("lgTxt_"+p_GMapID);
		el.innerHTML = '<a href="javascript:PopUp.openWin(\'key\');">Key</a>';
	},
	
	openWin : function (whichUrl) { 
		if ( this.winObj == null || this.winObj.closed ) {
			url = (whichUrl=='key')?this.keyUrl:this.faqUrl;
			this.winObj = window.open (url,"mapPopUp","location=0,status=0,scrollbars=1,width=440,height=400");
		} else {
			this.winObj.focus();
		}
	}
}

// -- "Map Object" 
function getZOrder (marker, b) { 
	if ( marker.isActive ) {
		return -GOverlay.getZIndex(marker.getPoint().lat())
	}
	return GOverlay.getZIndex(marker.getPoint().lat());
}

var MO = 
{

	node : null, /* <mapobject /> node */
	t : "", moid : 0 , pid : 0 , regid : 0 , resid : 0, /* ids */
	lat : 0, lng : 0, /* co-ords */
	defz : 0, minz : 0, maxz : 0, /* zoom */
	pid : 0, rid : 0, /* id's (prog & resort) */
	name : "" , desc : "" , iconImgSrc : "" , showImg : true , destUrl : "" , iconUrl : "", /* meta data */   
	html : "", marker : null, isActive : "",
	
	
	create : function ( node ) {
		this.parseNode ( node );
		this.createHtml();
		this.createMarker();
	},
	
	
	parseNode : function ( node ) {
		// ids
		this.t = node.getAttribute("t");
		this.pid = node.getAttribute("pid") ;
		this.moid = node.getAttribute("moid") ;
		this.regid = node.getAttribute("regid") ;
		this.resid = node.getAttribute("resid") ;
		// co-ords
		this.lat = parseFloat( node.getAttribute("lat") );
		this.lng = parseFloat( node.getAttribute("lng") );
		// zoom
		this.defz = parseInt( node.getAttribute("defz") );
		this.minz = parseInt( node.getAttribute("minz") );
		this.maxz = parseInt( node.getAttribute("maxz") );
		// meta
		this.name = node.childNodes[0].firstChild.data;
		this.desc = node.childNodes[1].firstChild.data;
		this.imgSrc = node.childNodes[2].firstChild.data;
		this.showImg = node.childNodes[2].getAttribute("show");
		this.destUrl = node.childNodes[3].firstChild.data;
		this.iconImgSrc = node.childNodes[4].firstChild.data;
	},
	
	createHtml : function () { 
	
		this.html = "";
		// --- div
		this.html += '<div class="htmlInfo">';
		// link if not UDO
		this.html += ( this.t != "UDO") ? '<a href="' + this.destUrl + '" />' : '';
		// --- title
		this.html += '<p class="title">' + this.name + '</p>' ;
		// link if not UDO
		this.html += (this.t != "UDO") ? '</a>' : '';
		// link if has show image        
		if ( this.showImg == "True" ) {
			// link if not UDO
			this.html += (this.t!="UDO") ? '<a href="' + this.destUrl + '" />' : '';
			// --- image
			this.html += '<img border="0" src="' + this.imgSrc + '" />';
			// link if not UDO
			this.html += (this.t!="UDO") ? '</a>' : '';
		}
		// --- info
		this.html += '<div class="infoDesc">' + this.desc + '</div>';
		// --- learn more (if not UDO)
		this.html += (this.t != "UDO") ? '<a href="' + this.destUrl + '>Learn more...</a>' : '';
		// end div
		this.html += '</div>';

	},
	
	createMarker : function () { 

		// marker
		this.marker = new GMarker( new GLatLng ( this.lat , this.lng ) , {zIndexProcess:getZOrder,icon:this.getIcon(),draggable:false,bouncy:false,dragCrossMove:false} );
		this.marker.isActive = this.isActive;
		// event 
		// #TODO - refactor object chain!
		this.marker.html = this.html;
		var m = this.marker;
		evtShowInfo = GEvent.addListener(m, "click", function() {
		    if ( m.isActive && G_MAP_ISMINIMAP ) { 
				document.location = "maps.aspx";
			} else {
				m.openInfoWindowHtml(m.html);
			}
		});	
		// props
		m.disableDragging();

	},
	
	getIcon : function () { 
	
		// base icon
		var bi = new GIcon();
		bi.iconSize = new GSize(24, 33);
		bi.iconAnchor = new GPoint(12, 33);
		bi.infoWindowAnchor = new GPoint(12, 12);
		
		// icon 
		var i = new GIcon( bi );
		var s = this.iconImgSrc.indexOf(".png");
		var p1 = this.iconImgSrc.substr(0, s);
		var p2 = this.iconImgSrc.substr(s, this.iconImgSrc.length);
		this.isActive = true;
		
		// rules - based on inital object type
		switch(Ids.Name) 
		{
			case "Region":
		        if ( this.regid != Ids.RegionId ) { 
					this.isActive = false 
				}; 
				break;
			case "Resort":
				if ( this.regid != Ids.RegionId || this.resid != Ids.ResortId ) { 
					this.isActive = false 
				}; 
				break;
			case "Hotel":
				if ( this.regid != Ids.RegionId || this.resid != Ids.ResortId || this.moid != Ids.MapObjectId ) { 
					this.isActive = false 
				}; 
				break;
		}
		
		// change icons
		if ( this.isActive ) {
			i.image = this.iconImgSrc;
		} else {
			i.image = p1 + "_grey" + p2;
		}
		
		// force udos
		if ( this.t == "UDO" ) { i.image = this.iconImgSrc; }
		
		return i;
		
	}
	
}

// -- "Expand" - link to open map in new window

var Expand = 
{

	winObj : null,
	baseUrl : "/info/about/destination_map/map_expand_popup.aspx?type=",	

	openWin : function (id) {
	    var ele = id.replace("$","_").replace("$","_") + '_ctrlQS'
		var ctrlQS = document.getElementById(ele).value;
		var url = this.baseUrl + ctrlQS;
		if ( this.winObj == null || this.winObj.closed ) {
			this.winObj = window.open (url,"expandedMap","location=0,status=0,scrollbars=1,width=700,height=490");
		} else {
			this.winObj.focus();
		}
	}	
}


var Directions = 
{
	
	// marker arrays (for directions)
	markerHtmls : [], markers : [], count : 0,
	GMapObj : null, mo : null , div : "",
	url : "http://maps.google.com/maps?",
	
	init : function ( GMapObj , MO ){
		this.GMapObj = GMapObj;
		this.markerHtmls = [];
		this.markers = [];
		this.count = 0;
		this.div = document.getElementById( this.GMapObj.GMapDivID + "_Directions" );
		this.renderTitle( MO );
	},

	renderTitle : function ( MO ) {
		var initLink = "<a href=\"javascript:Directions.show('"+this.count+"');\">"+MO.name+"</a>";
		this.div.innerHTML = '<div class="dirItem"><p><b>Directions ('+initLink+')</b></p></div>';
		this.update( MO );
	},
	
	update : function ( MO ) {
		this.markerHtmls[this.count] = MO.html;
		this.markers[this.count] = MO.marker;
		this.count++;
	},
	
	show : function ( index ) {
		this.markers[index].openInfoWindowHtml( this.markerHtmls[index] );
	},
	
	add : function ( MO ) {
		
		// locations
		var dll = this.GMapObj.DefaultMarker.getPoint()
		var parentAddr = dll.lat()+","+dll.lng()+"+("+this.GMapObj.DefaultMarkerName+")";
		var childAddr = MO.lat +","+MO.lng+"+("+MO.name+")";

		// item urls
		var toUrl = this.url + "saddr=" + parentAddr + "&daddr=" + childAddr;
		var fromUrl = this.url + "saddr=" + childAddr + "&daddr=" + parentAddr;
		
		// <a> links 
		var to = '<a href="'+ toUrl +'" target="_blank">To Airport</a>';
		var from = '<a href="'+ fromUrl +'" target="_blank">From Airport</a>';
		
		// <a> show me 
		var dirLink = "(<a href=\"javascript:Directions.show('"+this.count+"');\">Show on map</a>)";
		
		// altogether now...
		this.div.innerHTML += "<div class=\"dirItem\">" 
		+ "<div class=\"dirName clearfix\">"
		+ 	"<p>" + MO.name + "<br />" + dirLink + "</p>"
		+ "</div>"
		+ "<div class=\"dirToFrom\">"
		+ 	"<p>" + to + "&nbsp;&nbsp;&nbsp;" + from + "</p>"
		+ "</div>"
		+ "</div>";
				
		// update arrays
 		this.update ( MO )
		
	}

}

var Ids = {	MapObjectId : 0 , ProgramId : 0, RegionId : 0, ResortId : 0 }

// Globals;
var G_MAP_DEBUG = 1;
var G_MAP_ISMINIMAP = false;

// map bounds
var OuterViewPaneBounds=-1; 

//--- Listeners 
if ( GEvent ) { 
	GEvent.addDomListener(window, "unload", GUnload);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////

//--- Initialize Map
function InitMap( p_GMapID , p_GMapDivID, p_IsMiniMap ) {
	
	// ids
	GMAP_OBJ.GMapID = p_GMapID;
	GMAP_OBJ.GMapDivID = p_GMapDivID;
			
	// listeners
	AddListenersToMap ( GMAP_OBJ );
	
	// map key
	PopUp.init (  GMAP_OBJ.GMapID );
	
	// force google links in map to open in new window
	var m = document.getElementById ( GMAP_OBJ.GMapDivID )
	var as = m.getElementsByTagName("A");
	var asLen = as.length;
	for (var i = 0; i < asLen; i++) {
		as[i].target = "_blank";
	}
	
	ZolvMarkerManager.init();
	
	G_MAP_ISMINIMAP = p_IsMiniMap;
		
	// now the maps ready
	SendData("GMap_Ready");

}

//--- ConvertToXML
function ConvertToXML( text )
{    
    if (window.ActiveXObject)
    {
        try {
                var doc=new ActiveXObject("Microsoft.XMLDOM");
                doc.async="false";
                doc.loadXML(text);
        } catch (e) { 
            alert(e);
        }

    }
    // code for Mozilla, Firefox, Opera, etc.
    else
    {
        var parser=new DOMParser();
        var doc=parser.parseFromString(text,"text/xml");
    }
    return doc;
}


//--- OnHandleError;
function OnHandleError( str ) { 
    alert ( "Sorry, there has been an error.\nWe are working to fix the problem." );
}

//--- OnHandleResult
function OnHandleResult( str ) {
    
    $("#mapLoading").fadeOut("slow"); 
    // clear the map
    ZolvMarkerManager.clearMarkers();
    
    // convert to xml
    var xmlObj = ConvertToXML ( str ) 
    
    // guard
    if ( xmlObj == null ) { OnHandleError () };
    
    // get the instruction
    var instruction = xmlObj.documentElement.firstChild.firstChild.data;
    
    // process the instruction
	switch ( instruction ) {
		case "GMap_MapObject":
    		OnLoadMapObject( xmlObj );		
			break;
		case "GMap_MoreMapObjects":
			OnLoadMoreMapObjects( xmlObj );
			break;  
		case "GMap_Error":
			OnHandleError();
			break;
		case "GMap_Test_CallBack":
		    alert( instruction );
		    break;
		case "GMap_NoData":
			// nothing
			break;	
		default:
			// nothing
			break;
	}
	
}


//--- Add the Listeners;
var block = false;
function AddListenersToMap () {

	GEvent.addListener(GMAP_OBJ, "zoomend", function(oldzoom, newZoom) { 
		block = true;
		GetNewMarkers(GMAP_OBJ) 	 
	});
	
	GEvent.addListener(GMAP_OBJ, "moveend", function() { 
		if (block) {
			block = false;
		} else {
			if(OuterViewPaneBounds==-1 || ! OuterViewPaneBounds.containsBounds(GMAP_OBJ.getBounds())) { 
			    GetNewMarkers(GMAP_OBJ); 
			}
		}        
	});  
}

// -- Map Calculations

function GetNewMarkers()
{
	OuterViewPaneBounds = GetOuterViewPaneBounds(GMAP_OBJ);
	var z =GMAP_OBJ.getZoom();  
	var params = "|" +   OuterViewPaneBounds.toString() + "|" + z + "|" + Ids.ProgramId;
	if (OuterViewPaneBounds.isFullLat()) { //if window is zoomed out beyond 1 world width
		params = "|((-90,-180),(90,180))|" + z + "|" + Ids.ProgramId;
	}
	$("#mapLoading").fadeIn("fast"); 
	SendData( "GMap_Get_More_Object"+params );
	
}

function GetOuterViewPaneBounds()
{
	var bounds = GMAP_OBJ.getBounds();
	var southWest = bounds.getSouthWest();
	var northEast = bounds.getNorthEast();
	var lngSpan = northEast.lng() - southWest.lng();
	var latSpan = northEast.lat() - southWest.lat();

	bound = new GLatLngBounds(
	new GLatLng(southWest.lat() - latSpan, southWest.lng() - lngSpan), 
	new GLatLng(northEast.lat() + latSpan, northEast.lng() + lngSpan));
	return bound;
}

// -- Load Initial Map Object 

function OnLoadMapObject(p_XML)
{
	
	var	docElem = p_XML.documentElement;
	
	// ids
	Ids.Name = docElem.getAttribute("t");
	Ids.MapObjectId = docElem.getAttribute("moid");
	Ids.RegionId = docElem.getAttribute("regid");
	Ids.ResortId = docElem.getAttribute("resid");
	
	// program id
	var pid = docElem.getAttribute("pid");
	Ids.ProgramId = pid;
		
	// center co-ords
	var clat = parseFloat(docElem.getAttribute("clat"));
	var clng = parseFloat(docElem.getAttribute("clng"));
	var cUP = docElem.getAttribute("cUP");

	// mo array
	var mapObjects = docElem.getElementsByTagName("mapobject");
	var mapObject = mapObjects[0]; 
	
	// lat, lng
	var lat = parseFloat( mapObject.getAttribute("lat") );
	var lng = parseFloat( mapObject.getAttribute("lng") );
	var defz = parseInt( mapObject.getAttribute("defz") );
	
	// center using point?
	if ( cUP == "True" ) {
		GMAP_OBJ.setCenter( new GLatLng( clat , clng ) , defz );
	} else {
		GMAP_OBJ.setCenter( new GLatLng( lat , lng ) , defz );
	}
	
	// map type?
	var maptype = docElem.getAttribute("maptype");
	switch ( maptype ) { 
		case "G_NORMAL_MAP":
			GMAP_OBJ.setMapType ( G_NORMAL_MAP );
			break;
		case "G_HYBRID_MAP":
			GMAP_OBJ.setMapType ( G_HYBRID_MAP );
			break;
		case "G_SATELLITE_MAP":
			GMAP_OBJ.setMapType ( G_SATELLITE_MAP );
			break;
		default:
			GMAP_OBJ.setMapType ( G_NORMAL_MAP );
			break;
	}
	
	var len = mapObjects.length
	
	for (i=0;i<len;i++)
	{  

		MO.create ( mapObjects[i] );
		
		// used for editor & directions
		if ( i==0) {
			
			GMAP_OBJ.DefaultMarker = MO.marker;
			GMAP_OBJ.DefaultMarkerName = MO.name; 
		
			if ( mapObjects.length > 1 ) { // it has explictly linked objects
				if ( Ids.ProgramId == "1" || Ids.ProgramId == "4" || Ids.ProgramId == "3" ) { 
					if ( ! G_MAP_ISMINIMAP ) { // it not a minimap	
						Directions.init( GMAP_OBJ , MO );
					}
				}
			} 
			
		}
		// used for directions
		if ( i >= 1) {
			// only if we're in Florida (1), USA & Canada (4) or Ski (3);
			if ( Ids.ProgramId == "1" || Ids.ProgramId == "4" || Ids.ProgramId == "3" ) {
				if ( ! G_MAP_ISMINIMAP ) { // it not a minimap	
					Directions.add ( MO );
				}
			}
		}

		// add it if the minzoom and maxzoom is between 1 and 19
		if ( (MO.minz>0 && MO.minz<20) && (MO.maxz>0 && MO.maxz<20) ) { 
			GMAP_OBJ.addOverlay( MO.marker ); 
		}
		
	}

	$("#mapLoading").fadeOut("fast"); 
	GMAP_OBJ.savePosition();
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////

function OnLoadMoreMapObjects( p_XML )
{
	var mapObjects = p_XML.documentElement.getElementsByTagName("mapobject"); 
	AddMarkersToZolvMarkerManager(mapObjects)  
}
 
//////////////////////////////////////////////////////////////////////////////////////////////////////////
 
 function AddMarkersToZolvMarkerManager(mapObjects)
 {  
 	var len = mapObjects.length;
	
	for (i=0;i<len;i++)
	{  
		MO.create( mapObjects[i] );
		// add it if the minzoom and maxzoom is between 1 and 19
		if ( (MO.minz>0 && MO.minz<20) && (MO.maxz>0 && MO.maxz<20) ) { 
			ZolvMarkerManager.addMarker(MO.marker);
		}
 	} 
	ZolvMarkerManager.renderMarkers();  
 }
 
//////////////////////////////////////////////////////////////////////////////////////////////////////////





