var map;
var debug = false;
var tooltip;
var selectedRouteIndex = 0;
var mgr=null;	// the active marker manager

function serviceMap()
{
	// this object should contain all member elements and all methods
	this.serviceId=0;
	this.routeCollection = new Object();
	this.mapHtmlDivId;
	this.routeSelectorDivId;
	this.defaultLat;
	this.defaultLng;
	this.defaultZoom;
	this.routes = new Array();
	this.lastKnownSelectedStopId = -1;
	this.loadingimage=null;
	this.recenterMap=false;
	this.bubbleHeight=null;
	this.bubbleWidth=null;
	this.stopZoomLevel = 15;
	this.heading1Id=null;
	this.heading2Id = null;
}


// Handles the intiial load of the map.  This MUST be called before any other methods.
serviceMap.prototype.load=function()
{
	// set up the google map
	if (GBrowserIsCompatible()) 
	{ 
		map = new GMap2($(this.mapHtmlDivId));
		// Put the loading message underneath the tiles
		
		
		$(this.mapHtmlDivId).style.backgroundImage = "url(" + publicWebServiceUrl.substring(0, publicWebServiceUrl.lastIndexOf("/")) + "/clientimages/loading.gif)";
		
		map.addControl(new GLargeMapControl());
		//map.addControl(new GMapTypeControl());
		map.enableScrollWheelZoom();
		
		// set the center of the map to the default values set
		map.setCenter(new GLatLng(this.defaultLat,this.defaultLng), this.defaultZoom);
		GEvent.bind(map, "click", this, this.mapClickHandler);
		
		
	}
	else 
	{
		alert("Sorry, the Google Maps API is not compatible with this browser");
	}
	if (this.serviceId>0)
	{
		this.getServiceInfo();
	}
}


// Handles all clicks on the map.  Code in here all possible things that should happen when map elements are clicked.
serviceMap.prototype.mapClickHandler=function(overlay, point)
{
	if (overlay) 	// clicked on an overlay
	{
		// call maker click event handler
		this.marker_click_handler(overlay);
	}
	else if (point) 
	{
		//whatever you want to happen if you don't click on an overlay.
	}
	else
	{
		// anything else

	}
}

serviceMap.prototype.marker_click_handler=function(overlay)
{
	if (overlay.stopId!=null)
	{
		//this.showStopCustomToolTip(overlay, "<b>Some value</b>");
		//overlay.openInfoWindowHtml(this.getStopBubbleHtml(overlay.stopId));
	}
}

// Takes a stop id and returns the HTML that will appear in the 'Bubble' on the map.
serviceMap.prototype.getStopBubbleHtml=function(stopid)
{
	try
	{
		var rtidx = this.getSelectedRouteIndex();
		var stop = this.routes[rtidx].stops[stopid];	// WRONG SHOULD BE SELECTED ROUTE NOT 0
		var toRet="";
		
		// call the web service to update the servicesInfoWindow div even tho it doesn't exist yet.
		stop_getServicesByStop(stop.stopId, this.getServicesByStop_success.bind(this), this.ajaxError.bind(this));
		toRet += "<strong>" + stop.stopName + "</strong>" + "<br/>(text <strong>" + stop.naptanCode + "</strong> to XXXXX for <a href=\"/travel/text.aspx\" title=\"Details of our text message service\">times of next bus</a>)<p>Other services that stop here: <div id=\"servicesInfoWindow\"></div></p>";
		
		if (this.bubbleHeight!=null)
		{
			toRet = '<div style="height:' + this.bubbleHeight + 'px;width:' + this.bubbleWidth + 'px;" id="bubbleDiv">' + toRet + '</div>';
		}		

		return toRet;
		
	}
	catch(e) {
		return "";
	}
	
}

serviceMap.prototype.getServicesByStop_success=function(resp)
{
	var val = cleanResponse(resp.responseText);
	eval(val);
	var htmlString = "";
	for (var i=0; i<response.services.length; i++)
	{
		if (response.services[i].serviceId!=this.serviceId)
		{
			htmlString += "<a href=\"service.aspx?serviceid=" + response.services[i].serviceId + "&lng=" + map.getCenter().lng() + "&lat=" + map.getCenter().lat() + "&zm=" + map.getZoom() + "&st="+this.lastKnownSelectedStopId+"\" title=\"" + response.services[i].serviceName + " - " + response.services[i].serviceDescription + "\n\rClick to view this services route\">" + response.services[i].serviceName + "</a> | ";
		}
	}

	// update the div 'servicesInfoWindow'
	if (!$('servicesInfoWindow'))
	{
		// wait 3 seconds and try again
		setTimeout(function(){try { $('servicesInfoWindow').innerHTML = htmlString;} catch(e){}}, 300);
	}
	else
	{
		$('servicesInfoWindow').innerHTML = htmlString;
	}
}


serviceMap.prototype.getServiceInfo=function()
{
	// get service info from database
	servicemap_getServiceInfo(this.serviceId, this.getServiceInfo_success.bind(this), this.ajaxError.bind(this));
}

serviceMap.prototype.getServiceInfo_success=function(resp)
{
	var val = cleanResponse(resp.responseText);
	eval(val);
	this.routes = response.service.routes;
	this.createRouteSelector();
	this.showRoute(this.routes[0].routeId, this.routes[0].maps[0].routeMapId);
}



serviceMap.prototype.showRoute = function(routeid, routemapid) {
    this.hideAllRoutes();
    this.showRoutePolyline(routeid, routemapid);
    this.showRouteStops(routeid);
}



serviceMap.prototype.hideAllRoutes=function()
{
	for (var key in this.routeCollection) {  this.hideRoutePolylineFromWS(key);}
}


serviceMap.prototype.showRoutePolyline=function(routeid, routemapid) {

// if we dont already have this map

if (this.routeCollection[routemapid] == null)
	{
		this.getRoutePolyline(routeid, routemapid);
	}
	else
	{
	    if (this.routeCollection[routemapid].isHidden())
		{
		    this.routeCollection[routemapid].show();
		    if (this.heading1Id != null) {
		        $(this.heading1Id).innerHTML = this.routeCollection[routemapid].routeMapName;
		    }
		}
	}
}



serviceMap.prototype.hideRoutePolylineFromWS=function(routeid)
{

	// note either method can be used - need to see what uses most/least memory
	// map.removeOverlay(routeCollection[routeid]);
	
	this.routeCollection[routeid].hide();
}


serviceMap.prototype.getRoutePolyline=function(routeid, routemapid)
{
	// call the web service proxy
	locationmap_getRouteMapPolyline(routeid, routemapid, 10, this.getPolyline_success.bind(this), this.ajaxError.bind(this))
	
}

serviceMap.prototype.getPolyline_success=function(resp)
{
	var val = cleanResponse(resp.responseText);
	eval(val);
	response.polyline.weight=7;
	this.routeCollection[response.routeMapId] = response.polyline;
	if (response.routeMapName) this.routeCollection[response.routeMapId].routeMapName = response.routeMapName;
	if (this.recenterMap)
	{
		map.setCenter(new GLatLng(response.centerLat, response.centerLng), response.initialZoom);
		this.recenterMap = false;	// no more re-centering when loading other routes for this service
	}
	map.addOverlay(this.routeCollection[response.routeMapId]);
	if (this.heading1Id != null) {
	    $(this.heading1Id).innerHTML = this.routeCollection[response.routeMapId].routeMapName;
	}
}


serviceMap.prototype.createStopMarker=function(stop)
{
	// takes a stop and returns a GMarker

    var busIcon = new GIcon(G_DEFAULT_ICON);
    busIcon.image = "http://chart.apis.google.com/chart?chst=d_map_pin_icon&chld=bus|CCCCFF";

    var marker = new GMarker(new GLatLng(parseFloat(stop.Lat), parseFloat(stop.Lng)), { draggable: false, icon: busIcon });
        marker.stopId = stop.stopId;

	var _htmlstring = this.getTooltipHtml(stop);
	GEvent.addListener(marker,"mouseover", function() { showCustomTooltip(marker, _htmlstring); });      
	GEvent.addListener(marker,"mouseout", function() { tooltip.style.visibility="hidden" });         
	return marker;
	
}


serviceMap.prototype.hideAllStops=function()
{

}

serviceMap.prototype.showRouteStops = function(routeid) {
    var ridx = -1;
    for (var i = 0; i < this.routes.length; i++) {
        if (this.routes[i].routeId == routeid)
            ridx = i;
    }

    if (ridx == -1 || this.routes[ridx] == null) {
        this.getRouteStops(routeid);
    }
    else {
        // if we dont already have this route's stops loaded, call the web service proxy
        if (!this.routes[ridx].stops) {
            this.getRouteStops(routeid);
        }
        else	// show them
        {
            // need to show them as well
            this.plotStopsOnMap(ridx);
        }
    }
}



serviceMap.prototype.getRouteStops=function(routeid)
{
	locationmap_getRouteStops(routeid, this.getRouteStops_success.bind(this), this.ajaxError.bind(this))
}

serviceMap.prototype.getRouteStops_success = function(resp) {
    var val = cleanResponse2(resp.responseText);
    if (debug)
        $('debugConsole').innerHTML = (val);
    eval(val);

    var rid = response.routeid;
    var ridx = -1;
    for (var i = 0; i < this.routes.length; i++) {
        if (this.routes[i].routeId == rid)
            ridx = i;
    }

    if (ridx == -1)	// if we don't have a matching route in our service (because service id not set)
    {
        this.routes[ridx] = new Object();
    }

    this.routes[ridx].stops = new Object();

    // create the markers

    markers = new Object();
    
    for (i = 0; i < response.stops.length; i++) {
        response.stops[i].stopName = decodeURI(response.stops[i].stopName); 	// un encode URL encoded values
        var stopMarker = this.createStopMarker(response.stops[i]);
        //markers[i] = stopMarker; 
        markers[response.stops[i].stopId] = stopMarker;        // markers should not be indexed on the relative position they were loaded in, but rather should be associative with thier stopId
        this.routes[ridx].stops[response.stops[i].stopId] = response.stops[i];
    }

    // save the markers in the route object
    this.routes[ridx].stopMarkers = markers;

    this.plotStopsOnMap(ridx);
}

serviceMap.prototype.getRouteTimetableStops = function(routeid) {
    locationmap_getRouteTimetableStops(routeid, this.getRouteTimetableStops_success.bind(this), this.ajaxError.bind(this))
}

serviceMap.prototype.getRouteTimetableStops_success = function(resp) {
    var val = cleanResponse2(resp.responseText);
    if (debug)
        $('debugConsole').innerHTML = (val);
    eval(val);

    var rid = response.routeid;
    var ridx = -1;
    for (var i = 0; i < this.routes.length; i++) {
        if (this.routes[i].routeId == rid)
            ridx = i;
    }

    if (ridx == -1)	// if we don't have a matching route in our service (because service id not set)
    {
        this.routes[ridx] = new Object();
    }

    this.routes[ridx].timetablestops = new Object();

    // create the markers

    markers = new Object();

    for (i = 0; i < response.stops.length; i++) {
        response.stops[i].stopName = decodeURI(response.stops[i].stopName); 	// un encode URL encoded values
        this.routes[ridx].timetablestops[response.stops[i].stopId] = response.stops[i];
    }
}


serviceMap.prototype.ajaxError = function(error) {
    var val = error.responseText;
    //alert("An AJAX error occured");
    alert(val);
    alert(error.sourceUrl);
}


// NEED TO REWRITE THIS TO RENDER AS BULLETED HYPERLINKS
serviceMap.prototype.createRouteSelector = function() {
    var str = "<ul>";
    for (var i = 0; i < this.routes.length; i++) {

        for (var j = 0; j < this.routes[i].maps.length; j++) {
            var routeid = this.routes[i].routeId;
            var radioValue = this.routes[i].maps[j].routeMapId;
            var radioText = this.routes[i].maps[j].routeMapName;
            str += "<li><a href=\"#\" onclick=\"s.showRoute(" + routeid + "," + radioValue + "); selectedRouteIndex = " + i + ";\"><img src=\"images/iconMap.png\" align=\"absmiddle\" /><span>" + radioText + "</span></a></li>";
        }
    }
    str += "</ul>";

    $(this.routeSelectorDivId).innerHTML = str;
}


serviceMap.prototype.getSelectedRouteIndex=function()
{
	return selectedRouteIndex;	// could iterate through radios to see which is selected, or use teh global var which isn't really the best
}


serviceMap.prototype.plotStopsOnMap=function(ridx)
{
	// add the markers to the map
	if (mgr == null)
	
	mgr = new MarkerManager(map);


    mgr.clearMarkers();
    //	mgr.addMarkers(this.routes[ridx].stopMarkers, this.stopZoomLevel);
    mgr.addMarkersAssociative(this.routes[ridx].stopMarkers, this.stopZoomLevel);
	mgr.refresh();
}




serviceMap.prototype.getTooltipHtml=function(stop)
{
	return "<strong>" + stop.stopName + "</strong>";
}



/*** HACK * v2.76 only  
GMarkerManager.prototype.clearMarkers = function() {

    var me = this;

    // clear currently shown

    if (me.Wd > 0) {
        me.Id(me.K, me.Kd);
    }

    // reset arrays
    var maxZoom = me.df;
    var maxWidth = 256;
    for (var zoom = 0; zoom < maxZoom; ++zoom){
        me.ed[zoom] = [];
        me.oc[zoom] = 0;
        me.gc[zoom] = Math.ceil(maxWidth/me.Ec);
        maxWidth <<= 1;
     }
    me.refresh();
    
} */

