// Copyright Scott Penrose http://scott.dd.com.au/ 2008

Ext.onReady(function() {

	// DEBUG Counters
	var sequence = 0;

	// ----------------------------------------------------------------------
	// Icons
	// ----------------------------------------------------------------------
	var icons = {
		start: 0,
		finish: 0,
		turnpoint: 0,
		glider0: 0,
		glider1: 0,
		glider2: 0,
		glider3: 0
	};
	// TODO: Check colours are matching
	var icons_color = {
		glider0: '#9933ff',	// purple
		glider1: '#66ff33',	// green
		glider2: '#ff0000',	// red
		glider3: '#3366ff'	// blue
	};
	for (var t in icons) {
		icons[t] = new GIcon();
		icons[t].image = 'http://www.glidingmaps.com/flags/' + t + '.png';
		icons[t].shadow = 'http://www.glidingmaps.com/flags/shadow.png';
		icons[t].iconSize = new GSize(20,34);
		icons[t].shadowSize = new GSize(20,34);
		icons[t].iconAnchor = new GPoint(10, 34); 
		icons[t].infoWindowAnchor = new GPoint(20, 3); 
	}

	// ----------------------------------------------------------------------
	// Marker storage
	// ----------------------------------------------------------------------
	// List of gliders, and their details
	var gliders = {};
	/*
	Example of marker data
	  {
		"latitude" : -36.55125,			Current coordinates for marker
		"longitude" : 146.005466666667,		
		"title" : "VH-GJS",			Title for popup
		Other details, like photo		For popup
		color, type, etc			How to render this icon
		points: [],				Previous points for polygon
		pilot
	  },
	*/
	// List of task points (in order) and their details
	var tasks = [
		{
			"latitude" : -36.55125,
			"longitude" : 146.005466666667,
			"title" : "Start",
			"type" : 'start'
		},
		{
			"latitude" : -36.25125,
			"longitude" : 146.635466666667,
			"title" : "Turn one",
			"type" : 'turnpoint'
		},
		{
			"latitude" : -36.75125,
			"longitude" : 146.305466666667,
			"title" : "Turn two",
			"type" : 'turnpoint'
		},
		{
			"latitude" : -36.95125,
			"longitude" : 146.405466666667,
			"title" : "Finish",
			"type" : 'finish'
		}
	];

	// ----------------------------------------------------------------------
	// Main map window
	// ----------------------------------------------------------------------
	var mapwin = new Ext.ux.GMapPanel({
		title: 'Map Window',
		region: 'center',
		zoomLevel: 14,
		gmapType: 'map',
		mapConfOpts: ['enableScrollWheelZoom','enableDoubleClickZoom','enableDragging'],
		mapControls: ['GSmallMapControl','GMapTypeControl','NonExistantControl'],
		// XXX this version does not seem to call init by adding the GEvent
		//		the load event is added but never fires
		//		Yet a simple example using markers here it does work !
		// Temporary set centre to Benalla for start up
		setCenter: {
			lat: -36.55125,
			lng: 146.005466666667
		},
		tbar: [
			{
				text: 'Init',
				handler: function(){
					mapwin.onMapReady();
					initTasks();
					zoomTask();
				}
			},
			{
				text: 'Zoom Gliders',
				handler: function(){
				    zoomGliders();
				}
			},
			{
				text: 'Zoom Task',
				handler: function(){
				    zoomTask();
				}
			}
		]
	});

	// ----------------------------------------------------------------------
	// Basic Layout
	// ----------------------------------------------------------------------
	new Ext.Viewport({
		layout:'border',
		// XXX layoutConfig or defaults ?
		defaults: {
			split: true,
			bodyStyle: 'padding:0px'
		},
		items: [
			// outer - west
			{
				collapsible: true,
				layout: 'accordion',
				minSize: 100,
				width: 200,
				region:'west',
				layoutConfig: {
					titleCollapse: true,
					animate: true
				},
				items: [
					{
						title: 'Gliders',
						html: '<ul id="gliders-list"></ul>',
						// autoHeight: true,
						border: false,
						margins: '0 0 5 0'
					},
					{
						title: 'Task',
						html: '<h1>Page Title</h1><ul id="tasks-list"></ul>',
						// autoHeight: true,
						border: false,
						margins: '0 0 5 0'
					},
					{
						title: 'Leader Board',
						html: '<h1>Page Title</h1><ul id="leaders-list"></ul>',
						// autoHeight: true,
						border: false,
						margins: '0 0 5 0'
					}
				]
			},
			// outer - center
			mapwin
		]
	});

	// ----------------------------------------------------------------------
	// Get data every n seconds
	// ----------------------------------------------------------------------
	var doUpdate = function() {
		sequence++;		// Which one are we up to (because this is not real time)
		Ext.Ajax.request({
			url : 'get.cgi',
			params: {
				sequence: sequence
			},
			failure: function(result,request) { 
				Ext.MessageBox.alert('Failed', 'To process notification: '+result.responseText); 
			}, 
			success: function(result, request) {
				var results = Ext.util.JSON.decode(result.responseText).results;
				if (results.length) {
					for (var i = 0; i < results.length; i++) {
						var entry = results[i];

						if (gliders[entry.glider_id] == undefined) {
							gliders[entry.glider_id] = {
								type: entry.glider_type,
								title: entry.title,
								pilot: entry.pilot
							};
						}
						gliders[entry.glider_id].latitude = entry.latitude;
						gliders[entry.glider_id].longitude = entry.longitude;
						// console.log(gliders[entry.glider_id]);
						initMarker(entry.glider_id);
					}
				}
				else {
					clearInterval(intervalUpdate);
					Ext.MessageBox.alert('Complete', 'Race complete');
				}
			}
		});
	};
	var intervalUpdate = setInterval(doUpdate, 2500);       // 10 seconds

	// ----------------------------------------------------------------------
	// init a new marker - assumes lat and long are already set
	var deselectCurrent = undefined;	// Place holder for function to unselect
	var initMarker = function(id) {
		// Always set a new point (as they are read only)
		gliders[id].point = new GLatLng(gliders[id].latitude, gliders[id].longitude);

		// CREATE NEW MARKER
		if (gliders[id]['marker'] == undefined) {
			gliders[id].marker = new GMarker(
				gliders[id].point, 
				{
					draggable: false, 
					title: gliders[id].title,
					icon: getIcon(gliders[id].type)
				}
			);
			// Add to map
			mapwin.getMap().addOverlay(gliders[id].marker);

			// icon of glider
			var iUrl = 'http://www.glidingmaps.com/flags/' + gliders[id].type + '.png';
			
			// Keep the polyline for moving gliders
			gliders[id].pointcount = 0;
			gliders[id].polyline = new GPolyline([gliders[id].point], getColor(gliders[id].type), 3, 0.75);
			mapwin.getMap().addOverlay(gliders[id].polyline);

			// Create list entry
			gliders[id].listItem = document.createElement('li'); 
			var listItemLink = gliders[id].listItem.appendChild(document.createElement('a')); 
			listItemLink.href = "#"; 
			listItemLink.innerHTML = ''
				+ '<img src="' + iUrl + '"/>'
				+ '<strong>' + gliders[id].title + '</strong><br/>'
				+ gliders[id].type + '<br/>'
				+ gliders[id].pilot + '<br/>'
			;

			// Add event handler
			var focusPoint = function() {
				if (deselectCurrent) {deselectCurrent(); }
				gliders[id].listItem.className = 'current';
				gliders[id].listItem.focus();
				deselectCurrent = function() { gliders[id].listItem.className = ''; };
				gliders[id].marker.openInfoWindowTabsHtml([
					new GInfoWindowTab("Info", '' 
						+ '<div class="infowindow">'
						+ '<img src="' + iUrl + '"/>'
						+ '<div class="title">' + gliders[id].title + '</div>'
						+ '<div class="type">Type: ' + gliders[id].type + '</div>'
						+ '</div>'
					),
					new GInfoWindowTab("View", '' 
						+ 'TODO'
					)
				]);
				mapwin.getMap().panTo(gliders[id].point); 

				// Scroll the list (TODO better offset code than guess of 25)
				document.getElementById('gliders-list').scrollTop = listItemLink.offsetTop - 195;

				return false; 
			};
			GEvent.addListener(gliders[id].marker, 'click', focusPoint); 
			listItemLink.onclick = focusPoint; 

			// Show the list entry
			document.getElementById('gliders-list').appendChild(gliders[id].listItem); 
		}

		// MOVE EXISTING MARKER (and Track)
		else {
			gliders[id].marker.setPoint(gliders[id].point);
			gliders[id].pointcount++;
			gliders[id].polyline.insertVertex(gliders[id].points, gliders[id].point);
		}
	};

	// ----------------------------------------------------------------------
	// Zoom all (public?)
	var zoomGliders = function() {
		var bounds = new GLatLngBounds();
		for (var id in gliders) {
			// Check if they are on or off?
			bounds.extend(gliders[id].marker.getPoint());
		} 
		var map = mapwin.getMap();
		map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));
	};

	// ----------------------------------------------------------------------
	// Zoom tasks (public?)
	var zoomTask = function() {
		var bounds = new GLatLngBounds();
		for (var id = 0; id < tasks.length; ++id) {
			// Check if they are on or off?
			bounds.extend(tasks[id].marker.getPoint());
		} 
		var map = mapwin.getMap();
		map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));
	};

	// ----------------------------------------------------------------------
	// Currently call one off to init the tasks
	var initTasks = function() {
		// Init and add to map (TODO: Icon)
		var points = [];
		for (var id = 0; id < tasks.length; ++id) {
			tasks[id].point = new GLatLng(tasks[id].latitude, tasks[id].longitude);
			tasks[id].marker = new GMarker(tasks[id].point, {draggable: false, title: tasks[id].title, icon: getIcon(tasks[id].type)});
			mapwin.getMap().addOverlay(tasks[id].marker);
			points.push(tasks[id].point);

			// icon of glider
			var iUrl = 'http://www.glidingmaps.com/flags/' + tasks[id].type + '.png';
			
			// Create list entry
			tasks[id].listItem = document.createElement('li'); 
			var listItemLink = tasks[id].listItem.appendChild(document.createElement('a')); 
			listItemLink.href = "#"; 
			listItemLink.innerHTML = ''
				+ '<img src="' + iUrl + '"/>'
				+ '<strong>' + tasks[id].title + '</strong><br/>'
				+ tasks[id].type + '<br/>'
			;

			// Add event handler
			var focusPoint = makeTaskFocus(id, iUrl);
			GEvent.addListener(tasks[id].marker, 'click', focusPoint); 
			listItemLink.onclick = focusPoint; 

			// Show the list entry
			document.getElementById('tasks-list').appendChild(tasks[id].listItem); 
		}
		// Back to first point
		points.push(tasks[0].point);
		mapwin.getMap().addOverlay(new GPolyline(points));
	};
	//initTasks();
	//zoomTask();

	var makeTaskFocus = function(id, iUrl) {
		return function() {
			// NOTE: This is the same to allow deslect of either lists !  see focusPoint in gliders
			if (deselectCurrent) {deselectCurrent(); }
			tasks[id].listItem.className = 'current';
			tasks[id].listItem.focus();
			deselectCurrent = function() { tasks[id].listItem.className = ''; };
			tasks[id].marker.openInfoWindowTabsHtml([
				new GInfoWindowTab("Info", '' 
					+ '<div class="infowindow">'
					+ '<img src="' + iUrl + '"/>'
					+ '<div class="title">' + tasks[id].title + '</div>'
					+ '<div class="type">Type: ' + tasks[id].type + '</div>'
					+ '</div>'
				)
			]);
			mapwin.getMap().panTo(tasks[id].point); 

			// Scroll the list (TODO better offset code than guess of 25)
			document.getElementById('tasks-list').scrollTop = listItemLink.offsetTop - 195;

			return false; 
		};
	};

	// ----------------------------------------------------------------------
	// Little Helpers
	// ----------------------------------------------------------------------
	// get a valid icon, or default
	var getIcon = function(type) {
		var i = G_DEFAULT_ICON;
		if (icons[type]) {
			i = icons[type];
		}
		return i;
	};
	// And the icons color
	var getColor = function(type) {
		var i = '#ff0000';
		if (icons_color[type]) {
			i = icons_color[type];
		}
		return i;
	};

	// HACKS - since 'load' method does not work, run this after 1 second
	setTimeout(function() {
		mapwin.onMapReady();
		initTasks();
		zoomTask();
	}, 1000);


});
