
var KWMap_marker_type = function(obj){
	this.name = obj.name;
	this.image = obj.image;
	this.wd = obj.wd;
	this.ht = obj.ht;
	this.x = obj.x;
	this.y = obj.y;
	this.visible = obj.visible;
	this.mouseover = obj.mouseover;
	this.mouseout = obj.mouseout;
	this.click = obj.click;
	this.byoption = obj.byoption;
	this.altimg = obj.altimg;
}


var KWMap_marker_layer = function(layer_name, map){
	this.map = map;
	this.layer_name = layer_name;
	this.marker_lists = new Object(); 
	this.marker_keys  = new Object();
	this.marker_types = new Object();
	this.public_state = new Object();

	
	if ( KW_VARS.dynamic_type === 'Google' ) {
	this.marker_layer = new OpenLayers.Layer.Markers(this.layer_name ,{projection: new OpenLayers.Projection("EPSG:900913")});
	} else {
	this.marker_layer = new OpenLayers.Layer.Markers(this.layer_name ,{minResolution:0.000010,maxResolution:0.513848});
	}
	this.map.addLayer(this.marker_layer);

	
	this.state = function (key, value){
		if(value !== undefined){
			this.public_state[key] = value;
		}
		return this.public_state[key];
	}

	
	this.marker_type_add = function(mt){
		this.marker_types[mt.name] = mt;
	}

	this.marker_type_get = function(mt_name){
		return this.marker_types[mt_name];
	}

	
	this.marker_add = function(name, ll, data){
		var mt = this.marker_types[name];
		var alt;
		var img;

		if(mt === undefined){
			
			return null;
		}

		img = mt.image;
		alt = mt.altimg;

		if(mt.byoption == 1){
			if(data.option){
				img = mt.image + data.option + '.png';
			}
			if(mt.altimg){
				alt = mt.altimg + data.option + '.png';
			}
		}

		var foobar = kw_decode_txt(ll);
		var foobar_arr = foobar.split(';');
		
		var new_marker = this._create_marker(mt, new OpenLayers.LonLat(foobar_arr[1], foobar_arr[0]), img);
		if(data === undefined){
			var data = {};
		}

		new_marker.kwdata = data;

		
		if((new_marker.kwdata !== undefined) && (new_marker.kwdata.title !== undefined)){
			new_marker.icon.imageDiv.title = new_marker.kwdata.title;
		}			

		new_marker.kwset_zindex = function(n){
			
			// n is the state
			// 0 normal
			// 1 highlight
			if(n == 0){
				this.icon.imageDiv.style.zIndex = '100';
			} else if(n == 1){
				this.icon.imageDiv.style.zIndex = '101';
			}
		}
		new_marker.kwset_zindex(0);

		new_marker.kwmarker_data = {	'layer_name'   : this.layer_name,
						'marker_type'  : mt.name,
						'index'        : 0,
						'kwmap_ml'     : this,
						'imgurl'       : img,
						'alturl'       : alt
					};

		if(mt.visible){
			new_marker.icon.display(true);
		} else {
			new_marker.icon.display(false);
		}
	
		if(mt.click !== undefined){
			new_marker.events.register("click", new_marker, function(e) {
				mt.click(new_marker);
			});
		}

		if(mt.mouseover !== undefined){
			new_marker.events.register("mouseover", new_marker, function(e) {
				mt.mouseover(new_marker);
			});
		}

		if(mt.mouseout !== undefined){
			new_marker.events.register("mouseout", new_marker, function(e) {
				mt.mouseout(new_marker);
			});
		}

		if(this.marker_lists[mt.name] === undefined){
			this.marker_lists[mt.name] = new Array();
		}

		if(this.marker_keys[mt.name] === undefined){
			this.marker_keys[mt.name] = new Object();
		}

				
		new_marker.kwmarker_data.index = this.marker_lists[mt.name].length;
		this.marker_lists[mt.name].push(new_marker);
		this.marker_layer.addMarker(new_marker);
		new_marker.icon.imageDiv.style.cursor = 'pointer';

		if((data !== undefined) && (data.key !== undefined)){
			this.marker_keys[mt.name][data.key] = new_marker;
		}

		return new_marker;
		
	}; // end marker_add

	
	this.markers_update = function(uobject){
		var bound = new OpenLayers.Bounds();
		var marker;
		var smarker;
		var i;
		var key;
		var type;
		var ll;
		var data;

		this.marker_layer.setVisibility(false);

		// Clear the old markers from the search keys
		for(type in uobject){
			for(i in this.marker_lists[type]){
				marker = this.marker_lists[type][i];
				marker.icon.display(false);
				key = marker.kwdata.key;

				if(this.marker_keys[type] !== undefined && this.marker_keys[type][key] !== undefined){
					// Delete the marker
					delete this.marker_keys[type][key];
				}
			}
		}	
		var k = 0;
		for(type in uobject){
			for(i in uobject[type]){
				if(i >= this.marker_lists[type].length){
					// Make a new marker
					marker = this.marker_add(type, uobject[type][i].ll, uobject[type][i].data); 	
				} else {
					// Reuse Maker
					marker = this.marker_lists[type][i];
					if((uobject[type][i].data !== undefined) && (uobject[type][i].data.key !== undefined)){
	
						// Create the key list if if does not exist.
						if(this.marker_keys[type] === undefined){
							this.marker_keys[mt.name] = new Object();
						}

						// Add the new marker to the key list
						this.marker_keys[type][uobject[type][i].data.key] = marker;
					}

					// Add the new data into the new marker
					marker.kwdata = uobject[type][i].data;
					ll = uobject[type][i].ll;
					var foobar = kw_decode_txt(ll);
					var foobar_arr = foobar.split(';');

					marker.lonlat = new OpenLayers.LonLat(foobar_arr[1], foobar_arr[0]);
					if ( KW_VARS.dynamic_type === 'Google' ) {

						marker.lonlat.transform(KW_VARS.stdProjection,localmap.getProjectionObject());

					}

					// update images.
					var mt = this.marker_types[type];
					if(mt.byoption == 1){
						var alt = mt.altimg;
						var img = mt.image;
						var d = uobject[type][i].data;
						if(mt.byoption == 1){
							if(d.option){
								img += d.option + '.png';
							}
							if(mt.altimg){
								alt += d.option + '.png';
							}
						}
				
						if(marker.icon.url !== img){
							marker.setUrl(img);	
							marker.kwmarker_data.imgurl = img;
							marker.kwmarker_data.alturl = alt;
							marker.kwset_zindex(0);
						}
					}
				}
				// Create a new boundry
				if(k++ < 100){ 
					bound.extend(marker.lonlat);
				}
				marker.icon.display(true);
			}
		}

		if(typeof(bound.top) === 'number'){
			this.marker_layer.setVisibility(true);
		}
		return bound;
	}

	
	this.marker_update_by_i = function(type, i, ll, data){
		if(this.marker_lists[type] === undefined || this.marker_lists[type][i] === undefined){
			return 0;
		}

		var marker = this.marker_lists[type][i];
		marker.kwdata = data;
		delete this.marker_keys[type][data.key];

		if((data !== undefined) && (data.key !== undefined)){
			this.marker_keys[type][data.key] = marker;
		}
		return 1;
	}
		
	
	this.marker_get_by_i = function(type, i){
		if(this.marker_lists[type] !== undefined){
			return this.marker_lists[type][i];
		}
	};

	
	this.marker_get_by_key = function(type, key){
		if(this.marker_keys[type] !== undefined){
			return this.marker_keys[type][key];
		}
	};

	
	this._create_icon = function(mt,img){
		if(img === undefined){
			return new OpenLayers.Icon(	mt.image, 
							new OpenLayers.Size(mt.wd,mt.ht), 
							new OpenLayers.Pixel(-mt.x,-mt.y));
		} else {
			return new OpenLayers.Icon(	img, 
							new OpenLayers.Size(mt.wd,mt.ht), 
							new OpenLayers.Pixel(-mt.x,-mt.y));
		}
	};

	
	this._create_marker = function(mt, ll, img){
		if ( KW_VARS.dynamic_type === 'Google' ) {
			ll.transform(KW_VARS.stdProjection,localmap.getProjectionObject());
		}
		return new OpenLayers.Marker(ll,this._create_icon(mt,img));
	};

	return this;
}


function KWMap_on_zoomend() {
	var iz;
	for ( iz=0; iz < this.numZoomLevels; iz++ ) {
		this.kw_map_scale_icon_list[iz].display(false);
	}
	this.draw_scale();
}


function kw_highlight_marker(new_marker){
	var i  = new_marker.kwmarker_data.index;
	var ml = new_marker.kwmarker_data.kwmap_ml;
	var m  = ml.marker_get_by_i("normal", i);
	var ms = ml.marker_get_by_i("normal_shadow", i);

	if(m.kwmarker_data.alturl){
		m.setUrl(m.kwmarker_data.alturl);
	} else {
		m.setUrl(ml.marker_type_get("highlight").image);
	}

	if(ms.kwmarker_data.alturl){
			ms.setUrl(ms.kwmarker_data.alturl);
	} else {
		ms.setUrl(ml.marker_type_get("highlight_shadow").image);
	}

	m.kwset_zindex(1);
}

function kw_highlight_marker_off(new_marker){
	var i  = new_marker.kwmarker_data.index;
	var ml = new_marker.kwmarker_data.kwmap_ml;
	var m  = ml.marker_get_by_i("normal", i);
	var ms = ml.marker_get_by_i("normal_shadow", i);

	if(m.kwmarker_data.imgurl){
		m.setUrl(m.kwmarker_data.imgurl);
	} else {
		m.setUrl(ml.marker_type_get("normal").image);
	}
	m.kwset_zindex(0);
	if(ms.kwmarker_data.imgurl){
		ms.setUrl(ms.kwmarker_data.imgurl);
	} else {
		ms.setUrl(ml.marker_type_get("normal_shadow").image);
	}
}

function mouseover_action(new_marker) {
	var i = new_marker.kwmarker_data.index;
	
	kw_highlight_marker(new_marker);

	if(KW_MAP_API.enabled !== 1){
		
		
			var pi = Math.floor(i / KWResults.results_per_page);
			if(pi !== KWResults.page_current) {
				KWResults.show_page(pi);
			}
		
		KWResults.kwresult_highlight(i);
	}
}

function mouseout_action(new_marker) {
	var i = new_marker.kwmarker_data.index;
	
	
		if(KW_VARS.current_detail !== new_marker){
			kw_highlight_marker_off(new_marker);
		}
	

	if(KW_MAP_API.enabled !== 1){
		KWResults.kwresult_highlight_off(i);
	}

}

function click_action(new_marker) {
	var i  = new_marker.kwmarker_data.index;
	var ml = new_marker.kwmarker_data.kwmap_ml;
	var m  = ml.marker_get_by_i("normal", i);
	
	
	if(KW_VARS.current_detail !== undefined){
		kw_highlight_marker_off(KW_VARS.current_detail);
	}
	KW_VARS.current_detail = new_marker;
	kw_highlight_marker(new_marker);

	DD_remove_markers();

	kwshow_detail(m.kwdata.key);

	var p = Math.floor(i / KWResults.results_per_page);
	if(p !== KWResults.page_current) {
		KWResults.show_page(p);
	}

	KWMap_zoom(m.lonlat.lat, m.lonlat.lon, KW_PAGE_CONFIG.detail_zoom_level);
}

function kw_on_resize() {
	kwresize();
}

function kwresize () {
	if(KW_VARS.mapdone !== 1){
		return;
	}
	// resize map when page resized
	document.getElementById('LOCAL_MAP').style.width = KWMap_width() + 'px';
	document.getElementById('LOCAL_MAP').style.height = KWMap_height() + 'px';
	localmap.updateSize();
	localmap.controls[0].redraw();
	localmap.draw_copyright();
	
		localmap.draw_scale();
	
	// move markers and copyright - not done yet
	
		KW_VARS.vlpoi.moveTo(localmap.getCenter());
		KW_VARS.vlpoi.onMapResize();
		kwmap_ol();
	
	
}

function findBrowser() {
	if(!KW_VARS.browser)
	{	KW_VARS.browser = "modern";
		agt = navigator.userAgent.toLowerCase();
		if(document.layers)
		{	KW_VARS.browser = "ns4";
		}
		else if((navigator.userAgent.indexOf("Opera 5")!=-1) ||(navigator.userAgent.indexOf("Opera/5")!=-1))
		{	KW_VARS.browser = "op5";
		}
		else if((navigator.userAgent.indexOf("Opera 6")!=-1) ||(navigator.userAgent.indexOf("Opera/6")!=-1))
		{	KW_VARS.browser = "op6"
		}
		else if(agt.indexOf("mac") != -1)
		{	KW_VARS.browser = "mac"
			if(agt.indexOf("msie") != -1)
			{	KW_VARS.browser = "macie";
			}
		}
		else if(agt.indexOf("msie") != -1)
		{	KW_VARS.browser = "ie"
		}
		//alert(KW_VARS.browser);
	}
}

function getElementHeight(Elem) {
	findBrowser();
	if(KW_VARS.browser == "ns4") {
		var elem = getObjNN4(document, Elem);
		return elem.clip.height;
	} else {
		if(document.getElementById) {
			var elem = document.getElementById(Elem);
		} else if(document.all){
			var elem = document.all[Elem];
		}
		if(KW_VARS.browser == "op5") { 
			xPos = elem.style.pixelHeight;
		} else {
			xPos = elem.offsetHeight;
		}
		//alert(xPos);
		return xPos;
	}
}

function getElementWidth(Elem) {
	findBrowser();
	if(KW_VARS.browser == "ns4") {
		var elem = getObjNN4(document, Elem);
		return elem.clip.width;
	} else {
		if(document.getElementById) {
			var elem = document.getElementById(Elem);
		} else if(document.all){
			var elem = document.all[Elem];
		}
		if(KW_VARS.browser == "op5") {
			xPos = elem.style.pixelWidth;
		} else {
			xPos = elem.offsetWidth;
		}
		return xPos;
	}
}

function KWMap_width() {
	var wt;
	if(KW_MAP_API.enabled == 1){
		if(KW_MAP_API.width > 0){
			wt = KW_MAP_API.width;
		} else {
			wt = windowWidth() - KW_MAP_API.padding_width;
		}

		wt = Math.min(KW_MAP_API.max_width, wt);
		wt = Math.max(KW_MAP_API.min_width, wt);
		return wt;
	}
 
	if(KW_VARS.current_page=='details')
	{	wt = windowWidth() - KW_PAGE_CONFIG.det_width - KW_PAGE_CONFIG.horizontal_margins;
		wt = Math.min(KW_PAGE_CONFIG.max_det_map_width, wt);
		wt = Math.max(KW_PAGE_CONFIG.min_det_map_width, wt);
	}
	else if(KW_VARS.current_page=='dd')
	{	wt = windowWidth() - KW_PAGE_CONFIG.dd_width - KW_PAGE_CONFIG.horizontal_margins;
		wt = Math.min(KW_PAGE_CONFIG.max_dd_map_width, wt);
		wt = Math.max(KW_PAGE_CONFIG.min_dd_map_width, wt);
	}
	else	// search results page or other
	{	wt = windowWidth() - KW_PAGE_CONFIG.sr_width - KW_PAGE_CONFIG.horizontal_margins;
		wt = Math.min(KW_PAGE_CONFIG.max_sr_map_width, wt);
		wt = Math.max(KW_PAGE_CONFIG.min_sr_map_width, wt);
	}
	return wt;
}

function KWMap_height () {
	var ht;
	if(KW_MAP_API.enabled == 1){
		if(KW_MAP_API.height > 0){
			ht = KW_MAP_API.height;
		} else {
			ht = windowHeight() - KW_MAP_API.padding_height;
		}

		ht = Math.min(KW_MAP_API.max_height, ht);
		ht = Math.max(KW_MAP_API.min_height, ht);
		return ht;
	}
	
		ht = windowHeight() - KW_PAGE_CONFIG.unusable_height;
	

	if(KW_VARS.current_page=='details')
	{	ht = Math.min(KW_PAGE_CONFIG.max_det_map_height, ht);
		ht = Math.max(KW_PAGE_CONFIG.min_det_map_height, ht);
	}
	else if(KW_VARS.current_page=='dd')
	{	
			ht = getElementHeight('dd_page');

			// add height of detail div if hide_detail is off
			
				ht += getElementHeight('detail_page');

				
			
		

		ht = Math.min(KW_PAGE_CONFIG.max_dd_map_height, ht);
		ht = Math.max(KW_PAGE_CONFIG.min_dd_map_height, ht);
	}
	else	// (KW_VARS.current_page=='results')
	{	ht = Math.min(KW_PAGE_CONFIG.max_sr_map_height, ht);
		ht = Math.max(KW_PAGE_CONFIG.min_sr_map_height, ht);
	}

	// subtract top/bottom border of map
	border = "1px";
	b = border.replace('px','');
	ht -= b*2;

	return ht;
}

function KWMap_style(){
	var map_div = document.getElementById('LOCAL_MAP');
	map_div.style.height = KWMap_height () + 'px';
	map_div.style.width = KWMap_width () + 'px';
}

function KWMap_zoom(lat, lon, zoom) {
	var location = new OpenLayers.LonLat;
	location.lat = lat;
	location.lon = lon;
	if ( KW_VARS.dynamic_type === 'Google' ) {
		location.transform(KW_VARS.stdProjection,localmap.getProjectionObject());
	}
	localmap.setCenter(location,zoom,1,1)
	if ( localmap.hl_marker ) {
		localmap.hl_marker.icon.display(false);
	}
	if ( localmap.hl_shadow ) {
		localmap.hl_shadow.icon.display(false);
	}
}	

function KWMap_panTo(lat, lon) {
	var location = new OpenLayers.LonLat;
	location.lat = lat;
	location.lon = lon;
	if ( KW_VARS.dynamic_type === 'Google' ) {
		location.transform(KW_VARS.stdProjection,KW_VARS.googleProjection);
	}
	localmap.panTo(location);
}	

function KWMap_Bounds() {
	var that = new OpenLayers.Bounds();
	that.extend_by_loc = function(loc) {
		var foobar = kw_decode_txt(loc);
		var foobar_arr = foobar.split(';');
		var lonlat = new OpenLayers.LonLat(foobar_arr[1],foobar_arr[0]);

		if ( KW_VARS.dynamic_type === 'Google' ) {
			lonlat.transform(KW_VARS.stdProjection,KW_VARS.googleProjection);
		}
		this.extend(lonlat);
	}
	return that;
}

function DD_markers(lat_start, lon_start, lat_end, lon_end, key) {
	var dl = localmap.plugins["standard_dd_layer"];

	if(dl === undefined){
		return;
	}

	
	
	var nl = localmap.plugins["standard_marker_layers"];
	nl.state("current_dd", key);

	var n = nl.marker_get_by_key("normal", key);
	var ns = nl.marker_get_by_key("normal_shadow", key);
	n.icon.display(false);
	ns.icon.display(false);

	var dds  = dl.marker_get_by_i("dd_start",  0);
	var dde  = dl.marker_get_by_i("dd_end",    0);
	var ddss = dl.marker_get_by_i("dd_shadow", 0);
	var ddes = dl.marker_get_by_i("dd_shadow", 1);

	dds.lonlat  = new OpenLayers.LonLat(lon_start, lat_start);
	ddss.lonlat = new OpenLayers.LonLat(lon_start, lat_start);
	dde.lonlat  = new OpenLayers.LonLat(lon_end, lat_end);
	ddes.lonlat = new OpenLayers.LonLat(lon_end, lat_end);
		
	dds.icon.display(true);
	ddss.icon.display(true);
	dde.icon.display(true);
	ddes.icon.display(true);

	var bound = new OpenLayers.Bounds();
	bound.extend (dds.lonlat);
	bound.extend (dde.lonlat);

	localmap.zoomToExtent(bound);
	var startpixel = localmap.getPixelFromLonLat(dds.lonlat);
	var endpixel = localmap.getPixelFromLonLat(dde.lonlat);

	if (startpixel.y < - dds.icon.offset.y || endpixel.y < - dde.icon.offset.y || 
			startpixel.x < - dds.icon.offset.x || endpixel.x < - dde.icon.offset.x ||
			localmap.getSize().w - startpixel.x < dds.icon.size.w + dds.icon.offset.x ||
			localmap.getSize().w - endpixel.x < dde.icon.size.w + dde.icon.offset.x) {
		localmap.zoomOut();
	}
}

function DD_remove_markers() {
	var dl = localmap.plugins["standard_dd_layer"];
	if(dl === undefined){
		return;
	}

	var nl = localmap.plugins["standard_marker_layers"];
	var key = nl.state("current_dd");
	if(key === undefined){
		return;
	}
	nl.state("current_dd", undefined);

	var n = nl.marker_get_by_key("normal", key);
	var ns = nl.marker_get_by_key("normal_shadow", key);
	n.icon.display(true);
	ns.icon.display(true);

	dl.marker_get_by_i("dd_start",  0).icon.display(false);
	dl.marker_get_by_i("dd_end",    0).icon.display(false);
	dl.marker_get_by_i("dd_shadow", 0).icon.display(false);
	dl.marker_get_by_i("dd_shadow", 1).icon.display(false);
}



	

	function kw_poi_mouseout(f,p){
		var ll = localmap.getLonLatFromViewPortPx(p);

		if ( KW_VARS.dynamic_type === 'Google' ) {
			ll.transform(localmap.getProjectionObject(),KW_VARS.stdProjection);
		}
		kwsearch({ll: ll.lat + "," + ll.lon, stype: 'poimove'});
	}

	function kwmap_click_search(evt){
		var ll = localmap.getLonLatFromViewPortPx(new OpenLayers.Pixel(evt.xy.x, evt.xy.y) );

		if ( KW_VARS.dynamic_type === 'Google' ) {
			ll.transform(localmap.getProjectionObject(),KW_VARS.stdProjection);
		}
		kwsearch({ll: ll.lat + ", " + ll.lon, stype: 'click'});
	}

	
	function kwmap_search_onmove(m){

		if(m === 'end'){
			if(KW_VARS.current_map_bounds){
				var center = localmap.getCenter();


				if(!KW_VARS.current_map_bounds.containsLonLat(center)){
					if(KW_VARS.current_page && KW_VARS.current_page == 'results'){
						if ( KW_VARS.dynamic_type === 'Google' ) {
							center.transform(localmap.getProjectionObject(),KW_VARS.stdProjection);
						}
						kwsearch({ll: center.lat + ", " + center.lon, stype: 'pan'});
					}
				}
			}
		}
	}




OpenLayers.Control.Navigation.prototype.zoomWheelEnabled = false;


var kw_decode = new Array();
kw_decode['X'] = '6';
kw_decode['b'] = '3';
kw_decode['f'] = '7';
kw_decode['8'] = '9';
kw_decode['g'] = '2';
kw_decode['Y'] = '+';
kw_decode['l'] = '-';
kw_decode['n'] = '8';
kw_decode['5'] = '1';
kw_decode['I'] = '4';
kw_decode['q'] = '0';
kw_decode['P'] = '.';
kw_decode['Z'] = ';';
kw_decode['x'] = '5';



OpenLayers.Util.onImageLoadError = function() {

	this._attempts = (typeof(this._attempts) === "number") ? (this._attempts + 1) : 0;
	if(this._attempts < OpenLayers.IMAGE_RELOAD_ATTEMPTS) {
		this.src = this.src;
	} else if(this._attempts === OpenLayers.IMAGE_RELOAD_ATTEMPTS){
		this.src = "http://tile.know-where.com/tiles/nodata.gif";
	} else {
		this.style.backgroundColor = OpenLayers.Util.onImageLoadErrorColor;
	}
	this.style.display = "";
};

OpenLayers.Layer.TileCache.prototype.buffer = 0;


function init_renderTile(obj) {
	if (obj.imgDiv == null) {
		obj.initImgDiv();
	}

	obj.imgDiv.viewRequestID = obj.layer.map.viewRequestID;

	// needed for changing to a different serve for onload error
	if (obj.layer.url instanceof Array) {
		obj.imgDiv.urls = obj.layer.url.slice();
	}
	obj.url = obj.layer.getURL(obj.bounds);
	// position the frame
	OpenLayers.Util.modifyDOMElement(obj.frame, null, obj.position, obj.size);
}
function finish_renderTile(obj) {
	var imageSize = obj.layer.getImageSize();
        if (obj.layerAlphaHack) {
            OpenLayers.Util.modifyAlphaImageDiv(obj.imgDiv,
                    null, null, imageSize, obj.url);
        } else {
            OpenLayers.Util.modifyDOMElement(obj.imgDiv,
                    null, null, imageSize) ;
            obj.imgDiv.src = obj.url;
        }
}
KWImage_renderTile = function() {

	var queue_id = new Date().getTime();
	var args = arguments;
	var call_back_binder = function(obj, args, id){
		return function(){
			if ( obj.layer != null ) {
			
			var current_time = new Date().getTime();
			if ( queue_id === obj.kw_queue_id ) {
				
				
				if ( id != null ) {
				/*OpenLayers.Tile.Image.prototype.renderTile.apply(obj,args);*/
				finish_renderTile(obj);
				}

	                	obj.layer.map.kw_tile_throttle.eventCounter( new Object() );
				obj.delay_drawn = true;

				
			} 
			if ( id == null && obj.delay_drawn) {
			     obj.kw_queue_id = null;
			}
			}
		}
	}

	init_renderTile(this);

	if ( this.kw_queue_id == null ) {
		
		this.kw_queue_id = queue_id;
		this.delay_drawn = false;
		setTimeout(call_back_binder(this, arguments, queue_id), 350);
		setTimeout(call_back_binder(this,arguments,null),1000);
	} else {
		

		this.kw_queue_id = queue_id;
		this.delay_drawn = false;
		
		setTimeout(call_back_binder(this, arguments, queue_id), 600);
		
		setTimeout(call_back_binder(this,arguments,null),1000);
	}
	return(true);
}
OpenLayers.Layer.TileCache.prototype.addTile = function(bounds, position) {

        var url = this.getURL(bounds);
        var atile = new OpenLayers.Tile.Image(this, position, bounds,
                                             url, this.tileSize);
	atile.renderTile = KWImage_renderTile;
	return(atile);
}
function KWMap_moveTo(lonlat, zoom, options) {

	var move = true;
	var current_time = new Date().getTime();
	var throttled = this.kw_tile_throttle.eventCounter( null );
	if ( throttled ) {
/*console.error("throttle on: skipping");*/
			move = false;
			this.kw_move_skipped = true;
			if ( lonlat != null ) {
			this.kw_save_lonlat = lonlat.clone();
			} else {
				this.kw_save_lonlat = null;
			}
			this.kw_save_zoom = zoom;
			this.kw_save_options = options;
	} else {
		if ( this.kw_move_skipped ) {
/*console.error("rendering skipped");*/
			lonlat = this.kw_save_lonlat;
			zoom = this.kw_save_zoom;
			options = this.kw_save_options;
			this.kw_save_lonlat = null;
			this.kw_save_zoom = null;
			this.kw_save_options = null;
		} 
	}
	if ( lonlat === null && zoom === null && options === null ) {
		move = false;
	}
	if ( move ) {
		
        	OpenLayers.Map.prototype.moveTo.apply(this,arguments);
		this.kw_move_skipped = false;
	} 
}
KWMap_moveThrottle.prototype.counter = 0;
KWMap_moveThrottle.prototype.on = false;
KWMap_moveThrottle.prototype.start = null;
KWMap_moveThrottle.prototype.end = null;
KWMap_moveThrottle.prototype.eventCounter = function (event) {

	var current_time = new Date().getTime();

	
	var throttle_interval = 3000;
	
	throttle_interval = throttle_interval - 500;
	
	var throttle_max = 90;
	

	
	while( this.end != null  && (current_time - this.start.time) > throttle_interval ) {
		this.start = this.start.next;
		this.counter--;
		if ( this.start === null ) {
			this.end = null;
			this.counter = 0;
		}
	}
	
	if ( event != null ) {
		event.time = current_time;
		event.next = null;
		if ( this.end == null ) {
			this.end = event;
			this.start = event;
		} else {
			this.end.next = event;
			this.end = event;
		}
		this.counter++;
	}

	
	if ( this.counter >= throttle_max  ) {
		this.on = true;
	} else if ( this.on ) {
		this.on = false;
	}
/*
if ( event != null ) {
console.error(current_time+":event#: "+this.counter+" throttle interval:"+throttle_interval+ " throttle_max:"+throttle_max+" return:",this.on);
}
*/
	return(this.on);
}
function KWMap_moveThrottle(map) {

	this.map = map;
	this.map.moveTo = KWMap_moveTo;
	return(this);
}



OpenLayers.Map.prototype.pan = function(dx, dy, options) {
        options = OpenLayers.Util.applyDefaults(options, {
            animate: true,
            dragging: false
        });
        // getCenter
        var centerPx = this.getViewPortPxFromLonLat(this.getCenter());

        // adjust
        var newCenterPx = centerPx.add(dx, dy);

        // only call setCenter if not dragging or there has been a change
        if (!options.dragging || !newCenterPx.equals(centerPx)) {
            var newCenterLonLat = this.getLonLatFromViewPortPx(newCenterPx);

            if (options.animate) {
                this.panTo(newCenterLonLat);
            } else {
                this.setCenter(newCenterLonLat, null, options.dragging);
            }
        }

   };
OpenLayers.Control.PanZoomBar.prototype.destroy = function () {
	
	

        OpenLayers.Control.PanZoom.prototype.destroy.apply(this, arguments);

}
OpenLayers.Control.PanZoomBar.prototype.zoomStopWidth = 16;
OpenLayers.Control.PanZoomBar.prototype.buttonDown = function (evt) {
	if (!OpenLayers.Event.isLeftClick(evt)) {
            return;
        }

        switch (this.action) {
            case "panup":
                this.map.pan(0, -this.getSlideFactor("h"));
                break;
            case "pandown":
                this.map.pan(0, this.getSlideFactor("h"));
                break;
            case "panleft":
                this.map.pan(-this.getSlideFactor("w"), 0);
                break;
            case "panright":
                this.map.pan(this.getSlideFactor("w"), 0);
                break;
	    case "panSE":
                this.map.pan(this.getSlideFactor("w"), this.getSlideFactor("h"));
		break;
	    case "panSW":
                this.map.pan(-this.getSlideFactor("w"), this.getSlideFactor("h"));
		break;
	    case "panNE":
                this.map.pan(this.getSlideFactor("w"), -this.getSlideFactor("h"));
		break;
	    case "panNW":
                this.map.pan(-this.getSlideFactor("w"), -this.getSlideFactor("h"));
		break;
            case "zoomin":
                this.map.zoomIn();
                break;
            case "zoomout":
                this.map.zoomOut();
                break;
            case "zoomworld":
                this.map.zoomToMaxExtent();
                break;
        }

        OpenLayers.Event.stop(evt);
}
OpenLayers.Control.PanZoomBar.prototype._addButton = function(id,img,xy,sz) {
	var button_div = OpenLayers.Control.PanZoom.prototype._addButton.apply(this,arguments);
	button_div.style.cursor = 'pointer';
	return button_div;
}
OpenLayers.Control.PanZoomBar.prototype.draw = function(px) {

        OpenLayers.Control.prototype.draw.apply(this, arguments);
        px = this.position.clone();


        this.buttons = [];

        var top_bottom_button_sz = new OpenLayers.Size(33,25);
		var corner_button_sz = new OpenLayers.Size(28,30);
        var right_left_button_sz = new OpenLayers.Size(23,34);
        var zoombar_plus_minus_sz = new OpenLayers.Size(20,24);
        var zoom_plus_minus_sz = new OpenLayers.Size(20,20);
		var button_pad = 8;
        var origin_x = px.x-button_pad;
        var origin_y = px.y-button_pad;
		var map_width = KWMap_width();
		var map_height = KWMap_height();
		var map_ctr = new OpenLayers.Pixel (map_width/2, map_height/2);


        this.slideFactor = map_ctr.y-10;
		px.x = origin_x+map_ctr.x-(top_bottom_button_sz.w/2)
		px.y = origin_y;
        var button = this._addButton("panup", "north-mini.png", px, top_bottom_button_sz);
		button.style.cursor = 'pointer';
		px.y = map_height - (top_bottom_button_sz.h+7);
        this._addButton("pandown", "south-mini.png", px, top_bottom_button_sz);

	

        px.x = origin_x;
	

        px.y = origin_y + map_ctr.y - (right_left_button_sz.h/2);
        this.slideFactor = map_ctr.x-10;
        this._addButton("panleft", "west-mini.png", px, right_left_button_sz);

        px.x = map_width - right_left_button_sz.w;
        this._addButton("panright", "east-mini.png", px, right_left_button_sz);

	
		
			px.x = 15;
		
		
			px.y = 15;
		
        	this._addButton("zoomin", "zoom2-plus-mini.png", px, zoom_plus_minus_sz);
        	this._addButton("zoomout", "zoom2-minus-mini.png", px.add(0,zoom_plus_minus_sz.h), zoom_plus_minus_sz);
	
        return this.div;
}

OpenLayers.Control.PanZoomBar.prototype._removeZoomBar = function(px) {
 	//this.sliderEvents.un({
            //"mousedown": this.zoomBarDown,
            //"mousemove": this.zoomBarDrag,
            //"mouseup": this.zoomBarUp,
            //"dblclick": this.doubleClick,
            //"click": this.doubleClick
        //});
        //this.sliderEvents.destroy();

        //this.divEvents.un({
            //"mousedown": this.divClick,
            //"mousemove": this.passEventToSlider,
            //"dblclick": this.doubleClick,
            //"click": this.doubleClick
        //});
        //this.divEvents.destroy();

        //this.div.removeChild(this.zoombarDiv);
        this.zoombarDiv = null;
        //this.div.removeChild(this.slider);
        this.slider = null;

        this.map.events.unregister("zoomend", this, this.moveZoomBar);

}

function KWMap_configure_copyright(type) {

	if ( type === 'TileCache' ) {
	this.copyright_icon = new OpenLayers.Icon(
					"http://attwifi.know-where.com/attwifi/Icon/copyright.png", 
					new OpenLayers.Size(125,12), 
					new OpenLayers.Pixel(0,0) );
					this.copyright_icon.imageDiv.style.zIndex = 999;
	this.copyright_icon.map = this;
	this.draw_copyright = function() {
		this.copyright_icon.draw();
	}
	this.copyright_icon.draw = function() {
		
			var margin = 4;
		
		var imgURL = this.imageDiv.childNodes[0].src;
		OpenLayers.Icon.prototype.draw.apply( this, new Array(new OpenLayers.Pixel(
					
						KWMap_width() - (this.size.w+margin),
					
						KWMap_height() - (this.size.h+margin))) );
		
		if ( imgURL === "" ) {
			this.map.viewPortDiv.appendChild(this.imageDiv);
		}
	}
	} else {
		this.draw_copyright = function() {
		}
	}
}

function KWMap_configure_map_scale(type) {
	if ( type === 'TileCache' ) {
	this.events.register("zoomend",that,KWMap_on_zoomend );
	this.draw_scale = function() {
		var z = this.getZoom();
		
			var margin = 4;
		
		var imgURL = this.kw_map_scale_icon_list[z].imageDiv.childNodes[0].src;
		this.kw_map_scale_icon_list[z].display(true);
		this.kw_map_scale_icon_list[z].draw(new OpenLayers.Pixel(
					margin,
					KWMap_height() - (this.kw_map_scale_icon_list[z].size.h+margin)));
		if ( imgURL === "" ) {
			this.viewPortDiv.appendChild(this.kw_map_scale_icon_list[z].imageDiv);
		}
	}
	var zoom_num = this.numZoomLevels;
	this.kw_map_scale_icon_list = new Array(zoom_num);
	var z;
	for ( z=0; z < zoom_num; z++ ) {
		this.kw_map_scale_icon_list[z] =  new OpenLayers.Icon(
				"http://attwifi.know-where.com/attwifi/Icon/map_scale/zoom"+z+".png",
				new OpenLayers.Size(104,16), 
				new OpenLayers.Pixel(0,0) );
		this.kw_map_scale_icon_list[z].imageDiv.style.zIndex = 998;
	}
	} else {
		this.draw_scale = function() {
		}
	}
}


function kw_decode_txt(src) {
	var val = '';
	var c;
	for ( c=0; c < src.length; c++ ) {
		var newc = kw_decode[src.charAt(c)];
		val = val + newc;
	}
	return val;
}

function KWMap_draw_line(points) {
		if ( this.line_layer == null ) {
			this.line_layer = new OpenLayers.Layer.Vector( "Lines",
				{minResolution:0.000010,maxResolution:0.513848} );
			this.addLayer(this.line_layer);
		}
		var line_style = {
			strokeColor: "#00FF00",
			strokeWidth: 15,
			strokeRadius: 30,
			strokeOpacity: 0.6,
			pointerEvents: "visiblePainted"
		};
		var line_feature = new OpenLayers.Feature.Vector(
			new OpenLayers.Geometry.LineString(points),
			null,
			line_style
			);
		this.line_layer.addFeatures([line_feature]);
}

function KWMap_remove_line() {
	if ( this.line_layer != null ) {
		this.removeLayer(this.line_layer);
		this.line_layer = null;
	}
}

function KWMap_tilecache_layer(name) {
	var tile_size = 512;
	var n_zoom = 12;
	var zoom_levels = new Array(n_zoom-2);
	/* degrees lat/pixel @ most zoomed in level (1000 pix/mile & 69 miles/deg of lat)*/
	var zoom_max_pixel = 0.000014;  /* kwmap only support 6 decimals of precision */
	for ( z=2; z < n_zoom; z++ ) { /* limit to 10 zooms for now until we get world working properly */
		/* OpenLayers expects zoom resolution defined in units per pixel*/ 
		zoom_levels[z-2] = (zoom_max_pixel * Math.pow(2.6,n_zoom-(z+1))).toFixed(6);
	}
	var layer = new OpenLayers.Layer.TileCache( name,
			[ "http://tile.know-where.com/attwifi/tile" ],
			"custom",
			{format: 'image/gif',
			tileSize: new OpenLayers.Size(tile_size,tile_size),
			maxExtent : new OpenLayers.Bounds(-180,-60,180,90),
			resolutions: zoom_levels, transitionEffect: 'resize' });

	return layer;
}

function KWMap(mapid,lat,lon,zoom,type,bounds) {

	var base_layer;
	if ( type === 'Google' ) {
		base_layer   = new OpenLayers.Layer.Google("Streets", {"sphericalMercator":true});
	} else {
		type = 'TileCache';
		base_layer   = KWMap_tilecache_layer("Streets");
	}
	var mapOptions = { controls: [], resolutions: base_layer.resolutions };
	if ( type === 'Google' ) {
		mapOptions.projection = new OpenLayers.Projection("EPSG:900913");
		mapOptions.units = "m";
		mapOptions.maxResolution = 156543.0339;
		mapOptions.maxExtent = new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34);
	}
	that = new OpenLayers.Map( mapid,mapOptions );
	that.addLayer(base_layer);

	if ( type === 'TileCache' ) {
		that.kw_tile_throttle = new KWMap_moveThrottle(that);
	}


		KWMap_configure_map_scale.apply(that,new Array(type));

		KWMap_configure_copyright.apply(that,new Array(type));

	/* 
	 * Set map center & zoom level together, so that map
	 * only loads tiles once on creation
	 * Every change of center or zoom causes a "moveTo"
	 * on the map, which must load new tiles.
	 */
	var zoom_num = 0;
	if ( typeof(zoom) == "number" ) {
		zoom_num = zoom;
	} else {
		zoom_num = base_layer.getZoomForExtent(zoom);
	}
	var center = new OpenLayers.LonLat(lon,lat);
	if ( type === 'Google' ) {
		center.transform(KW_VARS.stdProjection,that.getProjectionObject());
	}
	that.setCenter(center,zoom_num);

	if ( type === 'TileCache' ) {
		that.copyright_icon.draw();
	}
	/* Add controls*/
	that.addControl( new OpenLayers.Control.PanZoomBar() );
	that.addControl( new OpenLayers.Control.Navigation() );
	that.addControl( new OpenLayers.Control.DragPan() );

	that.kw_center_lat  = lat;
	that.kw_center_lon  = lon;

	that.draw_line = KWMap_draw_line;
	that.remove_line = KWMap_remove_line;

	that.add_plugin = function(name, plugin){
		if(this.plugins === undefined){
			this.plugins = new Object();
		} 
		if(this.plugins[name] === undefined){
			this.plugins[name] = new Object();
		}

		this.plugins[name] = plugin;
	}


	
	
	if ( bounds != null ) {
	    that.restrictedExtent = bounds;
	} else {
	    bounds = new OpenLayers.Bounds(-170.0,15.5,-48.6,73.0);
	}
	
		

/* Return the new map */
	return (that);
}





