/*	usemedia.com . joes koppers . 01.2010
	thnx for reading this code */


/*	Laptop Reflections Mapview
*/

function Map()
{
	//settings
	this.startDate = new Date(2009,3,1).getTime(); //01-04-09, 00:00;
	this.maps = {
		luna:{ name:'Luna' },
		jonathan:{ name:'Jonathan' },
		roel:{ name:'Roel' },
		edo:{ name:'Edo' }
	};
	this.tours = {};
	this.view = 'map'; //current view mode, map|tour
	
	//map keys, laptopreflections.org and .com
	if (window.location.host.indexOf('.org')!=-1)
	{
		this.Gkey = 'ABQIAAAA6wAMqFuY8aYUX67TtQkcKRQuCcAdPiU_-0BBZoqOzTBlroetkRSj-7thxU_AodPBT7TUoD6w0b-lxw';
	}
	else
	{
		this.Gkey = 'ABQIAAAA6wAMqFuY8aYUX67TtQkcKRQD9QIUPm0dH-Fhgw5UQU7wxSHyXxSk_FBLsI1khb_5opxEf75XBgm_JA';
		if (window.location.host=='cd')
		{
			//local development key
			this.local = true;
			this.Gkey = 'ABQIAAAA6wAMqFuY8aYUX67TtQkcKRTbrMQeB9LWcJvZRGtNXjyYf_RYxRRrhawvN3HtkDE1O8vnw_XrIgtWGg';
		}
	}

	/*	init maps and Gui
	*/
	this.addGMaps();
}

Map.prototype.addGMaps = function()
{
	/*	load google js and maps api
	*/
	var obj = this;
	$.getScript('http://www.google.com/jsapi?key='+this.Gkey,function() {
		//get latest v2 stable
		google.load('maps','2',{ callback:function() { 
			obj.createMaps();			
		} });
	});
}

Map.prototype.createMaps = function()
{
	/*	create custom maps
	*/
	var obj = this;
 	var maptypes = [];
 	var c = new google.maps.CopyrightCollection();
 		c.addCopyright(new google.maps.Copyright(1,new google.maps.LatLngBounds(new google.maps.LatLng(-90, -180), new google.maps.LatLng(90, 180)),0,'Conditional Design'));
 		
 	$.each(this.maps, function(id) {

 		this.tilelayers = [new google.maps.TileLayer(c,1,8)];
 		this.tilelayers[0].getTileUrl = function(a,b) {
 			if (obj.local) return 'tiles-'+id+'/'+b+'_'+a.x+'_'+a.y+'.jpg';
 			var s = ((a.x + a.y) % 3) + 1;
 			return 'http://t'+s+'.laptopreflections.org/tiles-'+id+'/'+b+'_'+a.x+'_'+a.y+'.jpg';
 		};
 		
 		this.map = new google.maps.MapType(this.tilelayers,new google.maps.MercatorProjection(9),this.name, { errorMessage:'' });
 		
 		maptypes.push(this.map);
 	});
 	
	/*	create gmap
	*/
	var map = new google.maps.Map2($('#map').get(0),{ mapTypes:maptypes, backgroundColor:'#ffffff' });
		map.enableContinuousZoom();
		//map.addControl(new google.maps.OverviewMapControl());
		map.addControl(new google.maps.LargeMapControl3D());
		map.addControl(new google.maps.MapTypeControl(),new google.maps.ControlPosition(google.maps.ANCHOR_TOP_RIGHT,new google.maps.Size(15,13)));
		
	//init
	map.setCenter(new google.maps.LatLng(0,0), 1, this.maps.luna.map);
			
	this.gmap = map;
	
	//add shadow
	$.each(['top','right','bottom','left'], function(i,v) {
		$('<div></div>')
			.addClass('map-shadow '+v)
			.insertAfter('#map > div:first');
	
	});
	
	//event handling
	var obj = this;
	google.maps.Event.addListener(map,'mousemove',function(p) {
		obj.getTimeFromLatLng(p);
	});

	//attach date tooltip to mouse and show while shift-key is pressed
	$(document)
		.keydown(function(e) {
			if (e.shiftKey)
			{
				$('#date').fadeIn('fast');
			}
		})
		.keyup(function(e) {
			$('#date').fadeOut('fast');
		})
		.mousemove(function(e) {
			$('#date').css({
				left:e.clientX+8,
				top:e.clientY+8
			});
		});
		
	this.createGui();
}

Map.prototype.getTimeFromLatLng = function(p)
{
	/*	display date and time for geo location
	*/
	
	//column: 260 days divided over -180 to +180 degrees longitude
	var col = 130 + Math.floor((130/180) * p.lng());

	//row: 288 captures over 27280 pixels at zoom level 7 (calculated in pixels, as latitude varies depending on longitude)
	var px = new google.maps.MercatorProjection(8).fromLatLngToPixel(p,7);
	var row = 144 + Math.floor((px.y-16384) / (27280/288));

	//convert to time
	var d = new Date(this.startDate);
		d.setDate(d.getDate()+col);
		d.setTime(d.getTime()+row*5*60*1000);
	
	//display in date tooltip
	$('#date').html(d.format('longhumandate',' - ','time'));
}

Map.prototype.getLatLngFromTime = function(t)
{
	/*	center map to geolocation for given time-index
	*/
	
	//get column and row from time index
	t--;
	var col = Math.floor(t/288);
	var row = t - (col*288);
	
	//get pixel location at zoom level 7 (32768 x 27280)
	var x = (col * 32768/260) + (32768/260/2);
	var y = (16384 + ((row-144) * 27280/288)) + (27280/288/2);

	//center map at zoom level 8
	var p = new google.maps.MercatorProjection(8).fromPixelToLatLng(new google.maps.Point(x,y),7);
	this.gmap.setCenter(p,8);
	
	//update date tooltip
	this.getTimeFromLatLng(p);
}

Map.prototype.getTours = function()
{
	/*	get tours for each map
	*/
	var obj = this;
	$.each(this.maps, function(id) {

		$.getJSON('tours/?tour='+id,function(rsp) {
			obj.maps[id].toursloaded = true;

			if (!rsp.isError)
			{
				//create tour object for each tour on this map
				obj.tours[id] = new Array();
				$.each(rsp.tours, function(i,tour) {
					obj.tours[id].push(new Tour(obj,id,tour.name,tour.captures));
				});
			}
		});
	});
	
	this.listTours();
}

Map.prototype.createGui = function()
{
	/*	info panel
	*/
	var panel = $('<div></div>')
		.attr('id','info-panel')
		.html($('#info').html())
		.insertBefore('#map > .gmnoprint:last')
		.append($('<div class="shadow"></div>'));
	
	//add expand/collapse to title
	$('#title')
		.data('collapsed',false)
		.click(function() {

			var c = $(this).data('collapsed');
			$(this)
				.blur()
				.css('background-image','url(media/title-'+(c? 'default':'collapsed')+'.png)')
				.next()[c? 'show':'hide']();

			//toggle
			$(this).data('collapsed',!c);
		});

	/*	get and display tours
	*/
	this.getTours();
}

Map.prototype.listTours = function()
{
	var obj = this;

	//wait for tours in all maps to be loaded..
	var done = true;
	$.each(this.maps, function(id) { if (!this.toursloaded) done = false; })
	if (!done) return window.setTimeout(function() { obj.listTours() },100);

	//list available tours for each map
	$.each(this.maps, function(id) {

		var tour = obj.tours[id];
		if (!tour) return true;
	
		var item = $('<div></div>')
			.addClass('tour')
			.html('<select></select>'+obj.maps[id].name)
			.appendTo('#tours');
				
		//add select options
		var n=0;
		$.each(tour, function() {
			$(item).find('select').append('<option value="'+n+'">'+this.name+'</option>');
			n++;
		});

		//add go link	
		$('<a>')
			.attr('href','javascript://tour')
			.html('go')
			.click(function() {
				tour[$(this).next().val()].start();
			})
			.insertBefore($(item).find('select'));
	});
}

Map.prototype.toggleView = function(mode)
{
	/*	toggle between map and tour layout
	*/	
	this.view = mode;	
	$('#info-panel a:first')
		.data('collapsed',mode=='tour'? false:true)
		.click();
	
	$('#tour-overlay')[mode=='tour'? 'fadeIn':'fadeOut']('slow');
}

function Tour(map,maptype,name,captures)
{
	this.map = map;
	this.maptype = maptype;
	this.name = name;
	this.captures = captures;

	this.speed = 2500; //time in ms between captures;
	this.paused = true;
}

Tour.prototype.start = function()
{
	/*	enter tour view and start playing
	*/
	this.map.toggleView('tour');
	
	//title, navigation
	$('#tour-detail').html('Tour "'+this.name+'", <span>1</span>/'+this.captures.length);
	$.each(['previous','pause','next'], function(i,v) {
	
		$('<a/>', {
			href:'javascript://'+v,
			html:v,
			click:function(event) {
				$(this).blur();
				obj[v]();
				event.stopPropagation();
			}
		}).appendTo('#tour-control');
	});
	
	//attach stop event to tours-overlay
	var obj = this;
	$('#tour-overlay')
		.unbind()
		.click(function() {
			obj.stop();
		});
		
	this.map.gmap.setMapType(this.map.maps[this.maptype].map);
	this.index = -1;
	this.resume();
}

Tour.prototype.go = function(index)
{
	/*	display capture at index
	*/
	if (!index) index = this.index;
	$('#tour-detail').find('span').html(index+1);
	this.map.getLatLngFromTime(this.captures[index]);
}

Tour.prototype.playing = function()
{	
	this.index++;
	
	if (this.index==this.captures.length)
	{
		this.pause();
	}
	else
	{
		if (this.paused) return;

		this.go();	
		
		var obj = this;
		this.play = window.setTimeout(function() {
			obj.playing();
		},this.speed);
	}
}

Tour.prototype.pause = function()
{
	if (this.play) window.clearInterval(this.play);
	
	$('#tour-control').find('a').eq(1).html(this.paused? 'pause':'play');
	if (this.paused) return this.resume();

	this.paused = true;
}

Tour.prototype.resume = function()
{
	if (this.index==this.captures.length) this.index = -1;
	this.paused = false;
	this.playing();
}

Tour.prototype.previous = function()
{
	if (!this.paused) this.pause();
	this.index--;
	if (this.index<0) this.index = this.captures.length-1;
	this.go();
}

Tour.prototype.next = function()
{
	if (!this.paused) this.pause();
	this.index++;
	if (this.index==this.captures.length) this.index = 0;
	this.go();
}

Tour.prototype.stop = function()
{
	if (!this.paused) this.pause();
	$('#tour-detail,#tour-control').empty();
	this.map.toggleView('map');	
}