/*
 Custom class for a location
*/
gmap.Location = (function(){
	
	var Location=function(opts, onLoad){
		var I = this;
		j.extend(I, I.defaults, opts);
		if(onLoad!=null) I.onLoad=onLoad;
		I.init();		
	}
	
	Location.prototype={
		defaults:{
			name:"", //String
			address:"", //String
			category:"", //String 
			subCategories:"", //String - comma delimeted list of sub categories
			url:"",
			content:"",
			marker:null, //GMarker
			point:null, //GLatLng - http://code.google.com/apis/maps/documentation/reference.html#GLatLng
			geocode:null, //CSV geocode retrived from http://maps.google.com/maps/geo (http://code.google.com/apis/maps/documentation/geocoding/index.html)
			siblings:[], // Array - getPoint() tests gmap.location for other matching addresses and adds them to this list
			siblingCatsMustMatch:true, //Boolean - used in getSiblings(). if true, only allows siblings that have same category
			siblingRadius:10, //int - maximum meters another location can be to be qualified as a sibling		
			loaded:false, //Boolean - indicates whether the point has been loaded
			expandMap:false, //Boolean - determines whether the map's viewable area should be expanded 
			showOnLoad:true // Boolean - determines whether the marker will be shown when it is loaded
		},
		//get the lat/lng point based on the geocode or address
		getPoint:function(){
			var I = this;
			//check for geocode, finally, use gmap.geocoder to find address
				
			if(I.geocode!=null){
				var geocode = I.geocode.split(",");
				if(geocode[0]=="200"){
					var lat = geocode[2];
					var lng = geocode[3];					
					I.setMarker(new GLatLng(geocode[2], geocode[3]));					
				}else if(geocode[0]=="620"){
					//try again if serverside geocode response was "too many requests"
					I.geocode=null;
					I.getPoint();	
				}
				
			}else{
				//geocode the address
				trace("Geocoding "+I.address);
				gmap.geocoder.getLatLng(I.address, function(point){I.setMarker(point)});		
			}	
		},
		setMarker:function(point){
			var I = this;
			//handle the marker
			if(!point){
				trace("Could not find lat/lng for "+I.address);
				I._onLoad(false);
			}else{
				
				//set the location's point
				I.point = point;	
				
				//if the address is not in view, expand the viewport (if specified)
				if(!gmap.bounds().containsLatLng(I.point) && I.expandMap){
					var newBounds = gmap.bounds();
					newBounds.extend(I.point);
					gmap.setBounds(newBounds);
				}				
				
				//get siblings
				I.getSiblings();			
				//create the content
				I.setContent();
				//set the marker				
				if(I.siblingCatsMatch()){
					I.marker = new gmap.Marker(point, {category:I.category, hide:true});
				}else{
					I.marker = new gmap.Marker(point, {hide:true});
			    }	
				
				gmap.map.addOverlay(I.marker);	
				
				//replace sibling markers				
				for(var s=0; s < I.siblings.length; s++){
					var sibling = I.siblings[s];
					gmap.map.removeOverlay(sibling.marker);
					sibling.marker = I.marker;
					if(sibling.marker.window) sibling.marker.window.kill();
				}
				//trace(I.name+" has "+ I.siblings.length +" siblings.");
				
				//I.marker.window = new gmap.MarkerWindow({marker:I.marker});
				I.marker.window.refresh();
				
				I._onLoad(true);
			}		
			
		},
		setContent:function(){
			var I = this;
			//create content for gmap.MarkerWindow
			I.content = document.createElement("div");
			I.content.className="location-info "+I.category.toLowerCase()+"-info";
			var contentHtml = "<h5>"+I.name+"</h5><p>"+I.address;
			if(gmap.type=="full") contentHtml += "<br/><a href='"+I.url+"'>View Detail Page</a>";			
			contentHtml += "</p>";
			I.content.innerHTML = contentHtml;
			
		},
		//test if the sibling categories match
		siblingCatsMatch:function(){		
			var I = this;
			for(var s=0; s<I.siblings.length; s++){
				if(I.siblings[s].category!=I.category){
					return false;
				}
			}
			return true;
		},		
		getSiblings:function(){
			var I = this;
			I.siblings=[];
			for(var s=0; s<gmap.locations.length; s++){
				var location = gmap.locations[s];
				if(I.point!=null && location.point!=null && (!I.siblingCatsMustMatch || location.category==I.category)){
					try{
						if(I.point.distanceFrom(location.point) <= I.siblingRadius && location!=I){
							I.siblings.push(location);
						}	
					}catch(err){
						console.log(location);
						console.log(err);	
					}
				}
			}
			return I.siblings;
		},
		init:function(){
			var I = this;
			//add to map locations list
			gmap.locations.push(I);
			//get the lat/lng and create marker, content, etc, trigger load event
			
			I.getPoint();			
		},
		onLoad:function(evt, success){},
		_onLoad:function(success){
			var I = this;
			if(!I.showOnLoad){
				if(I.marker) I.marker.hide();
				if(I.content) I.content.style.display="none";
			}else{
				if(I.marker) I.marker.show();
				if(I.content) I.content.style.display="block";
			}
			
			//set the point loaded indicator
			I.loaded=true;
			//exec onLoad parameter
			if(typeof(I.onLoad=="function")){
				I.onLoad({type:"gmap.Location.load", target:I}, success);
			}
			//trigger loaded event
			j(I).trigger("gmap.Location.load", success);
		}
		
	};
	
	// ---- RETURN TO ENCAPSULATOR --------------------------
	return Location;
	
})();