// JavaScript Document
// Requires Prototype.js

if(!maps)
	var maps = new Object();

if(window['placemarks'] == 'undefined')
	var placemarks = new Object();

//Object Representing a Simpleview Map
function Map(name,divname,defaultLat,defaultLng,defaultZoom){
	this.defaultSettings = {
		control: new GSmallMapControl(),
		defaultLat: defaultLat,
		defaultLng: defaultLng,
		defaultZoom: defaultZoom,
		defaultPoint: new GLatLng(defaultLat,defaultLng)
	}

	this.settings = {
		control: new GSmallMapControl(),
		defaultLat: defaultLat,
		defaultLng: defaultLng,
		defaultZoom: defaultZoom,
		defaultPoint: new GLatLng(defaultLat,defaultLng)
	}
	
	this.bounds = new GLatLngBounds();
	this.name = name;
	this.gmap = null;

	this.collections = new Object();
	this.defaultCollection = null;

	this.allFilters = new Object();
	this.cancelCentering = false;


	//Create An Alias
	var map = this;

	this.sortCollection = function(collection,sortBy){
		this.collections[collection].sortBy(sortBy);
	}

	this.initCustomIcons = function(){
		this.iconStyles = {
			'default':{
				image: imgroot + '/includes/images/shell/google/default_icon:label.png',
				shadow: imgroot + '/includes/images/shell/google/default_shadow.png',
				smimage: imgroot + '/includes/images/shell/google/default_sm_icon:label.png',
				iconSize: new GSize(29.0, 34.0),
				shadowSize: new GSize(47.0, 34.0),
				iconAnchor: new GPoint(15.0, 34.0),
				infoWindowAnchor: new GPoint(14.0, 17.0)
			},
			'pushpin':{
				image: imgroot + '/includes/images/shell/google/pushpin_icon:label.png',
				shadow: imgroot + '/includes/images/shell/google/default_shadow.png',
				iconSize: new GSize(29.0, 34.0),
				shadowSize: new GSize(47.0, 34.0),
				iconAnchor: new GPoint(15.0, 34.0),
				infoWindowAnchor: new GPoint(14.0, 17.0)
			},
			'custom':{
				image: imgroot + '/includes/images/shell/google/other_icon:label.png',
				shadow: imgroot + '/includes/images/shell/google/large_shadow.png',
				iconSize: new GSize(53.0, 39.0),
				shadowSize: new GSize(73.0, 39.0),
				iconAnchor: new GPoint(34.0, 39.0),
				infoWindowAnchor: new GPoint(26.0, 19.0)
			},
			'other':{
				image: imgroot + '/includes/images/shell/google/other_icon:label.png',
				shadow: imgroot + '/includes/images/shell/google/large_shadow.png',
				iconSize: new GSize(53.0, 39.0),
				shadowSize: new GSize(73.0, 39.0),
				iconAnchor: new GPoint(34.0, 39.0),
				infoWindowAnchor: new GPoint(26.0, 19.0)
			},
			
			'hotel':{
				image: imgroot + '/includes/images/shell/google/hotel_icon:label.png',
				shadow: imgroot + '/includes/images/shell/google/large_shadow.png',
				iconSize: new GSize(53.0, 39.0),
				shadowSize: new GSize(73.0, 39.0),
				iconAnchor: new GPoint(34.0, 39.0),
				infoWindowAnchor: new GPoint(26.0, 19.0)
			},
			'dining':{
				image: imgroot + '/includes/images/shell/google/dining_icon:label.png',
				shadow: imgroot + '/includes/images/shell/google/large_shadow.png',
				iconSize: new GSize(53.0, 39.0),
				shadowSize: new GSize(73.0, 39.0),
				iconAnchor: new GPoint(34.0, 39.0),
				infoWindowAnchor: new GPoint(26.0, 19.0)
			},
			'nightlife':{
				image: imgroot + '/includes/images/shell/google/nightlife_icon:label.png',
				shadow: imgroot + '/includes/images/shell/google/large_shadow.png',
				iconSize: new GSize(53.0, 39.0),
				shadowSize: new GSize(73.0, 39.0),
				iconAnchor: new GPoint(34.0, 39.0),
				infoWindowAnchor: new GPoint(26.0, 19.0)
			},
			'shopping':{
				image: imgroot + '/includes/images/shell/google/shopping_icon:label.png',
				shadow: imgroot + '/includes/images/shell/google/large_shadow.png',
				iconSize: new GSize(53.0, 39.0),
				shadowSize: new GSize(73.0, 39.0),
				iconAnchor: new GPoint(34.0, 39.0),
				infoWindowAnchor: new GPoint(26.0, 19.0)
			},
			'trans':{
				image: imgroot + '/includes/images/shell/google/trans_icon:label.png',
				shadow: imgroot + '/includes/images/shell/google/large_shadow.png',
				iconSize: new GSize(53.0, 39.0),
				shadowSize: new GSize(73.0, 39.0),
				iconAnchor: new GPoint(34.0, 39.0),
				infoWindowAnchor: new GPoint(26.0, 19.0)
			}			
		};
	}

	//Initialize Map
	this.create = function(){
		this.initCustomIcons();
		map.div = $P(divname);
		map.gmap = new GMap2(map.div);

		if(!this.cancelCentering){
			map.gmap.setCenter(map.settings.defaultPoint);
			map.gmap.setZoom(map.settings.defaultZoom);
		}

		map.control = new GSmallMapControl();
		map.gmap.addControl(map.control);
		map.typeControl  = new GMapTypeControl();
		map.gmap.addControl(map.typeControl);
		map.gmap.addMapType(G_PHYSICAL_MAP);

		//Register Map with main array
		maps[map.name] = map;
	}
	
	
	this.addCollection = function(oc,isDefault){
		this.collections[oc.name] = oc;
		if(isDefault || this.defaultCollection == null)
			this.defaultCollection = oc;
		oc.map = this;
		return oc;
	}

	//Set Current Maps Control
	this.setControl = function(control){
		if(map.settings.control)
			map.gmap.removeControl(map.settings.control);

		if(control)
			map.gmap.addControl(control);
		this.settings.control = control;
	}

	this.setCenter = function(){
		map.bounds = new GLatLngBounds();
		var p;		
		for (var i in this.collections){
			var c = this.collections[i];
			map.bounds = addBounds(map.bounds,c.calcBounds());
		}
		if(map.bounds.isEmpty()){
			p = map.settings.defaultPoint;
		}
		else{
			p = map.bounds.getCenter();
		}		
		map.gmap.setCenter(p);
	}
	
	this.getBounds = function(){
		var bounds = new GLatLngBounds();
		for (var i in this.collections){
			var c = this.collections[i];
			var cbounds = c.calcBounds();		
			bounds = addBounds(bounds,cbounds);
		}
		return bounds;
	}
	
	this.setBoundsCenterAndZoom = function(){
		map.bounds = this.getBounds();
		if(!map.bounds.isEmpty()){
			var p = map.bounds.getCenter();
			var z = map.gmap.getBoundsZoomLevel(map.bounds);
		}
		else{
			var p = map.settings.defaultPoint;
			var z = map.settings.defaultZoom;
		}
		map.gmap.setCenter(p);
		map.gmap.setZoom(z);
	}

	this.removeOverlays = function(collection){
		for(var i in collection.data){
			var p = collection.data[i];
			if(p.marker){
				map.gmap.removeOverlay(p.marker);
				delete p.marker;
			}			
		}
	}

	//Remove all placemarks from the map
	this.removePlacemarks = function(collection,cancelHandlers){
		this.removeOverlays(collection);
		collection.clearAll();
		if(!cancelHandlers)
			collection.execHandler('addremove','removeplacemarks');
	}

	this.removePlacemark = function(placemark,collection,cancelHandlers){
		if(!collection)
			collection = this.defaultCollection;

		if(placemark.marker){
			placemark.marker.closeInfoWindow();
			this.gmap.removeOverlay(placemark.marker);
		}
		collection.clear(placemark);
		if(placemark.marker)
			delete placemark.marker;
		if(!cancelHandlers){
			collection.execHandler('addremove','removeplacemark');
		}
	}

	//Add a Simple Marker
	this.addPlacemark = function(placemark,collection,cancelHandlers){
		if(!collection)
			collection = map.defaultCollection;

		//If there is no preexisting marker, create marker and add a reference in the placemark
		if(!placemark.marker){
			placemark.marker = new GMarker(placemark.point);
			placemark.marker.placemark = placemark;
		}

		collection.set(placemark);	

		if(!cancelHandlers){
			collection.execHandler('addremove','addplacemark');
		}
	}


	this.initPlacemark = function(oc,placemark){
		var labelType = oc.labelType;
		placemark.label = '';
		placemark.icon = this.createCustomIcon(oc.getIconStyle(placemark),placemark.label);
		var p = new GLatLng(placemark.latitude,placemark.longitude);
		var m = new GMarker(p,{icon:placemark.icon});
		m.placemark = placemark;
		placemark.marker = m;
		placemark.marker.myInfoHTML = oc.getInfoHTML(placemark);
		placemark.collection = oc;
	}

	this.showPlacemark = function(placemark,cancelHandlers){
		var marker = placemark.marker;
		var collection = placemark.collection;
		map.bounds.extend(marker.getPoint());
		map.gmap.addOverlay(marker);
		if(marker.myInfoHTML){
			GEvent.addListener(marker, "click", function() { 
				map.gmap.setCenter(marker.getPoint());
				marker.openInfoWindowHtml(marker.myInfoHTML);
				collection.execHandler('openinfobubble',placemark);
			});
		}
		if(!cancelHandlers)
			collection.execHandler('showhide','showplacemark');
	}

	this.showPlacemarks = function(oc,page,cancelHandlers){
		this.removeOverlays(oc);
		if(!page)
			page = 1;

		oc.currPage = page;

		var placemarks = oc.getPage(page);
		for (var i = 0; i < placemarks.length; i++){
			var labelType = oc.labelType;
			var placemark = placemarks[i];
			if(oc.useLabels){
				placemark.label = (oc.labelType == 'Alpha' ? chr(i + asc('A')) :  i + 1);
			}
			else{
				placemark.label = '';
			}
			var p = new GLatLng(placemark.latitude,placemark.longitude);
			placemark.icon = this.createCustomIcon(oc.getIconStyle(placemark),placemark.label);
			var m = new GMarker(p,{icon:placemark.icon});
			//Add Reverse Lookups
			m.placemark = placemark;
			placemark.marker = m;
			placemark.marker.myInfoHTML = oc.getInfoHTML(placemark);
			this.showPlacemark(placemark,true);
		}
		if(!this.cancelCentering){
			map.setBoundsCenterAndZoom();
		}
		if(!cancelHandlers)
			oc.execHandler('showhide','showplacemarks');
	}

	this.addPlacemarks = function(placemarks,collection,cancelHandlers){
		for (var i = 0; i < placemarks.length; i++){
			var g = placemarks[i];
			var p = new GLatLng(g.latitude,g.longitude);
			//Add Reverse Lookups
			map.addPlacemark(g,collection,true);
		}
		if(!cancelHandlers)
			collection.execHandler('addremove','addplacemarks');
	}

	this.createCustomIcon = function (style,label){
		var iconStyle = clone(this.iconStyles[style]);
		iconStyle.image = iconStyle.image.replace('icon:label',label);
		if (iconStyle.smimage) iconStyle.smimage = iconStyle.smimage.replace('icon:label',label);
		var icon = new GIcon(iconStyle);
		return icon;
	}
	
	this.registerFilter = function(name,filter){
		this.allFilters[name] = filter;
	}
	
	this.initFilters = function(){
		for(var i in this.allFilters){
			this.allFilters[i].run();
		}
	}
	
	this.getVisiblePlacemarks = function(){
		var arr = new Array();
		for (var i in this.collections){
			var p = this.collections[i].getPage(this.collections[i].currPage);
			for(var j = 0; j < p.length; j++){
				arr.push({name:p[j].name,collection:this.collections[i].name,prikey:p[j].prikey});
			}
		}
		return arr;
	}
}

/*************************************************
	General Utility Functions
**************************************************/

function addBounds(b1,b2){
	if (b1.isEmpty())
		return b2;
		
	if(b2.isEmpty())
		return b1;

	var southWest = b1.getSouthWest();  
	var northEast = b1.getNorthEast();
	var b3 = new GLatLngBounds();
	b3.extend(southWest);
	b3.extend(northEast);
	var southWest = b2.getSouthWest();  
	var northEast = b2.getNorthEast();
	b3.extend(southWest);
	b3.extend(northEast);
	return b3;
}

function placemarkDistance(p1,p2){
	return distance(parseFloat(p1.latitude),parseFloat(p1.longitude),parseFloat(p2.latitude),parseFloat(p2.longitude));
}

function distance(lat1,lon1,lat2,lon2){
	var R = 6371; // km
	var kpm = 1.609344;  //km per mile
	var dLat = (lat2-lat1).toRad();
	var dLon = (lon2-lon1).toRad(); 
	var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
			Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) * 
			Math.sin(dLon/2) * Math.sin(dLon/2); 
	var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
	var d = (R * c) / kpm;
	return d;
}

function parsePlacemarkData(str,p){
	var fieldlist = ['name','prikey','weburl','addr1','addr2','city','state','zip'];
	for (var i = 0; i < fieldlist.length; i++){
		var searchstr = 'placemark:' + fieldlist[i];
		var replacewith = String(p[fieldlist[i]]).substr(0,300);
		while (str.indexOf(searchstr) > 0 && searchstr != replacewith){
			str = str.replace(searchstr,replacewith);
		}
	}
	

	var searchstr = 'placemark:description';
	if(p.description.length > 0){
		var replacewith = p.description;
	}
	else
		var replacewith = '*No Description Available*';

		while (str.indexOf(searchstr) > 0 && searchstr != replacewith){
			str = str.replace(searchstr,replacewith);
		}


	
	if(p.logofile){
		str = str.replace('placemark:logofile', p.logofile.length > 0 ? p.logofile  : 'notavailable.gif');
	}
	else
		str = str.replace('placemark:logofile', 'notavailable.gif');
	
	//Only available when the marker is visible on the map
	if(p.icon){
		str = str.replace('placemark:iconimage',p.icon.image);
		str = str.replace('placemark:sm_iconimage',p.icon.smimage);
	}
	if(p.distance){
		str = str.replace('placemark:distance',p.distance.toFixed(2));
	}
	
	if(p.itinerary == true){
		str = str.replace('placemark:itinerary','<b class="itin_added">Added to MyTucson</b>');
	}
	else
		str = str.replace('placemark:itinerary','<a href=\"javascript:void(itin_add(' + p.prikey + ', \'cbListing\',' + p.catid + '));\">Add to MyTucson</a>');
	
	if (p.weburl.length > 0)
		str = str.replace('placemark:website_redirect', '<a href=\"' + imgroot + '/includes/redirects/webcount.cfm?listingID=' + String(p.prikey) + '\" target=\"_blank\">Visit Website</a><br>');
	else
		str = str.replace('placemark:website_redirect', '');
		
	var addr = new Address();
	try{
		addr.loadFromObject(p);
		str = str.replace('placemark:address',addr.toHTMLString());
	}
	catch(ex){
		alert(ex);
	}


	return str;
}

function chr(num){
	return String.fromCharCode(num);
}

function asc(str){
	return str.charCodeAt(0);
}

function clone(obj){
    if(obj == null || typeof(obj) != 'object')
        return obj;

    var temp = new obj.constructor(); // changed (twice)
    for(var key in obj)
        temp[key] = clone(obj[key]);

    return temp;
}

Number.prototype.toRad = function() {  // convert degrees to radians
  return this * Math.PI / 180;
}

//Itinerary Add Function
/*function itin_add(listingid)
{
	var thisUrl  =  imgroot+'/mytucsonadd/index.cfm';
	var thisData = 'action=ajax_addItin&listingid='+listingid; 

	new Ajax.Request(thisUrl,
		{
			method: 'post',
			parameters: thisData,
			onSuccess: function (response){
					updatePlacemarkItinerary(listingid);
					return true;
				},
		   onFailure: function(response){
			   alert('Could not add to MyTucson');
		   }
		}
	);
}*/

//Itinerary Function
function updatePlacemarkItinerary(prikey){
	for (var i in placemarks){
		var p = findPlacemark(i,prikey);
		if(p != null){
			jQuery("#placemark_itinerary_" + prikey).html("Added to MyTucson").css({fontWeight: "bold"});
			p.itinerary = true;
			if(p.marker && p.collection){
				p.marker.myInfoHTML = p.collection.getInfoHTML(p);
			}
		}
	}
	//transferFromOverlays(prikey,itineraryOverlays);
	//goToPlacemark(prikey);
}

function itin_add(listingID,x, categoryId)
{
	GB_showCenter("MyTucson", "../../../MyTucsonAdd/index.cfm?action=AddListing&gb=1&CategoryID=" + categoryId + "&ListingID=" + listingID, 586, 604);
}