var SJJS = {
	parent:true,
	using: function(namespace) {
		var _namespacearray = namespace.split(".");
		var x, _namespacepointer = SJJS;

		for (x = 1; x < _namespacearray.length; x++)
		{
			_namespacepointer = _namespacepointer[_namespacearray[x]];
		}
		if (!_namespacepointer.parent)
		{
			eval(_namespacearray[_namespacearray.length - 1] + " = " + namespace + ";");
		} else {
			for (x in _namespacepointer)
			{
				eval(x + " = " + namespace + "." + x + ";");
			}
		}
	},
	Utilities:{
		parent:true,
		getBodyHeight: function() {
			return window.innerHeight || (document.documentElement.clientHeight || document.body.clientHeight);
		},
		getBodyWidth: function() {
			return window.innerWidth || (document.documentElement.clientWidth || document.body.clientWidth);
		}
	},
	GMap:{
		parent:true,
		Overlays:{parent:true},
		Controls:{parent:true}
	}
};

//Color class, provides various functionality for creating and manipulating colors

SJJS.Utilities.Color = function()
{
	var me = this;
	var _r = 0;
	var _g = 0;
	var _b = 0;
	var _hex = 0;
	var _h = 0;
	var _s = 0;
	var _l = 0;

	function _d2h(d) {
		var h2r = d.toString(16).toUpperCase();
		if (h2r.length === 1) {
			h2r = "0" + h2r;
		}
		return h2r;
	}

	function _h2d(h) {return parseInt(h,16);} 

	function _RGBToHSL()
	{
		//Normalize rgb values
		var r = _r / 255;
		var g = _g / 255;
		var b = _b / 255;
	
		//Determine the minimum and maximum values from the normalized rgb values
		var min, max;
		if (r <= g && r <= b) {
			min = r;
		}
		if (g <= r && g <= b) {
			min = g;
		}
		if (b <= r && b <= g) {
			min = b;
		}
		if (r >= g && r >= b) {
			max = r;
		}
		if (g >= r && g >= b) {
			max = g;
		}
		if (b >= r && b >= g) {
			max = b;
		}
	
		//Determine the hue value
		if (max === min)
		{
			_h = 0;
		}
		else if (max === r && g >= b)
		{
			_h = 60 * ((g - b) / (max - min)) + 0;
		}
		else if (max === r && g < b)
		{
			_h = 60 * ((g - b) / (max - min)) + 360;
		}
		else if (max === g)
		{
			_h = 60 * ((b - r) / (max - min)) + 120;
		}
		else if (max === b)
		{
			_h = 60 * ((r - g) / (max - min)) + 240;
		}
	
		//Determine light value
		_l = (1/2) * (max + min);
	
		//Determine saturation
		if (max === min) {
			_s = 0.0;
		}
		else if (_l <= (1/2)) {
			_s = (max - min) / (2 * _l);
		}
		else if (_l > (1/2)) {
			_s = (max - min) / (2 - (2 * _l));
		}
	
		//Clamp hsl values to [0,1]
		if (_h > 360) {
			_h = 360;
		}
		if (_h < 0) {
			_h = 0;
		}
		if (_s > 1.0) {
			_s = 1.0;
		}
		if (_s < 0) {
			_s = 0;
		}
		if (_l > 1.0) {
			_l = 1.0;
		}
		if (_l < 0) {
			_l = 0;
		}
	}
	
	function _HexToRGB()
	{
		var hexparse = _hex.replace(/#/, "");
		var hr = hexparse.substr(0, 2);
		var hg = hexparse.substr(2, 2);
		var hb = hexparse.substr(4, 2);
	
		_r = _h2d("0x" + hr);
		_g = _h2d("0x" + hg);
		_b = _h2d("0x" + hb);
	}
	
	function _HSLToRGB()
	{
		var q;
		if (_l < 0.5)
		{
			q = _l * (1 + _s);
		}
		if (_l >= 0.5)
		{
			q = _l + _s - (_l * _s);
		}
	
		var p = 2 * _l - q;
	
		var hk = _h / 360;
	
		var colors = [];
		colors[0] = hk + (1/3);
		colors[1] = hk;
		colors[2] = hk - (1/3);
	
		for (var i = 0; i < colors.length; i++)
		{
			if (colors[i] < 0.0) {
				colors[i] += 1.0;
			}
			if (colors[i] > 1.0) {
				colors[i] -= 1.0;
			}
	
			if (colors[i] < (1/6))
			{
				colors[i] = p + ((q - p) * 6 * colors[i]);
			}
			else if (colors[i] <= (1/6) || colors[i] < (1/2))
			{
				colors[i] = q;
			}
			else if (colors[i] <= (1/2) || colors[i] < (2/3))
			{
				colors[i] = p + ((q - p) * 6 * ((2/3) - colors[i]));
			}
			else
			{
				colors[i] = p;
			}
		}
	
		_r = Math.ceil(colors[0] * 255);
		_g = Math.ceil(colors[1] * 255);
		_b = Math.ceil(colors[2] * 255);
	}

	function _RGBToHex()
	{
		var hr = _d2h(_r);
		var hg = _d2h(_g);
		var hb = _d2h(_b);
	
		if (hr.length === 0) {
			hr = "0" + hr;
		}
		if (hg.length === 0) {
			hg = "0" + hg;
		}
		if (hb.length === 0) {
			hb = "0" + hb;
		}
	
		_hex = "#" + hr + hg + hb;
	}
	
	me.setRGB = function(r, g, b)
	{
		_r = r;
		_g = g;
		_b = b;

		_RGBToHex();
		_RGBToHSL();
	};
	me.setR = function(r)
	{
		_r = r;
	
		_RGBToHex();
		_RGBToHSL();
	};
	
	me.getR = function()
	{
		return _r;
	};
	
	me.setG = function(g)
	{
		_g = g;
	
		_RGBToHex();
		_RGBToHSL();
	};
	
	me.getG = function()
	{
		return _g;
	};
	
	me.setB = function(b)
	{
		_b = b;
	
		_RGBToHex();
		_RGBToHSL();
	};
	
	me.getB = function()
	{
		return _b;
	};
	
	me.setHex = function(hex)
	{
		_hex = hex;
	
		_HexToRGB();
		_RGBToHSL();
	};
	
	me.getHex = function()
	{
		return _hex;
	};

	me.setHSL = function(h, s, l)
	{
		_h = h;
		_s = s;
		_l = l;

		_HSLToRGB();
		_RGBToHex();
	};
	
	me.setH = function(h)
	{
		_h = h;
	
		_HSLToRGB();
		_RGBToHex();
	};
	
	me.getH = function()
	{
	 	return _h;
	};
	
	me.setS = function(s)
	{
		_s = s;
	
		_HSLToRGB();
		_RGBToHex();
	};
	
	me.getS = function()
	{
		return _s;
	};
	
	me.setL = function(l)
	{
		_l = l;
	
		_HSLToRGB();
		_RGBToHex();
	};
	
	me.getL = function()
	{
		return _l;
	};
}

SJJS.Utilities.ColorFactory = {
	FromRGB:function(r, g, b)
	{
		var _returncolor = new SJJS.Utilities.Color();
		_returncolor.setRGB(r, g, b);
	
		return _returncolor;
	},
	
	FromHex:function(hex)
	{
		var returncolor = new SJJS.Utilities.Color();
		returncolor.setHex(hex);
	
		return returncolor;
	},
	
	FromHSL:function(h, s, l)
	{
		var _returncolor = new SJJS.Utilities.Color();
		_returncolor.setHSL(h, s, l);
	
		return _returncolor;
	}
};

//SJCityOverlay provides a way to add city data to the map
SJJS.GMap.Overlays.GISOverlay = function(dataurl, styleurl, descriptionurl) {
	var me = this;
	var _sjplacemarks = [];
	var _events = [];
	var _jdata, _jstyle, _map, _currenturl = dataurl;
	var _delete = false, _loading = false, _alreadydeleting = false;

	this.type = "GISOverlay";

	if (descriptionurl !== undefined && descriptionurl !== null)
	{
		if (descriptionurl.indexOf("?") !== -1) {
			descriptionurl += ";";
		} else {
			descriptionurl += "?";
		}
	}

	function objectSetTimeout_(object, argument1, command, milliseconds) {
	  return window.setTimeout(function() {
	    command.call(object, argument1);
	  }, milliseconds);
	}

	function _pusheventfunction(dindex, findex, fhandle)
	{
		//GEvent.addListener(_jdata.data[dindex].features[findex], _events[fhandle].name, _events[fhandle].eventfunction);
		_jdata.data[dindex].eventhandles[findex].push(GEvent.addListener(_jdata.data[dindex].features[findex], _events[fhandle].name, _events[fhandle].eventfunction));
	}

	function _addeventstofeatures()
	{
		var x, i, j;

		if (_jdata !== null && _jdata !== undefined)
		{
			for (x = 0; x < _jdata.data.length; x++)
			{
				for (i = 0; i < _jdata.data[x].features.length; i++)
				{
					if (_jdata.data[x].features[i] !== undefined && _jdata.data[x].features[i] !== null)
					{
						for (j = 0; j < _events.length; j++)
						{
							if (_events[j].type === _jdata.data[x].coordinates[i].type)
							{
								_pusheventfunction(x, i, j);
							}
							else if (_events[j].type === "Features") {
								_pusheventfunction(x, i, j);
							}
						}
					}
				}
			}
		}
	}

	function _removefeatures()
	{
		var x, i, j;

		_delete = true;

		if (!_loading) {
			if (_jdata !== null && _jdata !== undefined)
			{
				for (x = 0; x < _jdata.data.length; x++)
				{
					if (_jdata.data[x].features !== undefined && _jdata.data[x].features !== null)
					{
						for (i = 0; i < _jdata.data[x].features.length; i++)
						{
							if (_jdata.data[x].features[i] !== undefined && _jdata.data[x].features[i] !== null)
							{
								for (j = 0; j < _jdata.data[x].eventhandles[i].length; j++)
								{
									GEvent.removeListener(_jdata.data[x].eventhandles[i][j]);
								}
								_map.removeOverlay(_jdata.data[x].features[i]);
								GEvent.trigger(me, "featureremoved", _jdata.data[x].name, _jdata.data[x].id);
							}
						}
					}
				}
				_jdata = null;
			}
		}
	}

	function _downloadstyle(styleurl) {
		var x;

		GDownloadUrl(styleurl, function(data, responseCode) {
			_jstyle = eval( '(' + data + ')' );
	
			for (x = 0; x < _jstyle.groups.length; x++)
			{
				if (_jstyle.groups[x].color === undefined || _jstyle.groups[x].color === null)
				{
					_jstyle.groups[x].color = "#FF0000";
				}
				if (_jstyle.groups[x].highlight === undefined || _jstyle.groups[x].highlight === null)
				{
					_jstyle.groups[x].highlight = _jstyle.groups[x].color;
				}
	
				_jstyle.groups[x].color = SJJS.Utilities.ColorFactory.FromHex(_jstyle.groups[x].color);
				_jstyle.groups[x].highlight = SJJS.Utilities.ColorFactory.FromHex(_jstyle.groups[x].highlight);
	
				_jstyle.groups[x].icon = MapIconMaker.createMarkerIcon({width:10, height:20, primaryColor: _jstyle.groups[x].color.getHex(), cornerColor: _jstyle.groups[x].color.getHex(), strokeColor: "#000000"});
				_jstyle.groups[x].highlighticon = MapIconMaker.createMarkerIcon({width:10, height:20, primaryColor: _jstyle.groups[x].highlight.getHex(), cornerColor: _jstyle.groups[x].highlight.getHex(), strokeColor: "#000000"});
			}

			for (x = 0; x < _jstyle.groups.length; x++)
			{
				var imagehtml = "";
				if (_jstyle.groups[x].haspoint === true)
				{
					imagehtml += "<img src='" + MapIconMaker.createMarkerIcon({width:14, height:24, primaryColor: _jstyle.groups[x].color.getHex(), cornerColor: _jstyle.groups[x].color.getHex(), strokeColor: "#000000"}).image + "' />";
				}
				if (_jstyle.groups[x].haspolyline === true)
				{
					imagehtml += "<img src='http://chart.apis.google.com/chart?chs=14x24&cht=ls&chco=" + _jstyle.groups[x].color.getHex().replace("#", "") + "&chls=4,0,0&chd=t:0,65,45,100' />";
				}
				_jstyle.groups[x].legendicon = imagehtml;
			}

			GEvent.trigger(me, "styleloaded");

			_downloaddata(dataurl);
		});
	}
	function _parsedata(dataindex) {
		if (!_delete) {
			if (_jdata.data[dataindex] !== null && _jdata.data[dataindex] !== undefined)
			{
				for (i = 0; i < _jstyle.groups.length; i++)
				{
					if (_jstyle.groups[i].id === _jdata.data[dataindex].group) {
						_jdata.data[dataindex].groupindex = i;
					}
				}
			
				_jdata.data[dataindex].features = [];
				_jdata.data[dataindex].eventhandles = [];
			
				//_parsecoordinates(dataindex, 0);
				window.setTimeout(function() {_parsecoordinates(dataindex, 0);}, 0);
			
				//_addfeaturebyindex(dataindex);
		
				//if (dataindex + 1 < _jdata.data.length) {
					window.setTimeout(function() {_parsedata(dataindex + 1);}, 1);
					//_parsedata(dataindex + 1);
			}
			else {
				_loading = false;
	
				if(!_delete) {
					_addeventstofeatures();
					GEvent.trigger(me, "enddownload");
				} else {
					_removefeatures();
				}
			}
		}
	}
	function _parsecoordinates(dataindex, coordinateindex) {
		var j;

		if (!_delete) {
			_jdata.data[dataindex].eventhandles[coordinateindex] = [];
	
			if (_jdata.data[dataindex].coordinates[coordinateindex].type === "Point") {
				_jdata.data[dataindex].coordinates[coordinateindex].glatlng = new GLatLng(_jdata.data[dataindex].coordinates[coordinateindex].data[0].lat, _jdata.data[dataindex].coordinates[coordinateindex].data[0].lng);
				_jdata.data[dataindex].features[coordinateindex] = new GMarker(_jdata.data[dataindex].coordinates[coordinateindex].glatlng, _jstyle.groups[_jdata.data[dataindex].groupindex].icon);
				_jdata.data[dataindex].features[coordinateindex].sjextensions = {dataindex: dataindex, featureindex: coordinateindex};
			}
			if (_jdata.data[dataindex].coordinates[coordinateindex].type === "Polyline") {
				_jdata.data[dataindex].coordinates[coordinateindex].glatlng = [];
	
				for (j = 0; j < _jdata.data[dataindex].coordinates[coordinateindex].data.length; j++)
				{
					_jdata.data[dataindex].coordinates[coordinateindex].glatlng.push(new GLatLng(_jdata.data[dataindex].coordinates[coordinateindex].data[j].lat, _jdata.data[dataindex].coordinates[coordinateindex].data[j].lng));
				}
				_jdata.data[dataindex].features[coordinateindex] = new GPolyline(_jdata.data[dataindex].coordinates[coordinateindex].glatlng, _jstyle.groups[_jdata.data[dataindex].groupindex].color.getHex(), 3, 1.0);
				_jdata.data[dataindex].features[coordinateindex].sjextensions = {dataindex: dataindex, featureindex: coordinateindex};
			}
			if (coordinateindex + 1 < _jdata.data[dataindex].coordinates.length) {
				window.setTimeout(function() {_parsecoordinates(dataindex, coordinateindex + 1);}, 0);
				//_parsecoordinates(dataindex, coordinateindex + 1);
			} else {
				window.setTimeout(function() {_addfeaturebyindex(dataindex);}, 2);
			}
		}
	}
	function _downloaddata(_du) {
		var x, i, j;

		GEvent.trigger(me, "begindownload");

		GDownloadUrl(_du, function(data, responseCode) {
			if (!_delete && (_du === _currenturl)) {
				_loading = true;

				_jdata = eval( '(' + data + ')' );
		
				for (x = 0; x < _jdata.data.length; x++) {
		
					var groupnumber;
					for (i = 0; i < _jstyle.groups.length; i++)
					{
						if (_jstyle.groups[i].id === _jdata.data[x].group) {
							_jdata.data[x].groupindex = i;
						}
					}
		
					_jdata.data[x].features = [];
					_jdata.data[x].eventhandles = [];
		
					for (i = 0; i < _jdata.data[x].coordinates.length; i++)
					{
						_jdata.data[x].eventhandles[i] = [];
	
						if (_jdata.data[x].coordinates[i].type === "Point") {
							_jdata.data[x].coordinates[i].glatlng = new GLatLng(_jdata.data[x].coordinates[i].data[0].lat, _jdata.data[x].coordinates[i].data[0].lng);
							_jdata.data[x].features[i] = new GMarker(_jdata.data[x].coordinates[i].glatlng, _jstyle.groups[_jdata.data[x].groupindex].icon);
							_jdata.data[x].features[i].sjextensions = {dataindex: x, featureindex: i};
						}
						if (_jdata.data[x].coordinates[i].type === "Polyline") {
							_jdata.data[x].coordinates[i].glatlng = [];
		
							for (j = 0; j < _jdata.data[x].coordinates[i].data.length; j++)
							{
								_jdata.data[x].coordinates[i].glatlng.push(new GLatLng(_jdata.data[x].coordinates[i].data[j].lat, _jdata.data[x].coordinates[i].data[j].lng));
							}
							_jdata.data[x].features[i] = new GPolyline(_jdata.data[x].coordinates[i].glatlng, _jstyle.groups[_jdata.data[x].groupindex].color.getHex(), 3, 1.0);
							_jdata.data[x].features[i].sjextensions = {dataindex: x, featureindex: i};
						}
						if (_jdata.data[x].coordinates[i].type === "Polygon") {
							_jdata.data[x].coordinates[i].glatlng = [];
		
							for (j = 0; j < _jdata.data[x].coordinates[i].data.length; j++)
							{
								_jdata.data[x].coordinates[i].glatlng.push(new GLatLng(_jdata.data[x].coordinates[i].data[j].lat, _jdata.data[x].coordinates[i].data[j].lng));
							}
							_jdata.data[x].features[i] = new GPolygon(_jdata.data[x].coordinates[i].glatlng, _jstyle.groups[_jdata.data[x].groupindex].color.getHex(), 3, 1.0, _jstyle.groups[_jdata.data[x].groupindex].color.getHex(), .1);
							_jdata.data[x].features[i].sjextensions = {dataindex: x, featureindex: i};
						}

						_map.addOverlay(_jdata.data[x].features[i]);
						GEvent.trigger(me, "featureadded", _jdata.data[x].name, _jdata.data[x].id);
					}
		
					//_addfeaturebyindex(x);
				}

				for (x = 0; x < _jdata.data.length; x++)
				{
					for (i = 0; i < _jdata.data[x].features.length; i++)
					{
						if (_jdata.data[x].features[i] !== undefined && _jdata.data[x].features[i] !== null)
						{
							for (j = 0; j < _events.length; j++)
							{
								if (_events[j].type === _jdata.data[x].coordinates[i].type)
								{
									_pusheventfunction(x, i, j);
								}
								else if (_events[j].type === "Features") {
									_pusheventfunction(x, i, j);
								}
							}
						}
					}
				}

				GEvent.trigger(me, "enddownload");
				//_parsedata(0);
			}
		});
	}

	function _addfeaturebyindex(index) {
		var x;
		if (!_delete) {
			for (x = 0; x < _jdata.data[index].coordinates.length; x++)
			{
				//if (_jdata.data[index].features[x] === undefined || _jdata.data[index].features[x] === null)
				//{
					//if (_jdata.data[index].coordinates[x].type === "Point") {
						//_jdata.data[index].features[x] = new GMarker(_jdata.data[index].coordinates[x].glatlng, _jstyle.groups[_jdata.data[index].groupindex].icon);
						objectSetTimeout_(_map, _jdata.data[index].features[x], _map.addOverlay, 0);
						GEvent.trigger(me, "featureadded", _jdata.data[index].name, _jdata.data[index].id);
					//}
				//}
			}
		}
	}

	function _removefeaturebyindex(index) {
		var x;
		for (x = 0; x < _jdata.data[index].coordinates.length; x++)
		{
			//if (_jdata.data[index].features[x] !== undefined && _jdata.data[index].features[x] !== null)
			//{
				_map.removeOverlay(_jdata.data[index].features[x]);
				//_jdata.data[index].features[x] = null;
				GEvent.trigger(me, "featureremoved", _jdata.data[index].name, _jdata.data[index].id);
			//}
		}
	}

	function _pusheventfunctiontofeatures(fhandle)
	{
		var x, i;
		
		
		if (_jdata !== null && _jdata !== undefined)
		{
			for (x = 0; x < _jdata.data.length; x++)
			{
				for (i = 0; i < _jdata.data[x].features.length; i++)
				{
					if (_jdata.data[x].features[i] !== undefined && _jdata.data[x].features[i] !== null)
					{
						if (_events[fhandle].type === _jdata.data[x].coordinates[i].type)
						{
							_pusheventfunction(x, i, fhandle);
						}
						else if (_events[fhandle].type === "Features") {
							_pusheventfunction(x, i, fhandle);
						}
					}
				}
			}
		}
	}

	me.getColor = function(index) {
		//Return copy so user can't change returned color inadvertently
		var _returncolor = Color.FromHex(_jstyle.groups[_jdata.data[index].groupindex].color.getHex());
		return _returncolor;
	};

	me.setColor = function(index, color) {
		//Work from copy of color so user can't inadvertently change reference after setting color
		var _tempcolor = Color.FromHex(color.getHex());
		_jstyle.groups[_jdata.data[index].groupindex].color = _tempcolor;
	};
	
	me.ShowGroup = function(groupname) {
		var x;
		for (x = 0; x < _jdata.data.length; x++)
		{
			if (_jdata.data[x].group === groupname) {
				_addfeaturebyindex(x);
			}
		}
	};
	
	me.RemoveGroup = function(groupname) {
		var x;
		for (x = 0; x < _jdata.data.length; x++)
		{
			if (_jdata.data[x].group === groupname) {
				_removefeaturebyindex(x);
			}
		}
	};

	me.getFeatureName = function(feature) {
		if (feature.sjextensions !== undefined && feature.sjextensions !== null)
		{
			return _jdata.data[feature.sjextensions.dataindex].name;
		}
	};

	me.getFeatureColor = function(feature) {
		if (feature.sjextensions !== undefined && feature.sjextensions !== null)
		{
			var _returncolor = SJJS.Utilities.ColorFactory.FromHex(_jstyle.groups[_jdata.data[feature.sjextensions.dataindex].groupindex].color.getHex());
			return _returncolor;
		}
	};

	me.getFeatureHighlightColor = function(feature) {
		if (feature.sjextensions !== undefined && feature.sjextensions !== null)
		{
			var _returncolor = SJJS.Utilities.ColorFactory.FromHex(_jstyle.groups[_jdata.data[feature.sjextensions.dataindex].groupindex].highlight.getHex());
			return _returncolor;
		}
	};

	me.setFeatureColor = function(feature, color) {
		if (feature.sjextensions !== undefined && feature.sjextensions !== null)
		{
			var _tempcolor = Color.FromHex(color.getHex());
			_jdata.data[feature.sjextensions.dataindex].features[feature.sjextensions.feature].color = _tempcolor;
		}
	};

	me.setFeatureHighlightColor = function(feature, color) {
		if (feature.sjextensions !== undefined && feature.sjextensions !== null)
		{
			var _tempcolor = Color.FromHex(color.getHex());
			_jdata.data[feature.sjextensions.dataindex].features[feature.sjextensions.feature].highlight = _tempcolor;
		}
	};

	me.highlightFeature = function(feature, highlight) {
		if (_jdata.data[feature.sjextensions.dataindex].coordinates[feature.sjextensions.featureindex].type === "Point")
		{
			if (highlight) {
				feature.setImage(_jstyle.groups[_jdata.data[feature.sjextensions.dataindex].groupindex].highlighticon.image);
			}
			else {
				feature.setImage(_jstyle.groups[_jdata.data[feature.sjextensions.dataindex].groupindex].icon.image);
			}
		}
		if (_jdata.data[feature.sjextensions.dataindex].coordinates[feature.sjextensions.featureindex].type === "Polyline")
		{
			if (highlight) {
				feature.setStrokeStyle({color:_jstyle.groups[_jdata.data[feature.sjextensions.dataindex].groupindex].highlight.getHex()});
			}
			else {
				feature.setStrokeStyle({color:_jstyle.groups[_jdata.data[feature.sjextensions.dataindex].groupindex].color.getHex()});
			}
		}
	};

	me.getFeaturesByName = function(name) {
		var x, i;
		var _returnarray = [];

		for (x = 0; x < _jdata.data.length; x++)
		{
			if (_jdata.data[x].name === name) {
				for (i = 0; i < _jdata.data[x].features.length; i++)
				{
					_returnarray.push(_jdata.data[x].features[i]);
				}
			}
		}

		return _returnarray;
	};
	
	me.getGroupNames = function() {
		var x;
		var _namearray = [];
	
		for (x = 0; x < _jstyle.groups.length; x++)
		{
			_namearray.push(_jstyle.groups[x].id);
		}
	
		return _namearray;
	};
	
	me.getMarkerNames = function() {
		var x;
		var _namearray = [];

		for (x = 0; x < _jdata.data.length; x++)
		{
			_namearray.push(_jdata.data[x].name);
		}
	
		return _namearray;
	};
	
	me.getLegendIcon = function(groupname) {
		var x;
		for (x = 0; x < _jstyle.groups.length; x++)
		{
			if (_jstyle.groups[x].id === groupname) {
				return _jstyle.groups[x].legendicon;
			}
		}
	};

	me.addEventToMarkers = function(eventname, eventfunction) {
		var _returnhandler;

		_events.push({type:"Point", eventfunction:eventfunction, name:eventname});
		_returnhandler = _events.length - 1;

		_pusheventfunctiontofeatures(_returnhandler);
	};

	me.addEventToPolylines = function(eventname, eventfunction) {
		var _returnhandler;

		_events.push({type:"Polyline", eventfunction:eventfunction, name:eventname});
		_returnhandler = _events.length - 1;

		_pusheventfunctiontofeatures(_returnhandler);
	};

	me.addEventToFeatures = function(eventname, eventfunction) {
		var _returnhandler;

		_events.push({type:"Features", eventfunction:eventfunction, name:eventname});
		_returnhandler = _events.length - 1;

		_pusheventfunctiontofeatures(_returnhandler);
	};

	me.changeData = function(newdataurl) {
		_currenturl = newdataurl
		_delete = true;
		_loading = false;
		_removefeatures();
		window.setTimeout(function() {
			_delete = false;
			_downloaddata(newdataurl);
		}, 20);
	};
	
	me.initialize = function(map) {
		_delete = false;
		_loading = true;

		var _tempscript = document.createElement("script");

		_map = map;

		_tempscript.src = "http://gmaps-utility-library.googlecode.com/svn/trunk/mapiconmaker/release/src/mapiconmaker.js";
		_tempscript.type = "text/javascript";
		document.getElementsByTagName("head")[0].appendChild(_tempscript);

		if (descriptionurl !== undefined && descriptionurl !== null)
		{
			me.addEventToFeatures("click", function(latlng) {
				GDownloadUrl(descriptionurl + "featureid=" + _jdata.data[this.sjextensions.dataindex].id, function(data, responseCode) {
					var _jdescription = eval( '(' + data + ')' );
					_map.openInfoWindowHtml(latlng, _jdescription.description[0].data, {maxWidth:250});
				});
			});
		}
		me.addEventToFeatures("mouseover", function(latlng) {
			me.highlightFeature(this, true);
		});
		me.addEventToFeatures("mouseout", function(latlng) {
			me.highlightFeature(this, false);
		});

		_downloadstyle(styleurl);
	};
	
	me.remove = function() {
		_delete = true;
		_loading = false;
		window.setTimeout(_removefeatures, 0);
	};
	
	me.copy = function() {
		return new SJJS.GMap.Overlays.GISOverlay(me.url_, me.type);
	};
	
	me.redraw = function(force) {
		if (!force) {
			return;
		}
	};
}

SJJS.GMap.Overlays.GISOverlay.prototype = new GOverlay();

//Window

SJJS.GMap.Controls.GWindow = function(windowoptions) {
	var me = this;

	var _container = document.createElement("div");
	var _titlebar = document.createElement("div");
	var _close = document.createElement("div");
	var _title = document.createElement("span");
	var _window = document.createElement("div");

	if (windowoptions.titlebackgroundcolor === undefined || windowoptions.titlebackgroundcolor === null) {
		windowoptions.titlebackgroundcolor = "#7AA9DD";
	}
	if (windowoptions.titlecolor === undefined || windowoptions.titlecolor === null) {
		windowoptions.titlecolor = "#FFFFFF";
	}
	if (windowoptions.width === undefined || windowoptions.width === null) {
		windowoptions.width = 200;
	}
	if (windowoptions.height === undefined || windowoptions.height === null) {
		windowoptions.height = 200;
	}
	if (windowoptions.hidden === undefined || windowoptions.hidden === null) {
		windowoptions.hidden = false;
	}
	if (windowoptions.border === undefined || windowoptions.border === null) {
		windowoptions.border = "1px solid black";
	}
	if (windowoptions.top === undefined || windowoptions.top === null) {
		windowoptions.top = ((SJJS.Utilities.getBodyHeight() / 2) - 10);
	}
	if (windowoptions.left === undefined || windowoptions.left === null) {
		windowoptions.left = ((SJJS.Utilities.getBodyWidth() / 2) - (windowoptions.width / 2));
	}

	var _hidden = windowoptions.hidden;

	_titlebar.style.borderTop = windowoptions.border;
	_titlebar.style.borderLeft = windowoptions.border;
	_titlebar.style.borderRight = windowoptions.border;
	_titlebar.style.padding = "0px 7px 0px 7px";
	_titlebar.style.position = "absolute";
	_titlebar.style.left = windowoptions.left + "px";
	_titlebar.style.top = windowoptions.top + "px";
	_titlebar.style.width = windowoptions.width + "px";
	_titlebar.style.height = "20px";
	_titlebar.style.backgroundColor = windowoptions.titlebackgroundcolor;
	_titlebar.style.color = windowoptions.titlecolor;
	if (windowoptions.title !== undefined && windowoptions.title !== null) {
		_title.innerHTML = windowoptions.title;
	}
	_title.style.cssFloat = "left";
	_titlebar.appendChild(_title);
	_container.appendChild(_titlebar);

	_close.innerHTML = "X";
	_close.style.width = "10px";
	_close.style.height = "20px";
	_close.style.position = "absolute";
	_close.style.top = _titlebar.style.top;
	_close.style.left = (windowoptions.left + (windowoptions.width - 3)) + "px";
	_close.style.cursor = "pointer";
	_close.style.cssFloat = "right";
	_close.style.color = windowoptions.titlecolor;
	_container.appendChild(_close);

	_window.style.height = windowoptions.height + "px";
	_window.style.position = "absolute";
	_window.style.borderBottom = windowoptions.border;
	_window.style.borderLeft = windowoptions.border;
	_window.style.borderRight = windowoptions.border;
	_window.style.left = windowoptions.left + "px";
	_window.style.top = (windowoptions.top + 20) + "px";
	_window.style.width = windowoptions.width + "px";
	_window.style.backgroundColor = "#FFFFFF";
	_window.style.padding = "0px 7px 0px 7px";
	if (windowoptions.backgroundrepeat !== undefined && windowoptions.backgroundrepeat !== null) {
		_window.style.backgroundRepeat = windowoptions.backgroundrepeat;
	}
	if (windowoptions.backgroundposition !== undefined && windowoptions.backgroundposition !== null) {
		_window.style.backgroundPosition = windowoptions.backgroundposition;
	}
	if (windowoptions.backgroundimage !== undefined && windowoptions.backgroundimage !== null) {
		_window.style.backgroundImage = windowoptions.backgroundimage;
	}

	_container.appendChild(_window);

	document.getElementsByTagName("body")[0].appendChild(_container);

	var _drag = new GDraggableObject(_titlebar);

	GEvent.addListener(_drag, "drag", function() {
		_window.style.top = (_drag.top + 20) + "px";
		_window.style.left = _drag.left + "px";
		_close.style.top = _titlebar.style.top;
		_close.style.left = (_drag.left + (windowoptions.width - 3)) + "px";
	});

	me.hide = function() {
		_titlebar.style.visibility = "hidden";
		_window.style.visibility = "hidden";
		_close.style.visibility = "hidden";
		_hidden = true;
	};
	me.show = function() {
		_titlebar.style.visibility = "visible";
		_window.style.visibility = "visible";
		_close.style.visibility = "visible";
		_hidden = false;
	};
	me.isHidden = function() {
		return _hidden;
	};

	GEvent.addDomListener(_close, "click", function() {
		me.hide();
	});

	if (_hidden) {
		me.hide();
	} else {
		me.show();
	}

	me.addContentDom = function(domcontent) {
		_window.appendChild(domcontent);
	};
	me.addContentHtml = function(htmlcontent) {
		_window.innerHTML = htmlcontent;
	};
};

//LabelOverlay class provides a way to display the name of the marker when hovered over
SJJS.GMap.Controls.Label = function(name, latlng) {
	var me = this;
	var _map;
	var _div = document.createElement("div");
	
	me.initialize = function(map) {
		_map = map;

		_div.style.border = "1px solid black";
		_div.style.position = "absolute";
		//_div.style.height = "50px";
		_div.style.width = "150px";
		_div.style.color = "#003366";
		_div.style.fontFamily = "Arial";
		_div.style.fontSize = "7pt";
		_div.style.textAlign = "center";
		_div.style.backgroundImage = "url('http://www.sanjoseca.gov/images/leftnav_bg.gif')";
		_div.innerHTML = "<table style='width:100%;height:100%;'><tr><td valign='center' align='center'><span style='font-size:9pt;'>" + name + "</span></td></tr></table>";
	
		map.getPane(G_MAP_FLOAT_PANE).appendChild(_div);
	};
	
	me.remove = function() {
		_div.parentNode.removeChild(_div);
		_div = null;
	};
	
	me.copy = function() {
		return new LabelOverlay(name, latlng);
	};
	
	me.redraw = function(force) {
		if (!force) {
			return;
		}
	
		_div.style.left = (_map.fromLatLngToDivPixel(latlng).x + 7) + "px";
		_div.style.top = (_map.fromLatLngToDivPixel(latlng).y - 80) + "px";
	};
};

SJJS.GMap.Controls.Label.prototype = new GOverlay();

//Legend provides a legend for the map

SJJS.GMap.Controls.GLegend = function(title, legendwidth) {
	var me = this;
	var _container = document.createElement("div");
	var _legenddiv = document.createElement("div");
	var _newtable = document.createElement("table");
	var _newtablebody = document.createElement("tbody");
	var _entries = [];
	var _titlespan = document.createElement("div");

	this.type = "GLegend";
	
	this.AddEntry = function(id, entry)
	{
		_entries[id] = {iconhtml: entry.iconhtml, name: entry.name, hascheck: entry.hascheck, checked: entry.hascheck};
		//entry (iconhtml, name, hascheck, checked)
		_entries[id].newrow = document.createElement("tr");
		_entries[id].newselectcol = document.createElement("td");
		_entries[id].newimagecol = document.createElement("td");
		_entries[id].newnamecol = document.createElement("td");
	
		_entries[id].newrow.style.width = "100%";
		if (_entries[id].hascheck) {
			_entries[id].newcheck = document.createElement("input");
			_entries[id].newcheck.id = _entries[id].name + "check";
			_entries[id].newcheck.type = "checkbox";
			_entries[id].newselectcol.appendChild(_entries[id].newcheck);

			if (_entries[id].checked === undefined || _entries[id].checked === null) {
				_entries[id].newcheck.checked = true;
			}
			else {
				_entries[id].newcheck.checked = true; //entry.checked;
			}

			GEvent.addDomListener(_entries[id].newcheck, "click", function() {
				GEvent.trigger(me, "entrycheck", _entries[id].newcheck.checked, _entries[id].name);
			});
		}

		_entries[id].newimagecol.innerHTML = _entries[id].iconhtml;
	
		_entries[id].newnamecol.style.textAlign = "left";
		_entries[id].newnamecol.style.color = "#3B6AA0";
		_entries[id].newnamecol.innerHTML += _entries[id].name;
		_entries[id].newrow.appendChild(_entries[id].newselectcol);
		_entries[id].newrow.appendChild(_entries[id].newimagecol);
		_entries[id].newrow.appendChild(_entries[id].newnamecol);
		_newtablebody.appendChild(_entries[id].newrow);
	};

	this.removeEntry = function(id)
	{
		_entries[id].newrow.removeChild(_entries[id].newselectcol);
		_entries[id].newrow.removeChild(_entries[id].newimagecol);
		_entries[id].newrow.removeChild(_entries[id].newnamecol);
		_newtablebody.removeChild(_entries[id].newrow);
		_entries[id].newrow = null;
		_entries[id].newselectcol = null;
		_entries[id].newimagecol = null;
		_entries[id].newnamecol = null;
		_entries[id] = null;
	};
	
	this.show = function()
	{
		_legenddiv.style.visibility = "visible";
		_legenddiv.style.height = null;
	};

	this.hide = function()
	{
		_legenddiv.style.visibility = "hidden";
		_legenddiv.style.height = 0;
	};
	
	this.initialize = function(map) {
		_legenddiv.id = "GLegend";

		_legenddiv.style.width = legendwidth;
		_legenddiv.style.backgroundColor = "#FFFFFF";
		_legenddiv.style.textAlign = "center";
		_legenddiv.style.fontFamily = "Arial";
		_legenddiv.style.fontSize = "9pt";
		_legenddiv.style.border = "1px solid black";
		_legenddiv.style.padding = "0px 0px 0px 0px";

		_titlespan.id = "GLegendTitle";
		_titlespan.style.color = "#FFFFFF";
		_titlespan.style.textAlign = "center";
		_titlespan.style.fontWeight = "bold";
		_titlespan.style.width = "100%";
		_titlespan.style.backgroundColor = "#7AA9DD";
		if (title !== undefined && title !== null)
		{
			_titlespan.innerHTML = title + "<br />";
		}
		_legenddiv.appendChild(_titlespan);
	
		_newtablebody.id = "legendtbody";
		_newtable.style.width = "100%";
		_newtable.appendChild(_newtablebody);
		_legenddiv.appendChild(_newtable);
	
		_container.appendChild(_legenddiv);

		map.getContainer().appendChild(_container);
		return _container;
	};
	
	this.getDefaultPosition = function() {
		return new GControlPosition(G_ANCHOR_BOTTOM_LEFT, new GSize(2, 32));
	};
}

SJJS.GMap.Controls.GLegend.prototype = new GControl();

//GList provides a list of markers added to the map

SJJS.GMap.Controls.GList = function() {
	var me = this;
	var _width = "203px";
	var _container = document.createElement("div");
	var _listdiv = document.createElement("div");
	var _listentries = [];
	//var _sortentries = [];
	var _listheight;

	function _listsort(l,r) {
		if (l.sort < r.sort) {
			return -1;
		}
		if (l.sort === r.sort) {
			return 0;
		}
		return 1;
	}

	function _dlistsort(l,r) {
		if (l.sort > r.sort) {
			return -1;
		}
		if (l.sort === r.sort) {
			return 0;
		}
		return 1;
	}

	function _findnameindex(name) {
		var x, _index = -1;

		for (x = 0; x < _listentries.length; x++) {
			if (_listentries[x].name === name) {
				return x;
			}
		}

		return _index;
	}


	this.initialize = function(map) {
		_listdiv.style.width = _width;
		_listdiv.id = "GList";
		_listheight = parseInt(map.getContainer().style.height.replace("px", ""), 10) - 20 + "px";
		_listdiv.style.height = "0px";
		_listdiv.style.visibility = "hidden";
		_listdiv.style.overflow = "auto";
		_listdiv.style.filter = "alpha(opacity=90)";
		_listdiv.style.opacity = ".9";
		_listdiv.style.fontFamily = "Arial";
		_listdiv.style.fontSize = "8pt";
		_listdiv.style.backgroundColor = "#FFFFFF";
		_listdiv.style.border = "1px solid black";
		_listdiv.style.textAlign = "left";
		_listdiv.style.cursor = "pointer";
		_listdiv.style.visibility = "hidden";
		_listdiv.style.overflow = "auto";
	
		_listdiv.innerHTML = "";
	
		_container.appendChild(_listdiv);
	
		map.getContainer().appendChild(_container);
	
		GEvent.addDomListener(map, "resize", function() {
			_listheight = parseInt(map.getContainer().style.height.replace("px", ""), 10) - 20 + "px";
			if (_listdiv.style.visibility === "visible") 
			{
				_listdiv.style.height = _listheight;
			}
		});
		map.List = me;

		return _container;
	};

	this.hide = function() {
		_listdiv.style.visibility = "hidden";
		_listdiv.style.height = "0px";
	};

	this.show = function() {
		_listdiv.style.visibility = "visible";
		_listdiv.style.height = _listheight;
	};

	this.addEntry = function (name) {
		var _index;
		var _newmarkerlist = document.createElement("div");
		var _nameindex = _findnameindex(name);

		if (_nameindex === -1) {
		//if (_listentries[name] === undefined || _listentries[name] === null)
		//{
			_newmarkerlist.style.borderBottom = "1px solid #EEEEEE";
			_newmarkerlist.style.padding = "0px 0px 0px 4px";
			_newmarkerlist.innerHTML = name;
			_newmarkerlist.id = "GListItem";
	
			_listentries.push({name:name, div:_newmarkerlist, sort:name});
			_index = _listentries.length - 1;
			_listentries.index = _index;
			//_sortentries.push({name:name, sort:name});
			//_listentries[name].index = _sortentries.length - 1;

			if (_index % 2 === 0) {
				_newmarkerlist.style.backgroundColor = "#EBECFF";
			}
	
			_listentries[_index].click = GEvent.addDomListener(_newmarkerlist, "click", function() { 
				GEvent.trigger(me, "clickitem", name);
			});
			_listentries[_index].mouseover = GEvent.addDomListener(_newmarkerlist, "mouseover", function() {
				GEvent.trigger(me, "mouseoveritem", name);
			});
			_listentries[_index].mouseout = GEvent.addDomListener(_newmarkerlist, "mouseout", function() {
				GEvent.trigger(me, "mouseoutitem", name);
			});
			_listdiv.appendChild(_listentries[_index].div);
		}
	};
	
	this.removeEntry = function (name) {
		var _nameindex = _findnameindex(name);

		//if (_listentries[name] !== undefined && _listentries[name] !== null) {
		if (_nameindex !== -1) {
			_listdiv.removeChild(_listentries[_nameindex].div);
			GEvent.removeListener(_listentries[_nameindex].click);
			GEvent.removeListener(_listentries[_nameindex].mouseover);
			GEvent.removeListener(_listentries[_nameindex].mouseout);
			//_sortentries.splice(_listentries[name].index, 1);
			_listentries.splice(_nameindex, 1);
			//_listentries[name] = undefined;
		}
	};
	
	this.getDefaultPosition = function() {
		//return new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(7, 27));
		return new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(0, 0));
	};
	
	this.getDivByName = function(name) {
		var _nameindex = _findnameindex(name);

		if (_nameindex !== -1) {
			return _listentries[_nameindex].div;
		}

		return undefined;
	};
	
	this.setSortByName = function(name, sort) {
		var _nameindex = _findnameindex(name);

		if (_nameindex !== -1) {
			_listentries[_nameindex].sort = sort;
		}
	};

	this.sortList = function(descending) {
		var x, i = 0;

		if (descending) {
			_listentries.sort(_dlistsort);
		}
		else
		{
			_listentries.sort(_listsort);
		}
		for (x = 0; x < _listentries.length; x++)
		{
			_listdiv.removeChild(_listentries[x].div);
		}
		for (x = 0; x < _listentries.length; x++)
		{
			_listdiv.appendChild(_listentries[x].div);
		}
	};

	this.Names = function() {
		var _namesarray = [];
		var x;

		for (x = 0; x < _listentries.length; x++) {
			_namesarray.push(_listentries[x].name);
		}

		return _namesarray;
	};
}

SJJS.GMap.Controls.GList.prototype = new GControl();

//GMenuBar

SJJS.GMap.Controls.GMenuBar = function() {
	var me = this;

	var _checkedbackcolor = "#7a7a7a";
	var _checkedcolor = "#eaeaea";
	var _startx = 0;
	var _starty = 0;

	var _items = [];

	var _numspans = 0;
	var _itemwidth = 50;

	var _newmap;
	var _mapdiv = document.createElement("div");

	var _totalzooms;

	var container = document.createElement("div");
	var _statusspan = document.createElement("span");
	var _statusbackspan = document.createElement("span");
	var _zoominspan = document.createElement("span");
	var _zoominbackspan = document.createElement("span");
	var _zoomoutspan = document.createElement("span");
	var _zoomoutbackspan = document.createElement("span");
	var _scrollcontainer = document.createElement("div");
	var _scrollbar = document.createElement("div");
	var _scrollbarold = document.createElement("div");
	var _scrollback = document.createElement("div");
	var _drag;

	var _map;

	var _menuopen = false;

	function _hideallexcept(menuid) {
		var x;

		for (x in _items)
		{
			if (x !== menuid)
			{
				_items[x].menuwindow.style.visibility = "hidden";
				_uncheckid(x);
				_items[x].checked = false;
			}
		}
	}

	function _checkdom(domobject, sub) {
		if (!sub)
		{
			domobject.style.border = "1px solid black";
			domobject.style.width = (_itemwidth - 2) + "px";
			domobject.style.height = "20px";
		}
		domobject.style.backgroundColor = _checkedbackcolor;
		domobject.style.color = _checkedcolor;
	}

	function _uncheckdom(domobject, sub) {
		if (!sub)
		{
			domobject.style.border = "0px";
			domobject.style.width = _itemwidth + "px";
			domobject.style.height = "20px";
		}
		domobject.style.backgroundColor = "#eaeaea";
		domobject.style.color = "#003366";
	}

	function _checkid(id) {
		_items[id].backspan.style.border = "1px solid black";
		_items[id].backspan.style.width = (_itemwidth - 2) + "px";
		_items[id].backspan.style.height = "18px";
		_items[id].backspan.style.backgroundColor = _checkedbackcolor;
		_items[id].span.style.color = _checkedcolor;
	}

	function _uncheckid(id) {
		_items[id].backspan.style.border = "0px";
		_items[id].backspan.style.width = _itemwidth + "px";
		_items[id].backspan.style.height = "20px";
		_items[id].backspan.style.backgroundColor = "#eaeaea";
		_items[id].span.style.color = "#003366";
	}

	function _removesubitems(menuid)
	{
		if (_items[menuid] !== null && _items[menuid] !== undefined)
		{
			var x;
	
			for (x in _items[menuid].subitems)
			{
				_items[menuid].menuwindow.removeChild(_items[menuid].subitems[x].div);
				_items[menuid].subitems[x].div = null;
			}
	
			_items[menuid].subitems = null;
			_items[menuid].subitems = [];
		}
	}

	function _addmaptypes() {
		var x, _maptypearray, _tempbool;

		if (_items.MapTypeID === null || _items.MapTypeID === undefined)
		{
			//me.addMenu("MapTypeID", _map.getCurrentMapType().getName(false));
			me.addMenu("MapTypeID", "Map");
		} else {
			_removesubitems("MapTypeID");
		}

		//_items.MapTypeID.span.innerHTML = _map.getCurrentMapType().getName(false);

		_maptypearray = _map.getMapTypes();
		for (x = 0; x < _maptypearray.length; x++)
		{
			if (_maptypearray[x].getName(false) === _map.getCurrentMapType().getName(false)) {
				_tempbool = true;
			} else {
				_tempbool = false;
			}
			me.addCheckItem(_maptypearray[x].getName(false) + "ID", _maptypearray[x].getName(false), "MapTypeID", _tempbool);

			_items.MapTypeID.subitems[_maptypearray[x].getName(false) + "ID"].maptype = _maptypearray[x];
		}
	}

	me.addMenu = function(id, text) {
		_items[id] = {text: text};

		_items[id].checked = false;
		_items[id].subitems = [];
		_items[id].spannum = _numspans;

		_items[id].backspan = document.createElement("span");
		_items[id].backspan.style.height = "20px";
		_items[id].backspan.style.width = _itemwidth + "px";
		_items[id].backspan.style.position = "absolute";
		_items[id].backspan.style.top = _starty + "px";
		_items[id].backspan.style.left = (_startx + (_numspans * _itemwidth)) + "px";
		_items[id].backspan.style.filter = "alpha(opacity=75)";
		_items[id].backspan.style.opacity = ".75";
		_items[id].backspan.style.backgroundColor = "#eaeaea";
		//_items[id].backspan.innerHTML = "";
		container.appendChild(_items[id].backspan);

		_items[id].span = document.createElement("span");
		_items[id].span.style.height = "20px";
		_items[id].span.style.position = "absolute";
		_items[id].span.style.top = _starty + "px";
		_items[id].span.style.left = (_startx + (_numspans * _itemwidth)) + "px";
		
		_items[id].span.style.width = _itemwidth + "px";
		_items[id].span.style.margin = "0px 0px 0px 0px";
		_items[id].span.style.padding = "0px 0px 0px 0px";
		_items[id].span.style.fontFamily = "Arial";
		_items[id].span.style.fontWeight = "bold";
		_items[id].span.style.textAlign = "center";
		_items[id].span.style.fontSize = "10pt";
		//_items[id].span.style.backgroundColor = "#eaeaea";
		_items[id].span.style.color = "#003366";
		//_menus[id].span.style.border = "1px solid black";
		_items[id].span.style.cursor = "pointer";
		_items[id].span.innerHTML = _items[id].text;

		GEvent.addDomListener(_items[id].span, "mouseover", function() {
			if (_menuopen) {
				_hideallexcept(id);
				_checkid(id);
				_items[id].menuwindow.style.visibility = "visible";
				_items[id].checked = true;
			}
			this.style.color = "#eaeaea";
			_items[id].backspan.style.backgroundColor = "#003366";
		});
		GEvent.addDomListener(_items[id].span, "mouseout", function() {
			if (_items[id].checked) {
				this.style.color = _checkedcolor;
				_items[id].backspan.style.backgroundColor = _checkedbackcolor;
			} else {
				this.style.color = "#003366";
				_items[id].backspan.style.backgroundColor = "#eaeaea";
			}
		});

		container.appendChild(_items[id].span);

		_items[id].menuwindow = document.createElement("div");

		_items[id].menuwindow.style.position = "absolute";
		_items[id].menuwindow.style.top = (_starty + 20) + "px";
		_items[id].menuwindow.style.left = (_startx + (_numspans * _itemwidth)) + "px";
		_items[id].menuwindow.style.width = "75px";
		if (id === "MapZoomID")
		{
			_items[id].menuwindow.style.left = (_startx + 23) + "px";
			_items[id].menuwindow.style.width = "25px";
		}
		//_items[id].menuwindow.style.height = "200px";
		_items[id].menuwindow.style.position = "absolute";
		_items[id].menuwindow.style.fontFamily = "Arial";
		_items[id].menuwindow.style.fontSize = "8pt";
		_items[id].menuwindow.style.color = "#003366";
		_items[id].menuwindow.style.backgroundColor = "#FFFFFF";
		_items[id].menuwindow.style.border = "1px solid black";
		_items[id].menuwindow.style.filter = "alpha(opacity=90)";
		_items[id].menuwindow.style.opacity = ".9";
		_items[id].menuwindow.style.margin = "0px 0px 0px 0px";
		_items[id].menuwindow.style.visibility = "hidden";

		container.appendChild(_items[id].menuwindow);

		GEvent.addDomListener(_items[id].span, "click", function() {
			_hideallexcept(id);
			if (_items[id].checked)
			{
				_menuopen = false;
				_uncheckid(id);
				_items[id].menuwindow.style.visibility = "hidden";
				_items[id].checked = false;
			}
			else {
				_menuopen = true;
				_checkid(id);
				_items[id].menuwindow.style.visibility = "visible";
				_items[id].checked = true;
			}
		});

		_numspans++;

		_statusbackspan.style.left = (_startx + (_numspans * _itemwidth)) + "px";
		_statusspan.style.left = (_startx + (_numspans * _itemwidth)) + "px";
	};

	me.addCheckItem = function(itemid, text, menuid, ischecked) {
		_items[menuid].subitems[itemid] = {text: text};

		_items[menuid].subitems[itemid].checked = ischecked;
		_items[menuid].subitems[itemid].div = document.createElement("div");
		_items[menuid].subitems[itemid].div = document.createElement("div");
		_items[menuid].subitems[itemid].div.style.width = "100%";
		if (menuid === "MapZoomID")
		{
			_items[menuid].subitems[itemid].div.style.height = "5px";
			_items[menuid].subitems[itemid].div.style.borderBottom = "1px solid black";
		}
		//_items[menuid].subitems[itemid].div.style.height = "8px";
		_items[menuid].subitems[itemid].div.style.backgroundColor = "#eaeaea";
		//_items[menuid].subitems[itemid].div.style.borderBottom = "1px solid black";
		_items[menuid].subitems[itemid].div.style.cursor = "pointer";
		//if (menuid !== "MapZoomID")
		//{
			_items[menuid].subitems[itemid].div.innerHTML = text;
		//}

		_items[menuid].menuwindow.appendChild(_items[menuid].subitems[itemid].div);

		if (ischecked) {
			_checkdom(_items[menuid].subitems[itemid].div, true);
		}

		GEvent.addDomListener(_items[menuid].subitems[itemid].div, "click", function() {
			_menuopen = false;
			_uncheckid(menuid);
			_items[menuid].checked = false;
			_items[menuid].menuwindow.style.visibility = "hidden";
			if (menuid === "MapTypeID")
			{
				if (!_items[menuid].subitems[itemid].checked)
				{
					_map.setMapType(_items[menuid].subitems[itemid].maptype);
				}
			} else {
				if (_items[menuid].subitems[itemid].checked)
				{
					_uncheckdom(_items[menuid].subitems[itemid].div, true);
					_items[menuid].subitems[itemid].checked = false;
					GEvent.trigger(me, "itemunchecked", itemid);
				}
				else {
					_checkdom(_items[menuid].subitems[itemid].div, true);
					_items[menuid].subitems[itemid].checked = true;
					GEvent.trigger(me, "itemchecked", itemid);
				}
			}
		});
		GEvent.addDomListener(_items[menuid].subitems[itemid].div, "mouseover", function() {
			this.style.color = "#eaeaea";
			this.style.backgroundColor = "#003366";
		});
		GEvent.addDomListener(_items[menuid].subitems[itemid].div, "mouseout", function() {
			if (_items[menuid].subitems[itemid].checked) {
				this.style.color = _checkedcolor;
				this.style.backgroundColor = _checkedbackcolor;
			} else {
				this.style.color = "#003366";
				this.style.backgroundColor = "#eaeaea";
			}
		});
	};

	me.addItem = function(itemid, text, menuid) {
		_items[menuid].subitems[itemid] = {text: text};

		_items[menuid].subitems[itemid].div = document.createElement("div");
		_items[menuid].subitems[itemid].div = document.createElement("div");
		_items[menuid].subitems[itemid].div.style.width = "100%";
		//_items[menuid].subitems[itemid].div.style.height = "8px";
		_items[menuid].subitems[itemid].div.style.backgroundColor = "#eaeaea";
		//_items[menuid].subitems[itemid].div.style.borderBottom = "1px solid black";
		_items[menuid].subitems[itemid].div.style.cursor = "pointer";
		_items[menuid].subitems[itemid].div.innerHTML = text;

		_items[menuid].menuwindow.appendChild(_items[menuid].subitems[itemid].div);

		GEvent.addDomListener(_items[menuid].subitems[itemid].div, "click", function() {
			_menuopen = false;
			_uncheckid(menuid);
			_items[menuid].checked = false;
			_items[menuid].menuwindow.style.visibility = "hidden";
			GEvent.trigger(me, "itemclicked", itemid);
		});
		GEvent.addDomListener(_items[menuid].subitems[itemid].div, "mouseover", function() {
			this.style.backgroundColor = "#003366";
			this.style.color = "#eaeaea";
		});
		GEvent.addDomListener(_items[menuid].subitems[itemid].div, "mouseout", function() {
			this.style.backgroundColor = "#eaeaea";
			this.style.color = "#003366";
		});
	};

	me.setStatus = function(statushtml) {
		_statusspan.innerHTML = statushtml;
		_statusbackspan.innerHTML = statushtml;
	};

	me.initialize = function(map) {
		_map = map;
	
		map.getContainer().appendChild(container);

		container.style.width = "100%";

		_statusbackspan.id = "StatusBackSpanID";
		_statusspan.id = "StatusSpanID";

		_statusbackspan.style.height = "20px";
		//_statusbackspan.style.width = "20px";
		_statusbackspan.style.position = "absolute";
		_statusbackspan.style.top = _starty + "px";
		_statusbackspan.style.left = _startx + "px";
		_statusbackspan.style.fontFamily = "Arial";
		_statusbackspan.style.textAlign = "left";
		_statusbackspan.style.fontSize = "10pt";
		_statusbackspan.style.filter = "alpha(opacity=75)";
		_statusbackspan.style.opacity = ".75";
		_statusbackspan.style.backgroundColor = "#eaeaea";

		container.appendChild(_statusbackspan);

		_statusspan.style.height = "20px";
		_statusspan.style.position = "absolute";
		_statusspan.style.top = _starty + "px";
		_statusspan.style.left = _startx + "px";
		
		//_statusspan.style.width = (8 *_itemwidth) + "px";
		_statusspan.style.margin = "0px 0px 0px 0px";
		_statusspan.style.padding = "0px 0px 0px 0px";
		_statusspan.style.fontFamily = "Arial";
		_statusspan.style.textAlign = "left";
		_statusspan.style.fontSize = "10pt";
		_statusspan.style.color = "#003366";
		_statusspan.style.cursor = "pointer";
		//_statusspan.innerHTML = _items[id].text;

		container.appendChild(_statusspan);

		//_starty += 20;
		

		_addmaptypes();

		GEvent.addListener(_map, "addmaptype", function(maptype) {
			_addmaptypes();
		});
		GEvent.addListener(_map, "removemaptype", function(maptype) {
			_addmaptypes();
		});
		GEvent.addListener(_map, "maptypechanged", function() {
			_addmaptypes();
		});
		GEvent.addListener(_map, "mousedown", function() {
			_menuopen = false;
			_hideallexcept("MapZoomID");
		});

		return container;
	};
	
	me.getDefaultPosition = function() {
		return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(70, 10));
	};
}

SJJS.GMap.Controls.GMenuBar.prototype = new GControl();