//save a lot of typing
getEl = function(id){
return document.getElementById(id);
}
//getElC = function(class,node,tag){
//return getElementsByClass(class,node,tag);
//}

var MapSystem = function(oConfig){
	this._debug = false;
	this._elTrace = null;
	this._elMapElement = null;
	this._oMap = null; 
	this._oMarkers = new Object();
	this._aryLocations = new Array();
	this._aryControls = null;
	this._oCurView = null;
	this._numLastID = 1000;
	this._strIDPre = 'MapS'
	this._icons = null;
	this._elDirections = null;
	var requiredelements = 0
	for(i in oConfig){
		switch(i){
			case 'elMapElement':
				this._elMapElement = oConfig[i];
				requiredelements++;
				break;
			case 'elTrace':
				this._elTrace = oConfig[i];
				break;
			case 'debug':
				this._debug = oConfig[i];
				break;
			case 'startingView':
				requiredelements++;
				this._oCurView = oConfig[i];
				break;
			case 'controls':
				this._aryControls = oConfig[i];
				break;
			case 'IDPrefix':
				this._strIDPre = oConfig[i];
				break;
			case 'icons':
				this._icons = oConfig[i];
				break;
			case 'elDirections':
				this._elDirections = oConfig[i];
				break;
			default:
				break;
		}
	}
	if(requiredelements == 2){
		this._doSetup();
	}else{
		alert("Not enough data to generate map");
	}
}

/*MapSystem.prototype.MapSystem = function(oConfig){
}*/
MapSystem.prototype.setTraceElement= function(el){
	this._elTrace = el;
}
MapSystem.prototype.trace = function(strMsg){
	if(this._debug){
		this._elTrace.innerHTML += strMsg+"<br />";
	}
}
MapSystem.prototype._doSetup = function(){
	this._oMap = new GMap2(this._elMapElement);
	this._oMap.MapSystem = this;
	if(this._oCurView != null){
		this._oMap.setCenter(this._oCurView.latlng, this._oCurView.zoom);
	}
	if(this._aryControls != null){
		for(i in this._aryControls){
			this._oMap.addControl(this._aryControls[i]);
		}
	}
	map = this._oMap
	getPop = this.getPopUp
	//this.trace(typeof getPop);
	GEvent.addListener(map,"click",getPop);
}
//required format for XML document
/*
<containerElement>
<element class="location">
<element class="data">## delim list </element>
<element class="description">HTML for pop window</element>
</element>
<element class="location">
<element class="data">## delim list </element>
<element class="description">HTML for pop window</element>
</element>
</containerElement>
*/
MapSystem.prototype.loadSetFromXML = function(args){
	var elements = getElementsByClass('location',args['el'],null);
	//this.trace(elements.length);
	var conut = 0;
	var latAvg = 0;
	var latMax = null;
	var latMin = null;
	var lngAvg = 0;
	var lngMax = null;
	var lngMin = null;
		for(i in elements){
			strNewID = this._strIDPre+this._numLastID
			elements[i].id = strNewID
			this._numLastID++;
			aryData = getElementsByClass('data',elements[i],null);
			for(j in aryData){
				oData = this.parseLoc(aryData[j].firstChild.nodeValue);
				
				conut++;
				latAvg += parseFloat(oData.lat);
				lngAvg += parseFloat(oData.lng);
				
				latMax == null? latMax = oData.lat : latMax = latMax;
				latMax < oData.lat ? latMax = oData.lat : latMax = latMax;
				latMin == null? latMin = oData.lat : latMin = latMin; 
				latMin > oData.lat ? latMin = oData.lat : latMin = latMin;
				
				lngMax == null? lngMax = oData.lng : lngMax = lngMax;
				lngMax < oData.lng ? lngMax = oData.lng : lngMax = lngMax;
				lngMin == null? lngMin = oData.lng : lngMin = lngMin; 
				lngMin > oData.lng ? lngMin = oData.lng : lngMin = lngMin;
			
				if(oData.icon == undefined || this._icons == null){
					//this.trace('No Icon');
					marker = new GMarker(new GLatLng(oData.lat,oData.lng))
				}else{
					//this.trace('Has an Icon '+oData.icon);
					marker = new GMarker(new GLatLng(oData.lat,oData.lng),this._icons[oData.icon]);
				}
			
			marker.mapSystemID = strNewID;
			//this.trace(oData.strAddress);
			marker.strAddress = oData.strAddress;
			funcPop = this.getPopUp;
			GEvent.addListener(this,"click",funcPop);
			
			this._oMap.addOverlay(marker);
			this._oMarkers[strNewID] = marker;
			marker = null;
		}
	}
	//this.trace(lngMin+","+lngMax+","+latMax+","+latMin+","+j);
	// please note this only works in the north west hemispher
	this.trace(parseFloat(lngMax));
	this.trace(lngMin+","+lngMax+","+latMax+","+latMin+","+j);
	this.trace(lngMin+","+lngMax+","+latMax+","+latMin+","+j);
	var bounds = new GLatLngBounds(new GLatLng(latMin,lngMax),new GLatLng(latMax,lngMin));
	var zoom = this._oMap.getBoundsZoomLevel(bounds);
	//this.trace(zoom);
	var center = new GLatLng(latMax-((latMax-latMin)/2),lngMax-((lngMax-lngMin)/2));
	//this.trace(center.lat()+" "+center.lng());
	if(args['zoom'] != undefined){
		this.trace("zoom"+args['zoom']);
		if(args['zoom'].indexOf('+') > -1){
			zoom += parseInt(args['zoom'])
			this.trace("+"+parseInt(args['zoom']));
		}else if(args['zoom'].indexOf('-') > -1){
			zoom += parseInt(args['zoom'])
			this.trace("-"+parseInt(args['zoom']));
		}else{
			zoom = parseInt(args['zoom']);
			this.trace("set"+parseInt(args['zoom']));
		}
	}
	this.trace("Z"+zoom);
	if(args['center'] != undefined){
		center = args['center'];
	}
	this._oMap.setCenter(center,zoom);
this.trace("lat:"+center.lat()+",<br />lng:"+center.lng());
	//this._oMap.panTo(center);
	if(typeof args['callback'] == "function"){
		args['callback'](args['el']);
	}
}

MapSystem.prototype.getPopUp = function(marker,point,callback){
	//this.MapSystem.trace("Pop Called");
	//this.MapSystem.trace(marker.mapSystemID);
	if(marker != undefined){
		if(this.MapSystem){
			me = this.MapSystem;
		}else{
			me = this;
		}
		elLocation = getEl(marker.mapSystemID);
		elDescription = getElementsByClass("description",elLocation);
		elPopup = elDescription[0].cloneNode(elDescription[0]);
		els = elPopup.getElementsByTagName('*');
		for(i in els){
			//me.trace("bob"+i);
			if(els[i].className == 'mappingPopup'){
				els[i].style.display = "block";
			}
		}
		if(me._elDirections != null){
			elDirections = me._elDirections.cloneNode(me._elDirections)
			
			elDirections.innerHTML = elDirections.innerHTML.replace(/##address##/g,marker.strAddress)
			elDirections.style.display = "block";
			//me.trace(elDirections.innerHTML);
			//me.trace(marker.strAddress);
			elPopup.appendChild(elDirections);
			elDirections  = null;
		}
		marker.openInfoWindowHtml(elPopup.innerHTML)
	}
	if(typeof callback == "function"){
		callback(marker);
	}

}
MapSystem.prototype.parseLoc = function(strLoc){
	oReturn = new Object();
	oReturn.lat = null;
	oReturn.lng = null;
	oReturn.strAddress = null;
	aryLoc = strLoc.split('##');
	for(i= 0; i < aryLoc.length; i++){
		switch(aryLoc[i]){
			case "lat":
				oReturn.lat = aryLoc[i+1];
				i++;
				break;
			case "lng":
				oReturn.lng = aryLoc[i+1];
				i++;
				break;
			case "address":
				oReturn.strAddress = aryLoc[i+1];
				i++;
				break;
			default:
				oReturn[aryLoc[i]] = aryLoc[i+1];
				i++;
				break;
		}
	}
	return oReturn;
}
MapSystem.prototype.getMarker = function(id){
	return this._oMarkers[id];
}
MapSystem.prototype.clearMarkers = function(){
	this._oMarkers = null;
	this._oMarkers = new Object();
	this._oMap.clearOverlays();
}
MapSystem.prototype.getCenter = function(){
	ll = this._oMap.getCenter()
	this.trace(ll.lat()+" , "+ll.lng());
}
MapSystem.prototype.getDirections = function(loc){
	targetUrl = "http://maps.google.com/maps?f=li&daddr="+loc.from+"&saddr="+loc.to
	window.open(targetUrl,'directionsWindow');
}
	/* this code can help find cenert and zoom
	b = new GLatLngBounds(new GLatLng(39.9985,-79.89548),new GLatLng(40.861239,-78.3247));
	z = mapS._oMap.getBoundsZoomLevel(b)
	mapS.trace(z);
	mapS._oMap.setCenter(new GLatLng(40.4298695,-79.11009),z);
	*/
