dojo.require("dojo.parser");

function hideLoader(){
	var loader = dojo.byId('loader'); 
	dojo.fadeOut({ node: loader, duration:250,
		onEnd: function(){ 
			loader.style.display = "none"; 
		}
	}).play();
}

dojo.addOnLoad(function() {
	dojo.byId('loader-inner').innerHTML += " done.";
	setTimeout("hideLoader()",250);
});

var dlgWorking = null;

function showWorking()
{
	if (dlgWorking == null) {
		dlgWorking = new dijit.Dialog({title: "Processing your request..."});	
	}
	dlgWorking.show();
}

function hideWorking()
{
	if (dlgWorking) dlgWorking.hide();	
}

dojo.declare("BaseClass", null, {
	id: '',
	getElementId: function(id) { return this.id + "-" + id;	},
	getDom: function(id) { return dojo.byId(this.getElementId(id)); },
	getElement: function(id) { return dijit.byId(this.getElementId(id)); }
});

dojo.declare("MapViewer", BaseClass, {
	constructor: function(id)
	{
		this.id = id;	
		this.gmap = null;
		this.center = new google.maps.LatLng(0, 0);
		this.zoomLevel = 1;		
		this.update_overlay = null;
		this.update_w = 124;
		this.update_h = 28;
		this.clusters = [];
		this.icon = null;	
		this.iconCluster = null;
		this.initial = true;
		this.page = 1;
		this.num_page = 1;
		this.activeCluster = 0;
		this.selectPhoto = 0;
		this.bubble = null;
		this.per_page = 19;
		this.display_clusters = false;
	},
	setCenter: function(point) { this.center = point; },
	setZoomLevel: function(zoomLevel) { this.zoomLevel = zoomLevel; },
	onAreaChange: function() {},
	onPointChange: function() {},
	getXY: function(lat, lng)
	{
		return this.gmap.getCurrentMapType().getProjection().fromLatLngToPixel(
			new google.maps.LatLng(lat, lng), this.gmap.getZoom());	
	},
	goToLatLng: function(lat, lng)
	{
		this.gmap.setCenter(new google.maps.LatLng(lat, lng), this.gmap.getZoom());
	},
	resetList: function()
	{
		this.page = 1;
		this.num_page = 1;
		this.getDom("list").innerHTML = '';
		this.updateButtons();
	},
	zoom: function(lat, lng)
	{
		this.gmap.closeInfoWindow();
        var z = this.gmap.getZoom();
		this.selectPhoto = this.clusters[this.activeCluster].photos[0].code;
		this.gmap.setCenter(new google.maps.LatLng(lat, lng), z < this.per_page ? this.gmap.getZoom() + 3 : z);
	},
	updateButtons: function()
	{
		this.getDom("next").innerHTML = (this.page == this.num_page) ? '<img src="images_map/next_disabled.gif" width=25 height=30 border=0>' : '<img src="images_map/next.gif" width=25 height=30 border=0 onclick="' + this.id + '.nextPage()">';
		this.getDom("prev").innerHTML = (this.page == 1) ? '<img src="images_map/prev_disabled.gif" width=25 height=30 border=0>' : '<img src="images_map/prev.gif" width=25 height=30 border=0 onclick="'+ this.id + '.prevPage()">';
	},
	updateList: function(response)
	{
		this.page = response.page;
		this.clusters[this.activeCluster].photos = response.photos;
		this.displayList(this.activeCluster);
	},
	setPage: function(page)
	{
		var c = this.clusters[this.activeCluster];
		var query = "key=" + c.key;
		query += "&min_lat=" + c.min_lat + "&min_lng=" + c.min_lng;
		query += "&max_lat=" + c.max_lat + "&max_lng=" + c.max_lng;
        query += "&zoom=" + this.gmap.getZoom();
		query += "&count=" + this.per_page + "&page=" + page;
		dojo.xhrGet({
			url: "get_list.php?" + query,
			handleAs: "json",
			timeout: 60000,
			mv: this,
			load: function(response, ioArgs) {
				this.mv.updateList(response);
			},
			error: function(response, ioArgs) {
				alert('Unable to update the list :( Please try again later.');
			}
		});
	},
	nextPage: function()
	{
		if (this.display_clusters) this.listClusters(this.page + 1); else this.setPage(this.page + 1);
	},
	prevPage: function()
	{
		if (this.display_clusters) this.listClusters(this.page - 1); else this.setPage(this.page - 1);
	},
    viewImage: function(code)
    {
		for (i in this.clusters) {
			var c = this.clusters[i];
			for (j in c.photos) {
				if (c.photos[j].code == code) {
					p = c.photos[j];
        			var h = '';
					h += '<img border=0 src="' + p.src + '_m.jpg" width=240 height=180>';
					h += '<p><b>By</b> '+ p.by;
					h += '<br><b>Location:</b> ' + p.place + ' ' + p.city + ' ' + p.state + ' ' + p.country;
					h += '</p>';
					h += '<p><b>TXT:</b> ' + p.txt + '</p>';
					h += '<p>View this arrow on the <a href="http://www.flickr.com/photos/yellowarrow/' + p.code + '/" target="_blank">YA Flickr site</a></p>';
        			this.getDom("info").innerHTML = h;
				}
			}
		}
    },
	viewImageInfo: function(id, code)
	{
		var c = this.clusters[id];
		for (i in c.photos) {
			p = c.photos[i];
			if (p.code == code) {
				this.bubble.openOnMarker(c.marker, this.getImageHTML(c, p));
				break;
			}
		}
	},
	displayList: function(id)
	{
		var i;
		var c = this.clusters[id];
        var h = '';
		this.activeCluster = id;
		this.num_page = Math.ceil(c.num_photo / this.per_page) | 0;
        for (i in c.photos) {
        	var p = c.photos[i];
        	h += '<img border=0 src="' + p.src + '_s.jpg" class="map-small-icon" onclick="' + this.id + '.viewImageInfo(' + id + ',\'' + p.code + '\')">';
        }
        this.getDom("list").innerHTML = h;
		this.updateButtons();
	},
	infoCluster: function(marker)
	{
		this.activeCluster = marker.cluster;
		var c = this.clusters[marker.cluster];
		this.display_clusters = false;
		this.page = 1;
		this.displayList(marker.cluster);
		/*
		if ((c.min_lat == c.max_lat) && (c.min_lng == c.max_lng)) {
			this.viewImageInfo(marker.cluster, c.photos[Math.floor(c.photos.length * Math.random())].code);
		} else this.zoom(c.lat, c.lng);		
		*/
		this.viewImageInfo(marker.cluster, c.photos[0/*Math.floor(c.photos.length * Math.random())*/].code);		
	},
	getImageHTML: function(c, p)
	{
		var h = '<div class="popup"><span class="black">Arrow:</span> ' + p.tag + ' <span class="black">By:</span> '+ p.by;
		h += '<br/><span class="black">Location:</span> '  + p.place + ' ' + p.city + ' ' + p.state + ' ' + p.country;
		if (c.num_photo > 1) {
			if (!c.collapsed) h += '<div class="small-text"><span class="black"><i>There are ' + c.num_photo + ' arrows nearby</i></span> <img src="images_map/zoom.gif" width="15" height="15" border=0 onclick="' + this.id + '.zoom(' + c.lat + ',' + c.lng + ')"></div>'; else h += '<div class="small-text">There are ' + c.num_photo + ' arrows here. Use the list below to view them.</div>';
		}
		h += '<table style="margin-top: 4px"><tr><td>';
		h += '<img border=0 src="' + p.src + '_t.jpg" width="100" height="75" border=0>';
		h += '</td><td valign="top" class="small-text"><div><span class="black">TXT:</span> ' + p.txt + '</div><div><a href="http://www.flickr.com/photos/yellowarrow/' + p.code + '/" target="_blank" class="popup-flickr"><img src="images_map/flicklink.png" border="0" /><span class="blue">YA Flickr site</span></a></div></td></tr></table>';
		h += '</div>';
		return h;
	},
	infoPoint: function(marker)
	{
        var c = this.clusters[marker.cluster];
        var p = c.photos[0];
		this.activeCluster = marker.cluster;
		this.page = 1;
		this.num_page = 1;
		this.getDom("list").innerHTML = '<a href="javascript:' + this.id + '.viewImageInfo(\'' + p.code + '\')"><img border=0 src="' + p.src + '_s.jpg" class="map-small-icon"></a>';
		this.bubble.openOnMarker(marker, this.getImageHTML(c, p));
		this.updateButtons();
	},
	selectCluster: function(id)
	{
		var i, j;
		for (i in this.clusters) {
			c = this.clusters[i];
			for (j in c.photos) {
				if (c.photos[j].code == id) {
					this.page = 1;
					this.display_clusters = false;
					this.displayList(i);
					return;
				}
			}
		}
	},
	listClusters: function(page)
	{
		var i;
		var h = '';
		var num_clusters = this.clusters.length;
		var start = (page - 1) * this.per_page;
		var end = Math.min(start + this.per_page, num_clusters);
		this.num_page = Math.ceil(num_clusters / this.per_page) | 0;
		for (i = start; i < end; i++) {
        	var p = this.clusters[i].photos[0];
        	h += '<img border=0 src="' + p.src + '_s.jpg" class="map-small-icon" onclick="' + this.id + '.viewImageInfo(' + i + ',\'' + p.code + '\')">';
        }
        this.getDom("list").innerHTML = h;
		this.display_clusters = true;
		this.page = page;
		this.updateButtons();
	},
	process: function(d)
	{
        var i, c;
        for (i in this.clusters) this.clusters[i].clear = true;
		oldActiveCluster = this.activeCluster;
        if (d.num_cluster) {
          for (i in d.clusters) {
            c = d.clusters[i];
			c.collapsed = (c.min_lat == c.max_lat) && (c.min_lng == c.max_lng);
            var found = false;
            for (j in this.clusters) {
              if (this.clusters[j].key == c.key && c.num_photo == this.clusters[j].num_photo) {
                this.clusters[j].clear = false;
				if (this.activeCluster == j) this.activeCluster = i;
                found = true;
                c.marker = this.clusters[j].marker;
                c.marker.cluster = i;
                break;
              }
            }
            if (found) continue;
            if (c.num_photo > 1) {
				marker = new google.maps.Marker(new google.maps.LatLng(c.lat, c.lng), {icon: this.iconCluster});
				this.gmap.addOverlay(marker);
				marker.setImage('icon.php?n=' + c.num_photo);
				google.maps.Event.addListener(marker, "click", function() { this.mv.infoCluster(this); });	
            } else {
				marker = new google.maps.Marker(new google.maps.LatLng(c.lat, c.lng), {icon: this.icon});
				this.gmap.addOverlay(marker);
				google.maps.Event.addListener(marker, "click", function() { this.mv.infoPoint(this); });
            }
            marker.mv = this;
            marker.cluster = i;
			c.marker = marker;
          }
        }
        for (i in this.clusters) {
          if (this.clusters[i].clear) {
			this.gmap.removeOverlay(this.clusters[i].marker);
			if (oldActiveCluster == i) this.resetList();
		  }
        }
        this.clusters = d.clusters;
		/*
		if (this.selectPhoto == 0 && this.clusters.length > 0) {
			var max_cluster = -1;
			for (i in this.clusters) {
				c = this.clusters[i];
				if (max_cluster < 0 || c.num_photo > this.clusters[max_cluster].num_photo)
					max_cluster = i;
			}
			this.selectPhoto = this.clusters[max_cluster].photos[0].code;
		}
		if (this.selectPhoto != 0) {
			this.selectCluster(this.selectPhoto);
			this.selectPhoto = 0;
		}
		*/
		this.listClusters(1);
		this.onPointChange();
		this.initial = false;
	},
	getBoundsURI: function()
	{
		var bounds = this.gmap.getBounds();
		var ne = bounds.getNorthEast();
		var sw = bounds.getSouthWest();
        var p1 = this.getXY(ne.lat(), ne.lng());
        var p2 = this.getXY(sw.lat(), sw.lng());
		return "ne_lat=" + ne.lat() + "&ne_lng=" + ne.lng() + 
          "&x1=" + p1.x + "&y1=" + p1.y +
          "&sw_lat=" + sw.lat() + "&sw_lng=" + sw.lng() +
          "&x2=" + p2.x + "&y2=" + p2.y +
          "&zoom=" + this.gmap.getZoom() + 
		  "&count=" + this.per_page;
	},
	updateMap: function()
	{
		var query = this.getBoundsURI();
		this.update_overlay.show();
      	dojo.xhrGet({
	        url: "get_map.php?" + query, 
        	handleAs: "json",
        	timeout: 60000,
			mv: this,
        	load: function(response, ioArgs) {
				this.mv.update_overlay.hide();
				this.mv.process(response);
			},
	        error: function(response, ioArgs) {
				this.mv.update_overlay.hide();
				alert("Unable to update the map :( Please try again later.");
          	}
        });
	},
	init: function()
	{
		if (!GBrowserIsCompatible()) return false;
		var map = new google.maps.Map2(this.getDom("gmap"));
		map.getContainer().style.overflow="hidden";
		map.setCenter(this.center, this.zoomLevel);
		map.addControl(new google.maps.SmallMapControl());
		map.setMapType(G_HYBRID_MAP);
		google.maps.Event.bind(map, "moveend", this, this.updateMap);
		var size = map.getSize();
		var x = (size.width - this.update_w) / 2;
		var y = (size.height - this.update_h) / 2;
		this.update_overlay = new google.maps.ScreenOverlay('images_map/updating_map.png', new google.maps.ScreenPoint(x, y), new google.maps.ScreenPoint(0, 0), new google.maps.ScreenSize(this.update_w, this.update_h));
		map.addOverlay(this.update_overlay);
		this.update_overlay.hide();
		this.gmap = map;
		var icon = new google.maps.Icon();
		icon.image = "images_map/sidewaysarrow.png";
		icon.shadow = "images_map/sidewaysarrow_shadow.png";
		icon.iconSize = new GSize(15.0, 21.0);
		icon.shadowSize = new GSize(15.0, 21.0);
		icon.iconAnchor = new GPoint(0.0, 12.0);
		icon.infoWindowAnchor = new GPoint(0.0, 12.0);		
		this.icon = icon;
        var iconCluster = new google.maps.Icon();
        iconCluster.image = "images_map/sidewaysarrow_large.gif";
        iconCluster.shadow = "images_map/sidewaysarrow_large.gif";
		iconCluster.iconSize = new GSize(23.0, 32.0);
		iconCluster.shadowSize = new GSize(23.0, 32.0);
		iconCluster.iconAnchor = new GPoint(0.0, 12.0);
		iconCluster.infoWindowAnchor = new GPoint(0.0, 12.0);		
        this.iconCluster = iconCluster;
		this.bubble = new EBubble(this.gmap, "images_map/bubble.png", new GSize(380,160), new GSize(355,140), new GPoint(15,10), new GPoint(0,80), true);  
		this.bubble.parent = this;
		this.bubble.onClose = function()
		{
			this.parent.listClusters(1);			
		};
		return true;		
	}
});