/* JS to correspond with GMaps php classes. All clients will have global access
   to the objects below, and the on-the-fly JS generated by GMaps classes will
   require the inclusion of this file. */

// GLOBAL ARRAYS
var maps = [];		// hold maps created on this page
var markers = [];	// hold markers created for maps on this page

/** GLOBAL ICON STUFF **/
// TODO: make these actual icons based on service categories
// Create a base icon for all of our markers that specifies the shadow, icon dimensions, etc.
var baseIcon = new GIcon();
baseIcon.image = "/media/images/map_icon.gif";
//baseIcon.onImage = "http://www.google.com/mapfiles/markerB.png";
//baseIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
baseIcon.iconSize = new GSize(38, 37);
//baseIcon.shadowSize = new GSize(37, 34);
baseIcon.iconAnchor = new GPoint(0, 33);
//baseIcon.infoWindowAnchor = new GPoint(9, 2);
//baseIcon.infoShadowAnchor = new GPoint(18, 25);

var baseServiceIcon = new GIcon();
baseServiceIcon.image = "http://www.google.com/mapfiles/markerA.png";
baseServiceIcon.iconSize = new GSize(50, 50);
baseServiceIcon.iconAnchor = new GPoint(2, 50);
baseServiceIcon.infoWindowAnchor = new GPoint(1, 1);

var baseNumberedIcon = new GIcon();
baseNumberedIcon.iconSize = new GSize(19, 19);
baseNumberedIcon.iconAnchor = new GPoint(0, 19);
baseNumberedIcon.infoWindowAnchor = new GPoint(1, 1);
baseNumberedIcon.shadow = "/_images/map_marker_shadow.png";
baseNumberedIcon.shadowSize = new GSize(27, 19);

var hiliteIcon = new GIcon();
hiliteIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
hiliteIcon.iconSize = new GSize(100, 100);
hiliteIcon.shadowSize = new GSize(0, 0);
hiliteIcon.iconAnchor = new GPoint(50, 50);
hiliteIcon.image = "/_images/target.gif";

var locationIcon = new GIcon();
locationIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
locationIcon.iconSize = new GSize(32, 32);
locationIcon.shadowSize = new GSize(0, 0);
locationIcon.iconAnchor = new GPoint(16, 16);
locationIcon.image = "/_images/location.png";

// make some "global" icons
// default icon
var icon_array = [];

for (var i = 1; i <= 60; i++) {

    icon_array[i] = new GIcon(baseNumberedIcon);

    icon_array[i].image  = "/_images/mapicons/numbered/" + i + ".png";

}

// old school letter icons
var mapicon_b = new GIcon(baseIcon);
mapicon_b.image = "http://www.google.com/mapfiles/markerB.png";

// new school default service icon for an iconless category
var mapicon_default = new GIcon(baseIcon);
mapicon_default.image = "/_images/mapicon_default.png";
mapicon_default.onImage = "/_images/mapicon_default.png";

// actual service icons corresponding to category_id
var mapicon_5 = new GIcon(baseServiceIcon);
mapicon_5.image = "/_images/mapicon_5.png";
mapicon_5.onImage = "/_images/mapicon_5_on.png";

var mapicon_6 = new GIcon(baseServiceIcon);
mapicon_6.image = "/_images/mapicon_6.png";
mapicon_6.onImage = "/_images/mapicon_6_on.png";

var mapicon_8 = new GIcon(baseServiceIcon);
mapicon_8.image = "/_images/mapicon_8.png";
mapicon_8.onImage = "/_images/mapicon_8_on.png";

var mapicon_9 = new GIcon(baseServiceIcon);
mapicon_9.image = "/_images/mapicon_9.png";
mapicon_9.onImage = "/_images/mapicon_9_on.png";

var mapicon_11 = new GIcon(baseServiceIcon);
mapicon_11.image = "/_images/mapicon_11.png";
mapicon_11.onImage = "/_images/mapicon_11_on.png";

var mapicon_12 = new GIcon(baseServiceIcon);
mapicon_12.image = "/_images/mapicon_12.png";
mapicon_12.onImage = "/_images/mapicon_12_on.png";

var mapicon_17 = new GIcon(baseServiceIcon);
mapicon_17.image = "/_images/mapicon_17.png";
mapicon_17.onImage = "/_images/mapicon_17_on.png";

var mapicon_18 = new GIcon(baseServiceIcon);
mapicon_18.image = "/_images/mapicon_18.png";
mapicon_18.onImage = "/_images/mapicon_18_on.png";

var mapicon_19 = new GIcon(baseServiceIcon);
mapicon_19.image = "/_images/mapicon_19.png";
mapicon_19.onImage = "/_images/mapicon_19_on.png";

var mapicon_21 = new GIcon(baseServiceIcon);
mapicon_21.image = "/_images/mapicon_21.png";
mapicon_21.onImage = "/_images/mapicon_21_on.png";

var mapicon_22 = new GIcon(baseServiceIcon);
mapicon_22.image = "/_images/mapicon_22.png";
mapicon_22.onImage = "/_images/mapicon_22_on.png";

var mapicon_1266 = new GIcon(baseServiceIcon);
mapicon_1266.image = "/_images/mapicon_1266.png";
mapicon_1266.onImage = "/_images/mapicon_1266_on.png";

var mapicon_1358 = new GIcon(baseServiceIcon);
mapicon_1358.image = "/_images/mapicon_1358.png";
mapicon_1358.onImage = "/_images/mapicon_1358_on.png";

// ZIP ICONS stuff (dynamically grown array)
var baseZipIcon = new GIcon();
baseZipIcon.image = "http://www.google.com/mapfiles/markerA.png";
baseZipIcon.iconSize = new GSize(75, 25);
baseZipIcon.iconAnchor = new GPoint(37, 12);
baseZipIcon.infoWindowAnchor = new GPoint(1, 1);

var zipicon_array = [];	// see functions way below for populating this

/** GLOBAL GMAP FUNCTIONS **/
bindAjaxHandler('DisplayMarker', function (jso){
	var markerID = jso.markerID;
	var marker = getMarker(markerID);
	marker.content = jso.content;
	displayMarkerContent(markerID);
});

// create a marker, id it, and tell it how / from where to get its content
function createMarker(id, point, icon, title, ajaxClassMethod, content, result_dom_id){
	if (!icon) icon = baseServiceIcon;

	opts = {};
	opts.icon = icon;
	if (title) opts.title = title;
	//if (zindex) opts.zIndexProcess = zIndexProc;
	var marker = new GMarker(point, opts);
	marker.id = id;
	marker.ajaxClassMethod = ajaxClassMethod;	// either false OR an (encrypted) class::method string
	marker.content = content;
	marker.result_dom_id = result_dom_id;

	return marker;
}

// add a marker to map and to the global markers array for later retrieval (ie toggling)
function addMarker(map, marker){
	marker.map = map;	// to tag markers by the map they is on
	map.addOverlay(marker);	// add dat shiz
	markers[marker.id] = marker;	// sto' it in the 'ray

	bindMarkerEvents(marker, true);
}

function bindMarkerEvents(marker, addOrRemove){
	if (addOrRemove){
		if (marker.alreadyBound) return;
		marker.evt_click = GEvent.addListener(marker, 'click', onMarkerClick);
		marker.evt_over = GEvent.addListener(marker, 'mouseover', onMarkerMouseover);
		marker.evt_out = GEvent.addListener(marker, 'mouseout', onMarkerMouseout);
		marker.alreadyBound = true;
	}else{
		GEvent.removeListener(marker.evt_click);
		GEvent.removeListener(marker.evt_over);
		GEvent.removeListener(marker.evt_out);
		marker.alreadyBound = false;
	}
}

var highlightDomElement = function(dom_element_id){
	hlClass = "mapresult_highlight";
	$("."+hlClass).removeClass(hlClass);

	dom_element = $("#"+dom_element_id);
	if (dom_element){
		dom_element.addClass(hlClass);
	}
};

// wrap the opening (ajax, "caching", etc) of the marker's modal
var openMarkerModal = function(marker){
	// choose whether to display content now, or to handle via ajax
	if (marker.content){
		displayMarkerContent(marker.id);
	}else if (marker.ajaxClassMethod) {
		ajax(marker.ajaxClassMethod, 'mapID='+marker.map.id+'&markerID='+marker.id, 'marker_'+marker.id);
		//response will go to 'DisplayMarker' handler defined above.
	}
}

// viewOnList modal link onclick
var modalLinkClicked = function(markerID){
	var marker = getMarker(markerID);

	if (marker.result_dom_id){
		window.location.href='#'+marker.result_dom_id;
	}
	
	return false;
};

// viewOnMap link onclick
var resultClicked = function(markerID){
	var marker = getMarker(markerID);

	//reset map to normal state.
	hideSelectedMarker(marker.map.id);

	// hilite marker
	hiliteMarkerOnMap(markerID, true);

	// hilite/treat map dom_element, if the marker is set up with the result_dom_id stuff
	if (marker.result_dom_id){
		window.location.href='#'+marker.map.id;
		highlightDomElement(marker.result_dom_id);
	}
	
	openMarkerModal(marker);
	
	return false;
};

// map marker listener... handles ajaxed marker content, caching, display of infowindow, tabs, etc THA WORX
var onMarkerClick = function(){
	var marker = this;
	var map = marker.map;

	//reset map to normal state.
	hideSelectedMarker(map.id);

	// hilite marker
	hiliteMarkerOnMap(marker.id, true);

	// hilite/treat result_dom element
	if (marker.result_dom_id){
		//window.location.href = "#"+marker.result_dom_id;
		highlightDomElement(marker.result_dom_id);
	}

	openMarkerModal(marker);
};

function clickMarker(id){
	GEvent.trigger(getMarker(id), 'click');
}


var onMarkerMouseover = function(){
	if (this.getIcon().onImage) this.setImage(this.getIcon().onImage);
};

function mouseoverMarker(id){
	GEvent.trigger(getMarker(id), 'mouseover');
}

var onMarkerMouseout = function(){
	if (this.getIcon().onImage) this.setImage(this.getIcon().image);
}

function mouseoutMarker(id){
	GEvent.trigger(getMarker(id), 'mouseout');
}

// create a GInfoWindowTab, tell it how / from where to get its content
function createInfoWindowTab(title, content){
	var tab = new GInfoWindowTab(title, content);
	// do stuff here if needsbe
	return tab;
}

// return one of the markers already created on the page, whether it was created on initial pageload or via ajax
function getMarker(id){
	return markers[id];
}
function getMap(id){
	return maps[id];
}

var hiliteMarkerOnMap = function(markerID, moveMap){// !!! there is a DIFFERENT VERSION of this function in: smallcontentwidget_service.tpl.php + largecontentwidget_details.tpl.php
	var marker = getMarker(markerID);
	var map = marker.map;
	var point = marker.getPoint();

	//add hilight, remove marker events.
	map.hiliteMarker.setPoint(new GLatLng(point.lat()+.00001, point.lng()));
	map.addOverlay(map.hiliteMarker);	//add the hilite marker
	bindMarkerEvents(marker, false);
	mouseoverMarker(marker.id);
	
	if (moveMap) map.panTo(point);

	//set this marker as selected.
	map.selectedMarker = marker;
}

// method to display marker contents
var displayMarkerContent = function(markerID){ // !!! there is a DIFFERENT VERSION of this function in: smallcontentwidget_service.tpl.php + largecontentwidget_details.tpl.php
	var marker = getMarker(markerID);
	var map = marker.map;
	var point = marker.getPoint();

	var modal = $('<div id="MapModal_'+map.id+'" class="mapmodal"></div>').prependTo('#MapBox_'+map.id);
	modal[0].innerHTML = marker.content;
	modal.prepend('<a class="mapmodalclose" onclick="hideSelectedMarker(\'' + map.id + '\')"></a>');
};

var hideSelectedMarker = function(mapID, refreshMap){
	var map = getMap(mapID);
	if (refreshMap) GEvent.trigger(map, 'moveend');
	
	var marker = map.selectedMarker;
	if (!marker) return;
	
	// unhighlight stuff
	highlightDomElement(false);

	//remove overlay, and reset marker events.
	map.removeOverlay(map.hiliteMarker);
	bindMarkerEvents(marker, true);
	mouseoutMarker(marker.id);

	//hide modal.
	$('#MapModal_'+map.id).remove();

	map.selectedMarker = null;
}

/********zipmarkery stuff***********/
var getZipIcon = function(zip){
	if (zipicon_array[zip] != null){
		return zipicon_array[zip];
	} else {
		root = getZipIconRoot(zip);
		zipicon = new GIcon(baseZipIcon);
		zipicon.image = root + zip + "_off.png";
		zipicon.onImage = root + zip + "_on.png";
		zipicon_array[zip] = zipicon;
		return zipicon;
	}
};
var getZipIconRoot = function(zip){
	root = "http://ugv.zootoo.com/spolists/";
	return root;
};
// create a ZIPmarker, id it, etc
function createZipMarker(zipcode, point, icon, offTitle, onTitle, ajaxClassMethod, on){
	if (!icon) icon = baseZipIcon;

	opts = {};
	opts.icon = icon;
	opts.title = offTitle;
	//if (zindex) opts.zIndexProcess = zIndexProc;
	var marker = new GMarker(point, opts);
	marker.id = zipcode;
	marker.zipcode = zipcode;
	marker.ajaxClassMethod = ajaxClassMethod;	// either false OR an (encrypted) class::method string
	marker.offTitle = offTitle;
	marker.onTitle = onTitle;
	marker.turnedOn = on;	// apparently google reserves marker.on for something... hence marker.turnedOn
	return marker;
}
// add a ZIP marker to map and to pthe global markers array for later retrieval (ie toggling)
function addZipMarker(map, marker){
	marker.map = map;	// to tag markers by the map they is on
	map.addOverlay(marker);	// add dat shiz
	markers[marker.id] = marker;	// sto' it in the 'ray

	bindZipMarkerEvents(marker, true);
	if (marker.turnedOn) {
		turnOnZipMarker(marker);
	}
}
function bindZipMarkerEvents(marker, addOrRemove){
	if (addOrRemove){
		if (marker.alreadyBound) return;
		marker.evt_click = GEvent.addListener(marker, 'click', onZipMarkerClick);
		marker.alreadyBound = true;
	}else{
		GEvent.removeListener(marker.evt_click);
		marker.alreadyBound = false;
	}
}
var onZipMarkerClick = function(){
	var marker = this;
	var map = marker.map;

	// call spolists js to toggle (will eventually toggle marker and do ajax)
	if (marker.turnedOn){
		changeSelection('remove', marker.zipcode);
	} else {
		changeSelection('add', marker.zipcode);
	}
};
var turnOnZipMarker = function(marker){
	if (marker == null) {	// incase spolists calls this on a nonvisible marker (assumes clearing old markers upon re-add-all)
		return false;
	}
	marker.setImage(marker.getIcon().onImage);
	//	marker.title = marker.offTitle;		// cannot change titles without replacing marker yet
	marker.turnedOn = true;
};
var turnOffZipMarker = function(marker){
	if (marker == null) {	// incase spolists calls this on a nonvisible marker (assumes clearing old markers upon re-add-all)
		return false;
	}
	marker.setImage(marker.getIcon().image);
	//	marker.title = marker.onTitle; 		// cannot change titles without replacing marker yet
	marker.turnedOn = false;
};
