/**
 * Fleet tracking event handler package for the gps autotracker app
 */
com_starsensortech_www_atms_fastrack_client = new es_lang.Package(true,
	/*Title*/   'Testing Package',
	/*Docs */   '-- none --',
	/*Package*/ function() {
		// Packages
		var LANG = es_lang;
		var LOG = es_util_logging;
		var NET = es_net;
		var WU = com_pagasg_www_util;
		var XSER = com_pagasg_xxapp_serialize;
		var FXT = com_pagasg_www_fx_transition;
		var MPNG = com_starsensortech_www_atms_mapping;
		var FST = com_starsensortech_www_atms_fastrack;
		
		var NS = FST.NS;

		// Constructors
		var Class = es_lang.Class;
		var Enum = es_lang.Enum;
		var StringBuilder = LANG.StringBuilder;

		var Transition = FXT.Transition;
		var Animation = FXT.Animation;

		var Objects = WU.Objects;
		var Elements = WU.Elements;
		var Strings = WU.Strings;
		var Inputs = WU.Inputs;
		var Converter = MPNG.Converter;
		var MapController = MPNG.MapController;
		var Point = MPNG.Point;
		var Extent = MPNG.Extent;
		var Handle = MPNG.Handle;
		var Dot = MPNG.Dot;
		var Ellipse = MPNG.Ellipse;

		var Cycle = WU.Cycle;

		var WebApplication = FST.WebApplication;
		var GpsFixStatus = FST.GpsFixStatus;

		// Functions
		var extend = Class.extend;
		var implement = Class.implement;
		var enumerate = Enum.enumerate;

		// ****** EventHandler ******
		var Console = {
			// Properties
			logger: LOG.Logger.getLogger('com.starsensortech.www.atms.fastrack.client.EventHandler'),
			webapp: undefined,

			// Implementation
			startup: function(webapp) {
				var logger = Console.logger;
				var session = webapp.session;
				var poller = webapp.poller;

				// Init
				Console.webapp = webapp;

				// Private
				var AddressPainter = function(unit) {
					this.painter = function() {
						var speed;
						var buf = new StringBuilder();
						var unitXml = unit.xml;
						var locationXml = unitXml.getChild('last-location');
						var heading = parseInt(Strings.testDefault(locationXml.getChild('heading')));
						var speed = parseInt(Strings.testDefault(locationXml.getChild('speed')));
						var fixTime = parseInt(locationXml.getChild('gpsfix-time'));
						var parts = MapController.splitAddress(this.address);
						var serialNumber = unitXml.getChild('serialnumber').text;
						var factorySN = unitXml.getChild('factory-serialnumber').text;
						
						buf.append('<div style="font-size:90%;width:25em;">');
						buf.append('<b>Unit</b>: ');
						buf.append(unitXml.getAttribute('display', NS.atms));
						buf.append('<br/><b>ID</b>: ');
						buf.append(factorySN);
						if (factorySN != serialNumber) {
							buf.append(' (' + serialNumber + ')');
						}
						buf.append('<br/><b>Rpt-ID</b>: ').append(locationXml.getChild('serial'));

						if (fixTime) {
							buf.append('<br/><b>Time of Fix</b>: ');
							buf.append(webapp.formatter.formatAge(fixTime, ' old'));
						}
						if (heading && speed && (speed > 8)) {
							buf.append('<br/><b>Moving: </b>');
							buf.append(MapController.getHeadingName(heading)).append(' at: ');
							buf.append(parseInt(speed / 1.6) + ' mph');
						} else {
							buf.append('<br/><b>Moving: </b>0 to 5 mph');
						}

						if (parts) {
							buf.append('<div>');
							buf.append('<div style="float:left;"><b>Address</b>:<br/><br/><br/></div>');
							buf.append('<div>');
							if (parts.street) buf.append(parts.street);
							if (parts.city) buf.append('<br/>' + parts.city);
							if (parts.statezip) buf.append(', ' + parts.statezip);
							if (parts.country) buf.append('<br/>' + parts.country);
							buf.append('</div>');
						} else {
							buf.append('<br/>' + this.address);
						}

						buf.append('</div>');
						
						return buf.toString();
					}
				}

				/* Session */
				session.onLogon.addListener(
					function(event) {
						poller.period = 20000;

						//poller.start();
						poller.poll();
					}
				);
				session.onLogoff.addListener(
					function(event) {
						poller.stop();
					}
				);
				webapp.units.onEndTransaction.addListener(function(event) {
					var tran;
					var unitKey;
					var unit;
					var units = event.target;
					var transactions = event.context;

					function handler(event) {
						var lat, lng;
						var selected;
						var unit = event.target;
						var unitXml = unit.xml;
						var uuid = unitXml.getAttribute('external-id', NS.atms);
						var locationXml = unitXml.getChild('last-location');

						if (locationXml) {
							lat = Strings.testEmpty(locationXml.getChild('latitude'));
							lng = Strings.testEmpty(locationXml.getChild('longitude'));

							if (lat && lng) {
								shape = Console.touchShape(uuid, lng, lat)
								if (shape) {
									shape.paintAddress = new AddressPainter(unit).painter;

									if (unit.isSelected()) {
										shape.show();
									} else {
										shape.hide();
									}
								}
							}
						} else if (unit.isSelected()) {
							alert('This unit has not yet reported it\'s location');
							unit.deselect();
						}
					}

					for (var i = 0; i < transactions.length; i++) {
						tran = transactions[i];
						unit = tran.context.value;
						unitKey = tran.context.key;

						if (tran.type == 'onAdd') {
							unit.onSelect.addListener(handler);
							unit.onDeselect.addListener(handler);
						} else if (tran.type == 'onRemove') {
						} else if (tran.type == 'onChange') {
						}
					}
				});
				webapp.units.onSelect.addListener(function(event) {
					var lat, lng;
					var reportXml;
					var unitKey = event.context.key;
					var unit = event.context.value;
					var priorUnitKey = event.context.priorKey;
					var priorUnit = event.context.priorValue;
					var unitXml = unit.xml;
					var reportXml = unitXml.getChild('last-location');

					if (unit) {
						if (reportXml) {
							lat = Strings.testEmpty(reportXml.getChild('latitude'));
							lng = Strings.testEmpty(reportXml.getChild('longitude'));

							shape = Console.touchShape(unitKey, lng, lat)
							if (shape) {
								shape.paintAddress = new AddressPainter(unit).painter;
								shape.activate();

								if (priorUnit && !priorUnit.isSelected()) {
									shape = webapp.shapes.get(priorUnitKey);
									if (shape) shape.hide();
								}
							}
						}
					}
				});
				webapp.queries.onAdd.addListener(function(event) {
					var context = event.context;
					var url = context.key;
					
					Console.queryListeners(url);
				});
				webapp.reports.onAdd.addListener(function(event) {
					var lat, lng;
					var shape;
					var fixType;
					var id;
					var unit;
					var unitKey;
					var unitXml;
					var reportXml = event.context.value;
					var unitId = reportXml.getChild('unit').text;
					var units = webapp.units;

					webapp.logger.info('Invoking onadd ...');

					units.getValues(function(key, value) {
						unitXml = value.xml;
						id = unitXml.getAttribute('id', NS.atms);
						if (id == unitId) {
							unit = value;
							unitKey = key;
						}
					});

					if (unitKey) {
						unit.setLastReport(reportXml);
						webapp.shapes.get(unitKey);
						fixType = reportXml.getChild('gpsfix-type').text;

						if (fixType != 'no-fix') {
							lat = Strings.testEmpty(reportXml.getChild('latitude'));
							lng = Strings.testEmpty(reportXml.getChild('longitude'));

							shape = Console.touchShape(unitKey, lng, lat)
							if (shape) {
								shape.follow = true;
								shape.activate();
								alert('The unit was located');
							}
						} else {
							alert('The unit was unable to get a GPS fix');
						}
					} else {
						alert('The unit id: ' + unitId);
					}
				});

				// Primary page load handler
				var loadPage = function(pageName) {
					var conn;
					var loader;
					var blocks = [ 'list-guts-block', 'list-options-block' ];

					if (webapp.session.isLoggedOn()) {
						conn = new URLConnection('/shell/' + pageName + '-profile.html');
						
						loader = function(doc) {
							var sink
							var source;

							for (var i = 0; i < blocks.length; i++) {
								source = doc.getElementById(blocks[i]);
								sink = document.getElementById(blocks[i]);

								if (source && sink) {
									sink.innerHTML = source.innerHTML
								}
							}
						}
						
						conn.open(loader, 20000);
					}
				}
				webapp.session.onLogon.addListener(function(event) {
					//alert('loading once for the session');
					//loadPage(webapp.page.getName() || 'ondemand');
				});
				webapp.page.onOpen.addListener(function(event) {
					var context = event.context;
					//alert('loading once for the page change');
					loadPage(context.name || 'ondemand');
				});
				
				// FST.WebApplication.onActivation
				webapp.activation.onHandleResponse.addListener(
					function(event) {
						var stage;
						var stageNbr;
						var length;
						var newHash;
						var contactXml;
						//var activationXml;
						//var responseXml = event.context;
						var activationXml = event.context;
						
						//activationXml = responseXml.getChild('activation', NS.fst);
						contactXml = activationXml.getChild('contact');
						stage = activationXml.getChild('stage').toString();

						if ((contactXml) && (stage == 'step1' || stage == 'step2')) {
							WU.Frames.setHash('step3');
						} else {
							length = stage.length;
							stageNbr = parseInt(stage.substring(stage.length-1));
							stageNbr = stageNbr + 1;
							newHash = 'step' + stageNbr;
							//alert ('newHash; ' + newHash)
							WU.Frames.setHash(newHash);
						}
					}
				);
				
				
				// this needs to be updated/changed
				function updateFromLocate (event) {
					var lat, lng;
					var shape;
					var fixType;
					var id;
					var unit;
					var unitKey;
					var unitXml;
					//var reportXml = event.context.value;
					var unitId = reportXml.getChild('unit').text;
					var units = webapp.units;

					webapp.logger.info('Invoking onadd ...');

					units.getValues(function(key, value) {
						unitXml = value.xml;
						id = unitXml.getAttribute('id', NS.atms);
						if (id == unitId) {
							unit = value;
							unitKey = key;
						}
					});

					if (unitKey) {
						unit.setLastReport(reportXml);
						webapp.shapes.get(unitKey);
						fixType = reportXml.getChild('gpsfix-type').text;

						if (fixType != 'no-fix') {
							lat = Strings.testEmpty(reportXml.getChild('latitude'));
							lng = Strings.testEmpty(reportXml.getChild('longitude'));

							shape = Console.touchShape(unitKey, lng, lat)
							if (shape) {
								shape.follow = true;
								shape.activate();
								alert('The unit was located');
							}
						} else {
							alert('The unit was unable to get a GPS fix');
						}
					} else {
						alert('The unit id: ' + unitId);
					}
				}
			},
			touchShape: function(shapeId, lng, lat, radius, buildHandle) {
				var pt;
				var handle;
				var shapes = Console.webapp.shapes;
				var shape = shapes.get(shapeId);

				if (Console.webapp.mapController) {
					if (shape == null) {
						if (buildHandle) {
							handle = buildHandle();
						} else {
							handle = new Handle('/_img/map/pin/roundhead.png');
							handle.extent = new Extent(21, 24);
							handle.control = new Point(12, 22);
							handle.center = new Point(31, 8);
						}
						shape = Console.initShape(lng, lat, radius, handle);
						shapes.put(shapeId, shape);
						Console.webapp.mapController.registerShape(shape);
					} else if (lat && lng) {
						pt = new MPNG.Point(lng, lat);
						shape.moveTo(pt);
					}
				}
				return shape;
			},
			initShape: function(lng, lat, radius, handle) {
				var pt;
				var shape;
				var axes;
				var rlat;
				var rlng;
				var radius = radius || 20;

				pt = new Point(parseFloat(lng), parseFloat(lat));

				rlat = Converter.meters2Lat(radius);
				rlng = Converter.meters2Lon(pt.y, radius);
				axes = new Point(rlng, rlat);

				shape = new Ellipse(pt, axes, 16);
				shape.fillColor = '#939';
				shape.fillOpacity = .5;
				shape.strokeWidth = 1;
				shape.strokeColor = '#999';
				shape.strokeOpacity = 1;
				shape.visible = false;
				shape.activated = false;
				shape.zoomlevel = 14;
				shape.handle = handle;

				return shape;
			},
			handleQueryClick: function(checkbox, url, refId) {
				var query = this.webapp.queries.get(url);

				if (query) {
					if (checkbox.checked) {
						query.mark(refId);
					} else {
						query.unmark(refId);
					}
				} else {
					// LOG THE ERROR
				}
			},
			
			queryListeners: function(url) {
				var query = this.webapp.queries.get(url);

				// FIX THIS!
				if (!query || !query.onMark) {
					return;
				}
				
				function handleQueryImg(rowXml) {
					var imgPath;
					var xmlAlert = rowXml.getChild('alert');
					var xmlSpeed = rowXml.getChild('speed');

					if ((xmlSpeed > 5) && (xmlAlert)) {
						imgPath = '/_img/map/pin/moving-alert.png';
					} else if ((xmlSpeed > 0) && (!xmlAlert)) {
						imgPath = '/_img/map/pin/moving.png';
					} else if ((xmlSpeed <= 5) && (xmlAlert)) {
						imgPath = '/_img/map/pin/stopped-alert.png';
					} else if ((xmlSpeed <= 5) && (!xmlAlert)) {
						imgPath = '/_img/map/pin/stopped.png';
					}
					return imgPath;
				}
				
				query.onMark.addListener(function(event) {
					var lat, lng;
					var rowXml;
					var externalId;
					var shape;
					var imgPath;
					var eventMap = event.context;
					var queryXml = query.getXml();
					var mc = Console.webapp.mapController;
					var shapes = Console.webapp.shapes;
					
					
					for (var key in eventMap) {
						externalId = key;
						rowXml = queryXml.getChildByIndex(eventMap[key]);
						if (rowXml) {
							imgPath = handleQueryImg(rowXml);
							lat = rowXml.getChild('latitude');
							lng = rowXml.getChild('longitude');
						}
						
						if (lat && lng) {
							if ((lat != '0.000000') && (lng != '0.000000')) {
								shape = Console.touchShape(externalId, lng, lat, null, function() {
									var handle = new MPNG.Handle(imgPath);
									handle.extent = new MPNG.Extent(36, 36);
									handle.control = new MPNG.Point(18, 18);
									handle.center = new MPNG.Point(18, 18);
									handle.moveable = true;
									return handle;
								});
								
								if (shape) {
									shape.show();
								}
							}
						}
					}
				});
				query.onUnmark.addListener(function(event) {
					var externalId;
					var shape;
					var eventMap = event.context;
					var shapes = Console.webapp.shapes;
					
					for (var key in eventMap) {
						externalId = key;
						shape = shapes.get(externalId);
						if (shape) {
							shape.hide();
						}
					}
				});
				query.onMarkRemove.addListener(function(event) {
					var externalId;
					var shape;
					var shapes = Console.webapp.shapes;
					var externalIds = event.context;
					var mc = Console.webapp.mapController;
					
					for (var i = 0; i < externalIds.length; i++) {
						externalId = externalIds[i];
						shape = shapes.remove(externalId);
						if (shape) {
							shape.dispose();
						}
					}
				});
				query.onMarkKeep.addListener(function(event) {
					var externalId;
					var checkbox;
					var getElm = WU.Elements.idOrElm2Elm;
					var externalIds = event.context;

					for (var i = 0; i < externalIds.length; i++) {
						externalId = externalIds[i];
						checkbox = getElm('unit-history-' + externalId + '-checkbox');
						checkbox.checked = true;
					}
				});
			}
			
		}
	
		// === PACKAGE PUBLIC ===
		this.Console = Console;
		// === PACKAGE PUBLIC ===
	}
)


/*
var locateUnit = function(unit) {
	var userXml;
	var unitXml = unit.xml;
	var uuid = unitXml.getAttribute('external-id', NS.atms);
	var credsXml = webapp.session.credentials;
	var frm = document.getElementById('locate-form');
	var conn = new NET.URLConnection(frm.action);

	if (credsXml) {
		if (frm) {
			userXml = credsXml.getChild('user');
			if (userXml && unitXml) {
				Inputs.initForm(frm, {
					unit: unitXml.getAttribute('external-id', NS.atms),
					user: userXml.getAttribute('external-id', NS.atms)
				});

				conn.outputForm(frm);
				conn.open();

			} else {
				_logger.warning('No user or unit (not logged on?)');
			}
		} else {
			_logger.warning('The locate-form cannot be found');
		}
	} else {
			_logger.warning('No user credentials (not logged on?)');
	}
	
};
*/











