﻿var MarkerManager = new Class({//manages marker population on the map
	initialize: function(options) {		
		this.map = options.map;				    
	    this.markerIds = [];
	    this.layers = [];
	    this.hiddenLayers = [];
	    this.icons = [];
	    this.baseImageURL = options.baseImageURL;    
	    this.layersData = options.layers;	    
	    if (options.layers != null && options.layers.length > 0) {
	        for(var i=0; i< options.layers.length; i++) {	            
	            this.generateIcon(options.layers[i]);        
	        }
	    }   
	},
	addMarkers : function(markers) {//markerData: {id, desc, name ,layer ,lon, lat, icon}	    
	    for (var i=0; i<this.markerIds.length; i++) {
	        map.removeOverlay(this.markerIds[i]);
	    }
	    this.markerIds = [];
	    for(var i=0; i<markers.length; i++) {
	        var currentMarker = this.markerFactory(markers[i]);
	        currentMarker.params = {'id': markers[i].id, 'category': markers[i].category, 'desc' : markers[i].desc};
    		this.markerIds.push(currentMarker);			
	        map.addOverlay(currentMarker);
	    }
	    this.renderMarkers(map.getBounds(), map.getZoom())//TODO: remove once only relevant layer comes from server        
	},
	renderMarkers : function(bbox, zoom) {
	    var visibleLayers = this.getVisibleLayersForZoom(zoom);
	    for(var i=0; i<this.markerIds.length; i++) {
	        if(visibleLayers.contains(this.markerIds[i].params.category)) {
	            this.markerIds[i].show();	            
	        }
	        else    
	            this.markerIds[i].hide();
	    }	        
	},	
	showLayer : function(layerId) {
	    if(layerId == "99") {//weather exception, refactor..
	        for(var i=0; i< this.layersData.length; i++){
	            if (this.layersData[i].id.indexOf('99') == 0)
	                this.layersData[i].vs = true;
	        }	    
	    } else {//weather exception ends	         
	        var layerData = this.getLayerData(layerId);
	        if(layerData.vs == true) { 
	            return;
	        }	    
	        this.getLayerData(layerId).vs = true;
	    }
	    this.renderMarkers(this.map.getBounds(), this.map.getZoom());
	},
	hideLayer : function(layerId) {
	    if(layerId == 99) {//weather exception, refactor..
	        for(var i=0; i< this.layersData.length; i++){
	            if (this.layersData[i].id.indexOf('99') == 0)
	                this.layersData[i].vs = false;
	        }
	        this.renderMarkers(this.map.getBounds(), this.map.getZoom());	    
	    } else {//weather exception ends	    
	    var layerData = this.getLayerData(layerId);
	        if(layerData.vs == false) {
	            return;
	        }
	        else { 
	            layerData.vs = false;	        
	            this.renderMarkers(this.map.getBounds(), this.map.getZoom());
	        }
	    }
	},
	getLayerData : function(layerId) {
	    for(var i=0; i< this.layersData.length ; i++){
	        if (this.layersData[i].id == layerId)
	            return this.layersData[i];
	    }	
	},
	getVisibleLayersForZoom : function(zoomLevel) {
	    var layerIds = [];
	    for(var i=0; i< this.layersData.length; i++){
	        if (this.layersData[i].mx > zoomLevel-1 && this.layersData[i].mn < zoomLevel+1 && this.layersData[i].vs == true )
	            layerIds.push(this.layersData[i].id);
	    }
	    return layerIds;	
	},
	markerFactory : function(markerData) {
	    var currentIcon = this.generateIcon({ c : markerData.category });
      	var currentMarker = new GMarker(new GLatLng(markerData.lat, markerData.lon), currentIcon);
      	currentMarker.tooltip = '<div class="tooltip">'+ markerData.desc +'</div>';			      	
      	currentMarker.params = {'id': markerData.id, 'category': markerData.category, 'desc' : markerData.desc };      	
      	if(markerData.category == "1_2" || markerData.category.indexOf('99') != -1 ) {//zoom in on city/weather markers exception
      	    if(!(markerData.category.indexOf('99') != -1)) {//do nothing on weather
      	        GEvent.addListener(currentMarker, "click", function() {
                    map.setCenter(this.getLatLng(), 12);                                                                                 
                });   
      	    }     	          	
      	} else {
      	    GEvent.addListener(currentMarker, "click", function() {
                var params = this.params;
                markerManager1.openMarkerBubble(params);		                                                                                 
            });        
        }
        GEvent.addListener(currentMarker,"mouseover", function() {//bind tooltip
            markerManager1.showTooltip(this);
        });
        GEvent.addListener(currentMarker,"mouseout", function() {//bind tooltip
            tooltip.style.visibility="hidden";
        });                                       				      	
      	currentMarker.category = markerData.category;
      	return currentMarker;	
	},	
	openMarkerBubble : function(params) {
	    var markerId = params.id;
	    var markerCategory = params.category;
        var selectedMarker = this.getMarker(markerId);//TODO: condition on null
	    var request = new Ajax("Dispatcher/MarkerInfo.aspx?markerId=" + markerId +"&markerCategory="+ markerCategory , {
			method: 'get',
			onSuccess: function(response){			    			    	    
		        GEvent.addListener(this,"infowindowopen", function() {
		            bindAC();
		        });
		        this.openInfoWindowHtml(response); 	             	                    
		    }.bind(selectedMarker)
        }).request();            
	},
	generateIcon : function(iOptions) {
		var mCategory = iOptions.c.split('.')[0];//chop ext
		var existingIcon = this.getIcon(mCategory);
		if (existingIcon != null) {
		    return existingIcon;		
		} else {
		    var Icon = new GIcon();      	    
      	    Icon.category = mCategory;
      	    Icon.image = this.baseImageURL + "i"+ iOptions.c ;     	          	    
            var height = iOptions.h;
            var width = iOptions.w;
            Icon.iconSize = new GSize(width, height);           
      	    //Icon.transparent = "/images/t" +  mCategory + ".png";
      	    //Icon.printImage  = "/images/p" + mCategory + ".png";
      	    if(iOptions.c.indexOf('99') == -1){//weather icon no shadow
      	        Icon.shadowSize = new GSize(width*2, height);
      	        Icon.shadow = this.baseImageURL + "s" + iOptions.c ;      	    
      	    }
      	    Icon.iconAnchor = new GPoint(width/2, height);
      	    Icon.infoWindowAnchor = new GPoint(width/2, height);		    
		    this.addIcon(mCategory, Icon);		    
		    return Icon;
		} 	
	},
	addIcon : function(category, icon) {
	    if(this.icons.length > 0) {
	        for(var i=0; i<this.icons.length; i++) {
	            if(this.icons[i].category == category)
	                return;  
	        }	        	    
	    }
	    this.icons.push(icon);	
	},	
	getIcon : function(category) {
	    if(this.icons.length > 0) {
	        for(var i=0; i<this.icons.length; i++) {
	            if(this.icons[i].category == category)
	                return this.icons[i];  
	        }
	    }
	    return null;	
	},	 
	getMarker : function(markerId) {
	    for(j=0; j < this.markerIds.length; j++) {
	        if (this.markerIds[j].params.id == markerId) 
	            return this.markerIds[j];
	    }
	    return null;	    
	},
	showTooltip : function(marker) {
        tooltip.innerHTML = marker.tooltip;
        var point= map.getCurrentMapType().getProjection().fromLatLngToPixel(map.getBounds().getSouthWest(),map.getZoom());
        var offset=map.getCurrentMapType().getProjection().fromLatLngToPixel(marker.getPoint(),map.getZoom());
        var anchor=marker.getIcon().iconAnchor;
        var width=marker.getIcon().iconSize.width;
        var pos = new GControlPosition(G_ANCHOR_BOTTOM_LEFT, new GSize(offset.x - point.x - anchor.x + width,- offset.y + point.y +anchor.y));
        pos.apply(tooltip);
        tooltip.style.visibility="visible";
    }		
});

/* Direction Factory */
var DirectionManager = new Class({//manages user defined favourites
	initialize: function(options) {		
		this.map = options.map;
		this.panel = options.panel;		    
	},
	getDirections : function(options) {
	    this.source = options.source;
		this.destination = options.destination;
	    this.GDir = new GDirections(this.map, this.panel);
	    GEvent.addListener(this.GDir, "load", this.onDirectionLoad);	    
	    var query = "from:"+ this.source + " to: "+ this.destination;
	    this.GDir.load(query, {getPolyline : true});	    
	},
	onDirectionLoad : function() {
	    $('mapContainer').addClass('Directions');//refactor and launch
	    $E('#directionsPanelHead .Address').setText(dirManager1.source);
	    $E('#directionsPanelFooter .Address').setText(dirManager1.destination);	    
	    $ES('#directionsPanel .Print').addEvent('click', function(e) {//bind each one with event
            dirManager1.printResult();
		});
		$ES('#directionsPanel .Close').addEvent('click', function(e) {//bind each one with event
            $('mapContainer').removeClass('Directions');
		});			
		map.getInfoWindow().hide();        
	},
	printResult : function() {	
	    var pUrl = "http://maps.google.co.nz/maps?f=d&hl=en&geocode=10131904562613516108,-36.845930,174.760840&saddr="+ this.source +"&daddr="+ this.destination +"&mra=mi&mrsp=1,0&sz=15&sll=-36.864996,174.769006&sspn=0.023588,0.049224&ie=UTF8&z=15&pw=2";
	    window.open(pUrl, "printWindow", "target=_blank,width=800px,scrollbars=yes");	    
	}
});

var map = null;
var markerManager1 = null;

function initMap(startLon, startLat, startZ) {//TODO: pass init coords(nz)
	if (GBrowserIsCompatible()) {//TODO: move to initMap map manager 
   		map = new GMap2(document.getElementById("map"));
   		if (bookingsMap == true)
   		    bookingsMap = map;
        map.addControl(new GSmallMapControl());
        map.addControl(new GMapTypeControl());
        map.enableContinuousZoom();
        map.setCenter(new GLatLng(startLat, startLon), startZ);
        map.enableScrollWheelZoom();
        map.addControl(new GOverviewMapControl());
        //map.setMapType(G_PHYSICAL_MAP);
        GEvent.addListener(map, "dragend", function() {//populate markers on pan
  			loadBranches();  				  					
  		});
  		GEvent.addListener(map, "zoomend", function(oldZ, newZ) {//populate markers on zoom OUT only
  		    loadBranches();
  		    $('zoomCounter').innerHTML = newZ;//debug point  				  					
  		});
  		GEvent.addListener(map, "dblclick", function(oldZ,newZ) {//populate markers on zoom IN only
  			loadBranches();
  			$('zoomCounter').innerHTML = newZ;//debug point	  					
  		});               
        $ES('input.LayerSelector').each(function(el){
            el.checked = false;
            el.addEvent('click', function(e) {//bind each one with event
  	            var event = new Event(e);
		        var element = new Element(event.target);
		        var layerId = element.getProperty('name');		    
		        if(element.checked) {//expose the layers markers		        
			        markerManager1.showLayer(layerId);		        			        		    		
		        } else {//hide the layers markers
			        markerManager1.hideLayer(layerId);					
		        }	
	        });	    
  	    }); 	    	  	    
  	    document.getElementById("map").appendChild(tooltip);
        tooltip.style.visibility="hidden";	    
  	    if($("weatherPanelContainer").innerHTML == "")
  	        $("weatherPanelContainer").setStyle("display","none");  	   
  	    $ES('a','tabContainer').each(function(el){
            el.checked = false;
            el.addEvent('click', function(e) {//bind each one with event  	            
  	            var event = new Event(e);
		        event.stop(); 
		        var element = new Element(event.target);                               
                var linkElm = element;
                while(linkElm.nodeName != 'A')
                    linkElm = linkElm.parentNode;               
                branchType = linkElm.hasClass('cars') ? 'cars' : 'campers';
                loadBranches();
                var other = (linkElm.id == "mapCampersTab") ? $("mapCarsTab") : $("mapCampersTab");
                other.removeClass('Selected');
                linkElm.addClass('Selected');
                linkElm.blur();                
  	        });
  	    });
  	    
  	    var closeWeather = $('closeWeather');
  	        if(closeWeather != null) {
  	            closeWeather.addEvent('click', function(e) {
		        var event = new Event(e);
		        event.stop();
		        var wContainer = $('weatherPanelContainer')
		        var element = new Element(event.target)
			        wContainer.toggleClass('Hide');    			    
			    var linkElm = element;
	            while(linkElm.nodeName != 'A')
                        linkElm = linkElm.parentNode;
	            linkElm.blur();
	            if(wContainer.hasClass('Hide')) {
	                linkElm.setText('Open +');  
	            } else {
	                linkElm.setText('Close X');
	            }      	    
	        });
	    }  	    
  	    loadBranches(); 	      	     	    
  	    return true;//successfully initialed the map
  	} else {
  		return false;//failed to initial the map
  	}  	   
}

function getDirections(caller) {//bind each one with event
    var element = new Element(caller);
    var formDiv = element.parentNode;
    var streetAdr = $E('#streetAddress', formDiv);
    var suburb = $E('#suburb', formDiv);
    var dest = element.getProperty('rel');
    var origin = (streetAdr.value == "Enter Street Address" ? "" : streetAdr.value ) + " " + (suburb.value != "Enter Suburb" ? suburb.value.split(',')[0] : "") + " " + suburb.getProperty('rel').split(':')[0];
    //alert("or:" +origin+ " dest:" + dest);
    dirManager1 = new DirectionManager({
        map: map,
        panel: $('directionsPanelBody')
    });
    dirManager1.getDirections({source:origin, destination: dest});
}

function loadBranches() {    
    var requestURL = "webservices/getmarkers.asmx/GetMarkersForBox";
    var request = new Ajax(requestURL , {
        method: "post",
        postBody: 'bbox='+ map.getBounds() + '&layers=l1_2&zoom=' + map.getZoom()+ '&branchType=' + branchType,
        onSuccess: function(response){
            var response = response.substr(response.indexOf("com\">")+5, response.indexOf("</string>") - response.indexOf("com\">")-5  );
            var responseJson = Json.evaluate(response);           
            var filtered = [];
            for(var i=0; i< responseJson.length; i++) {
                if(typeof responseJson[i].type == 'undefined' /*|| responseJson[i].type == null*/) 
                    filtered.push(responseJson[i]);//not a branch                
                if(branchType=="cars" && (responseJson[i].type == 1 || responseJson[i].type == 3)) {
                    filtered.push(responseJson[i]);
                } else if (branchType=="campers" && (responseJson[i].type == 2 || responseJson[i].type == 3)) {
                    filtered.push(responseJson[i]);
                } else if(branchType=="both") {
                    filtered.push(responseJson[i]);
                }
            }
            markerManager1.addMarkers(filtered);       
        }.bind(this)
    }).request();        	
}

function bindAC(){//bind AC functionality
    var searchInput = $('suburb');//AC Directions, content specific code               
    var indicator = new Element('div', {
        'class': 'autocompleter-loading',
        'styles': {'display': 'none'}
    }).injectAfter(searchInput); // appended after the input      
    var completer = new Autocompleter.Ajax.Json(searchInput,"webservices/GetGISData.asmx/GetSuburbsForCity", {
        'postVar': 'query',
        'onRequest': function(el) {
            indicator.setStyle('display', '');
        },
        'onComplete': function(el) {
            indicator.setStyle('display', 'none');
        }                    
    });//End AC Directions
}

