/*!
 * ShowNearby Widget Library v1.0
 * http://api.shownearby.com/
 * Copyright (c) 2009 ShowNearby Pte Ltd
 */
(function() {

var Snb = window.Snb;

/**
 * Location widget
 */
Snb.LocationWidget = function(opts) {
	return new Snb.locationWidget(opts);
}
Snb.locationWidget = function() {
	this.opts = arguments[0];
	if (!document.getElementById(this.opts.id)) document.write('<div id="'+this.opts.id+'"></div>');
	this.map = Snb.Map(this.opts.id, this.opts.api, {'size':this.opts.map_size});
	this.map.scrollWheelZoom(false);
	this.map.onzoomend.addListener(bind(this, function(zoom) {
		if (this.markers2) {
			zoom < 16 ? this.map.deleteMarkerOnMap(this.markers2) : this.map.addMarkerToMap(this.markers2);
		}
	}));
	this.onmarkercreated = Snb.Event();
	this.gc = Snb.Geocoder(this.opts.ref+'.gc');
	this.gc.oncallback.addListener(bind(this, function(obj) {
		if (obj.status == 200) {
			this.marker = Snb.Marker(Snb.Point(obj.pois[0].latitude, obj.pois[0].longitude), this.opts.text, this.opts.window_size, this.opts.api);
			this.marker.onleftclick.addListener(bind(this, function(marker) {
				this.map.setCenterAndZoom(marker.point(), 17);
				setTimeout(bind(this, function(e) { marker.openWindow(this.map); }), 500);
			}));
			this.onmarkercreated.trigger(this.marker);
			this.map.addMarkerToMap(this.marker);
			this.map.setCenterAndZoom(this.marker.point(), this.opts.zoom);
			if (!this.opts.window_close) this.marker.openWindow(this.map);
			this.map.savePosition();
			this.gc2.setQuery(this.marker.point().lat()+','+this.marker.point().lng()).setTags(this.opts.tags).getPOIs();
			this.map.loadingStatus(false);
		}
	}));
	this.gc.setQuery(this.opts.address).getPOIs();
	this.map.loadingStatus(true);
	this.gc2 = Snb.Geocoder(this.opts.ref+'.gc2');
	this.gc2.oncallback.addListener(bind(this, function(obj) {
		if (obj.status == 200) {
			this.markers2 = new Array();
			for (var i=0; i<obj.pois.length; i++) {
				if (obj.pois[i].distance <= 0.8) {
					switch(this.opts.api) {
						case 'google':
							this.markers2[i] = Snb.Marker(Snb.Point(obj.pois[i].latitude, obj.pois[i].longitude), obj.pois[i].html, this.opts.window_size, 'google');
							if (obj.pois[i].pattributes['icon']) {
								this.markers2[i].icon().image = Snb.url+'images/icons/16x16/'+obj.pois[i].pattributes['icon'].replace(/ /g,'-')+'.gif';
								this.markers2[i].icon().iconSize = new GSize(16,16);
								this.markers2[i].icon().iconAnchor = new GPoint(8,16);
								this.markers2[i].icon().infoWindowAnchor = new GPoint(8,0);
							}
						break;
						case 'microsoft':
							this.markers2[i] = Snb.Marker(Snb.Point(obj.pois[i].latitude, obj.pois[i].longitude), obj.pois[i].html, this.opts.window_size, 'microsoft');
							if (obj.pois[i].pattributes['icon']) {
								this.markers2[i].icon().Image = Snb.url+'images/icons/16x16/'+obj.pois[i].pattributes['icon'].replace(/ /g,'-')+'.gif';
							}
						break;
					}
					this.markers2[i].onleftclick.addListener(bind(this, function(marker) {
						setTimeout(bind(this, function(e) { marker.openWindow(this.map); }), 500);
					}));
				}
			}
			this.map.addMarkerToMap(this.markers2);
		}
	}));
}

/**
 * Directions widget
 */
Snb.DirectionsWidget = function() {
	document.write('<form style="padding:0; margin:0;" action="http://directions.shownearby.com/" method="post" target="_blank" onsubmit="if (document.getElementById(\''+arguments[0].id+'\').value==\'\' || document.getElementById(\''+arguments[0].id+'\').value==\'Enter your location...\') { document.getElementById(\''+arguments[0].id+'\').focus(); return false; } else { return true; }">');
	document.write('<select name="order">');
	document.write('<option value="2">To '+arguments[0].text+' From</option>');
	document.write('<option value="1">From '+arguments[0].text+' To</option>');
	document.write('</select>');
	document.write('<input type="hidden" name="address[]" value="'+arguments[0].address+'" />');
	document.write('<input type="text" id="'+arguments[0].id+'" name="address[]" value="Enter your location..." size="25" onfocus="if (this.value==\'Enter your location...\') this.value=\'\'" onblur="if (this.value==\'\') this.value=\'Enter your location...\'" />');
	document.write('<button type="submit">'+arguments[0].button+'</button>');
	document.write('</form>');
}

/**
 * Store widget
 */
Snb.StoreWidget = function(opts) {
	return new Snb.storeWidget(opts);
}
Snb.storeWidget = function() {
	this.opts = arguments[0];
	this.opts.layout == 'vertical' ?
		document.write('<table border="0" cellpadding="0" cellspacing="0"><tr><td><div id="'+this.opts.id+'_mp"></div></td></tr><tr><td><input id="'+this.opts.id+'_ac" value="" class="snb-autocomplete-input" /><div id="'+this.opts.id+'_pn" class="snb-autocomplete-div"></div></td></tr><tr><td><div class="snb-listing-wrap"><div id="'+this.opts.id+'_ls" class="snb-listing-div"></div><div class="snb-listing-logo"><a href="http://widgets.shownearby.com/" style="float:left; height:22px; width:167px;"><img src="'+Snb.url+'/images/snb-poweredby.png" alt="" style="border:none;" /></a></div></div></td></tr></table>') :
			document.write('<table border="0" cellpadding="0" cellspacing="0"><tr><td><input id="'+this.opts.id+'_ac" value="" class="snb-autocomplete-input" /><div id="'+this.opts.id+'_pn" class="snb-autocomplete-div"></div></td><td rowspan="2"><div id="'+this.opts.id+'_mp"></div></td></tr><tr><td><div class="snb-listing-wrap"><div id="'+this.opts.id+'_ls" class="snb-listing-div"></div><div class="snb-listing-logo"><a href="http://widgets.shownearby.com/" style="float:left; height:22px; width:167px;"><img src="'+Snb.url+'/images/snb-poweredby.png" alt="" style="border:none;" /></a></div></div></td></tr></table>');
	this.ac = document.getElementById(this.opts.id+'_ac');
	this.ac.style.width = (this.opts.list_size.width()-12)+'px';
	this.pn = document.getElementById(this.opts.id+'_pn');
	this.pn.style.width = this.opts.list_size.width()+'px';
	this.list = document.getElementById(this.opts.id+'_ls');
	this.list.style.width = (this.opts.list_size.width()-12)+'px';
	this.list.style.height = (this.opts.layout == 'vertical'?this.opts.list_size.height():this.opts.map_size.height()-28)+'px';
	this.opts.center && this.opts.zoom ? this.opts.initpos = true : this.opts.initpos = false;
	this.map = Snb.Map(this.opts.id+'_mp', this.opts.api, {'size':this.opts.map_size, 'center':this.opts.center?this.opts.center:null, 'zoom':this.opts.zoom?this.opts.zoom:null});
	this.map.onzoomend.addListener(bind(this, function(zoom) {
		if (this.markers2 && zoom < 16) this.map.deleteMarkerOnMap(this.markers2);
	}));
	this.shownearby = null;
	this.ac = Snb.Autocomplete(this.opts.ref+'.ac', this.opts.id+'_ac', this.opts.id+'_pn', 121, this.opts.autoFill);
	this.ac.gc.setOwners('1');
	this.ac.onselect.addListener(bind(this, function(obj) {
		this.shownearby = Snb.Point(obj.latitude, obj.longitude);
		this.map.loadingStatus(true);
		this.opts.initpos = false;
		this.gc.setOwners(this.opts.owner).setQuery(obj.latitude+','+obj.longitude).getPOIs(); 
	}));
	this.ac.onclear.addListener(bind(this, function() {
		this.map.loadingStatus(true);
		this.opts.center && this.opts.zoom ? this.opts.initpos = true : this.opts.initpos = false;
		this.gc.setOwners(this.opts.owner).setQuery('').getPOIs();
	}));
	this.onmarkercreated = Snb.Event();
	this.onsnbmarkercreated = Snb.Event();
	this.gc = Snb.Geocoder(this.opts.ref+'.gc');
	this.gc.oncallback.addListener(bind(this, function(obj) {
		if (obj.status == 200) {
			this.hashtable = new Array();
			this.pois = new Array();
			this.markers = new Array();
			var ol = '<ol>';
			for (var i=0; i<obj.pois.length; i++) {
				this.pois[i] = obj.pois[i];
				this.pois[i].html += '<div style="margin-bottom:10px;"><small style="font-size:10px;"><a href="http://directions.shownearby.com/from-'+
				(this.shownearby?this.ac.results[this.ac.cursor].directions+'-to-':'')+obj.pois[i].directions+'" target="_blank">Get Directions</a></small></div>';
				var hash = new Number(obj.pois[i].latitude).toFixed(6)+'-'+new Number(obj.pois[i].longitude).toFixed(6);
				var markerNum = this.markers.length;
				if (hash in this.hashtable) {
					markerNum = this.hashtable[hash];
					this.markers[markerNum].html(this.markers[markerNum].html()+this.pois[i].html);
				}
				else {
					this.hashtable[hash] = markerNum;
					switch(this.opts.api) {
						case 'google': this.markers[markerNum] = Snb.Marker(Snb.Point(obj.pois[i].latitude, obj.pois[i].longitude), this.pois[i].html, this.opts.window_size, 'google'); break;
						case 'microsoft': this.markers[markerNum] = Snb.Marker(Snb.Point(obj.pois[i].latitude, obj.pois[i].longitude), this.pois[i].html, this.opts.window_size, 'microsoft'); break;
					}
					this.markers[markerNum].onleftclick.addListener(bind(this, function(marker) {
						this.map.loadingStatus(true);
						this.gc2.setQuery(marker.point().lat()+','+marker.point().lng()).setTags(this.opts.tags).getPOIs();
						this.map.setCenterAndZoom(marker.point(), 17);
						if (marker.html()) {
							setTimeout(bind(this, function(e) { marker.openWindow(this.map); }), 500);
						}
						this.map.loadingStatus(false);
					}));
					this.onmarkercreated.trigger(this.markers[markerNum]);
				}
				this.pois[i].marker = markerNum;
				ol += '<li><a href="" onclick="'+this.opts.ref+'.show('+i+'); return false;" class="title">'+obj.pois[i].name+'</a>'+(obj.pois[i].distance?' <small class="distance">('+(new Number(obj.pois[i].distance).toFixed(2))+' km away)</small>':'')+'<br />'+obj.pois[i].address+'</li>';
			}
			ol += '</ol>';
			this.list.innerHTML = ol;
			if (this.shownearby) {
				var marker; 
				switch(this.opts.api) {
					case 'google':
						marker = Snb.Marker(this.shownearby, '', '', 'google');
						marker.icon().image = Snb.url+'images/shownearby-image.png';
						marker.icon().iconSize = new GSize(26,50);
						marker.icon().iconAnchor = new GPoint(14,50);
						marker.icon().infoWindowAnchor = new GPoint(14,0);
						marker.icon().shadow = Snb.url+'images/shownearby-shadow.png';
						marker.icon().shadowSize = new GSize(51,50);
					break;
					case 'microsoft':
						marker = Snb.Marker(this.shownearby, '', '', 'microsoft');
						marker.icon().Image = Snb.url+'images/shownearby-image.png';
					break;
				}
				this.onsnbmarkercreated.trigger(marker);
				this.markers.push(marker);
				this.shownearby = null;
			}
			if (this.opts.clustering == 'none') {
				this.map.deleteAllMarkersOnMap();
				this.map.addMarkerToMap(this.markers);
				this.opts.initpos ?
					this.map.setCenterAndZoom(this.opts.center, this.opts.zoom) : 
						this.map.showBounds(this.map.getMapBounds());
			}
			else {
				this.map.deleteAllMarkersOnClusterer();
				this.map.addMarkerToClusterer(this.markers);
				this.opts.initpos ?
					this.map.setCenterAndZoom(this.opts.center, this.opts.zoom) : 
						this.map.showBounds(this.map.getClustererBounds());
			}
			setTimeout(bind(this, function(e) {
				this.map.loadingStatus(false);
				this.map.savePosition();
			}), 500);
		}
		if (obj.status == 620) {
			alert('SNB_SEARCH_TOO_MANY_QUERIES - Please try again later.');
		}
	}));
	this.map.loadingStatus(true);
	this.gc.setOwners(this.opts.owner).setQuery('').getPOIs();
	this.show = function(num) {
		this.map.loadingStatus(true);
		var marker = this.markers[this.pois[num].marker];
		this.gc2.setQuery(marker.point().lat()+','+marker.point().lng()).setTags(this.opts.tags).getPOIs();
		this.map.setCenterAndZoom(marker.point(), 17);
		setTimeout(bind(this, function(e) {
			marker.openWindow(this.map, this.pois[num].html);
		}), 500);
		this.map.loadingStatus(false);
	}
	this.gc2 = Snb.Geocoder(this.opts.ref+'.gc2');
	this.gc2.oncallback.addListener(bind(this, function(obj) {
		if (obj.status == 200) {
			if (this.markers2) this.map.deleteMarkerOnMap(this.markers2);
			this.markers2 = new Array();
			for (var i=0; i<obj.pois.length; i++) {
				if (obj.pois[i].distance <= 0.8) {
					switch(this.opts.api) {
						case 'google':
							this.markers2[i] = Snb.Marker(Snb.Point(obj.pois[i].latitude, obj.pois[i].longitude), obj.pois[i].html, this.opts.window_size, 'google');
							if (obj.pois[i].pattributes['icon']) {
								this.markers2[i].icon().image = Snb.url+'images/icons/16x16/'+obj.pois[i].pattributes['icon'].replace(/ /g,'-')+'.gif';
								this.markers2[i].icon().iconSize = new GSize(16,16);
								this.markers2[i].icon().iconAnchor = new GPoint(8,16);
								this.markers2[i].icon().infoWindowAnchor = new GPoint(8,0);
							}
						break;
						case 'microsoft':
							this.markers2[i] = Snb.Marker(Snb.Point(obj.pois[i].latitude, obj.pois[i].longitude), obj.pois[i].html, this.opts.window_size, 'microsoft');
							if (obj.pois[i].pattributes['icon']) {
								this.markers2[i].icon().Image = Snb.url+'images/icons/16x16/'+obj.pois[i].pattributes['icon'].replace(/ /g,'-')+'.gif';
							}
						break;
					}
					this.markers2[i].onleftclick.addListener(bind(this, function(marker) {
						setTimeout(bind(this, function(e) { marker.openWindow(this.map); }), 500);
					}));
				}
			}
			this.map.addMarkerToMap(this.markers2);
		}
	}));
}

/**
 * Bind scope to function
 */
function bind(scope, fn) {
	return function () {
		fn.apply(scope, arguments);
	};
};

})();