var Map = OZ.Class().extend(App.Module);
App.Modules.push(Map);

Map.prototype.init = function(app) {
	this.app = app;
	
	this._apiState = 0;
	this._requestState = 0;

	this._map = null;
	this._xml = null;
	
	
	this._elm = null;
	this._win = null;
	this._markers = [];
	this._polylines = [];
}

Map.prototype.activate = function() {
	this._active = true;
	var c = this.app.getContent();
	OZ.DOM.addClass(c, "map");

	if (!this._elm) {
		availh = Math.round(c.offsetHeight * 0.8);
		this._elm = OZ.DOM.elm("div", {id:"map", width:"80%", height:availh+"px", textAlign:"center"});
		var throbber = OZ.DOM.elm("img", {src:"/img/throbber.gif"});
		this._elm.appendChild(throbber);
	}
	
	c.appendChild(this._elm);

	this._check();
}

Map.prototype.deactivate = function() {
	this._active = false;
	var c = this.app.getContent();
	OZ.DOM.removeClass(c, "maps");
}

Map.prototype.update = function() {
	if (!this._map) { return; }
	
	this._win.close();
	var m = this._markers[this.app.currentIndex()];
	if (!m) { return; }

	var div = OZ.DOM.elm("div");
	var img = OZ.DOM.elm("img", {width:"64",height:"64",cursor:"pointer",src:this.app.currentSmall()});
	OZ.Event.add(img, "click", this.bind(this._switch));
	div.appendChild(img);
	this._win.setOptions({maxWidth:64, content:div});
	this._win.open(this._map, m);
}

Map.prototype._switch = function(e) {
	this.app.setModule(0);
}

Map.prototype._build = function() {
	var arr = [];
	var bounds = new google.maps.LatLngBounds();
	var images = this._xml.getElementsByTagName("exif");
	for (var i=0;i<images.length;i++) {
		var image = images[i];
		var lon = image.getAttribute("GPSLongitude");
		var lat = image.getAttribute("GPSLatitude");
		var marker = false;
		if (lon && lat) {
			lon = parseFloat(lon);
			lat = parseFloat(lat);
			var coords = new google.maps.LatLng(lat, lon);
			arr.push(coords);
			bounds.extend(coords);
			marker = new google.maps.Marker({position:coords});
		}
		this._markers.push(marker);
	}
	
	this._parseGPX(bounds);
	
	if (bounds.isEmpty()) {
		this._map = true;
		this._elm.innerHTML = "<p>Žádná geografická data nejsou k dispozici.</p>";
		return;
	}
	
	var opts = {
		mapTypeId: google.maps.MapTypeId.TERRAIN
	};
	OZ.DOM.clear(this._elm);
	this._elm.style.textAlign = "";
	this._map = new google.maps.Map(this._elm, opts);
	
	this._map.fitBounds(bounds);
	this._win = new google.maps.InfoWindow();
	
	for (var i=0;i<this._markers.length;i++) {
		var m = this._markers[i];
		if (!m) { continue; }
		m.setMap(this._map);
		this._addEvent(m, i);
	}
	
	for (var i=0;i<this._polylines.length;i++) {
		this._polylines[i].setMap(this._map);
	}
	
	this.update();
}

Map.prototype._apiLoaded = function() {
	this._apiState = 2;
	this._check();
}

Map.prototype._request = function() {
	OZ.Request(document.location.pathname + "?geo", this.bind(this._response), {xml:true});
}

Map.prototype._response = function(xml) {
	this._xml = xml;
	this._requestState = 2;
	this._check();
}

Map.prototype._check = function() {
	if (this._map) { return; }

	if (this._apiState == 0) {
		this._apiState = 1;
		google.load("maps", 3, {callback:this.bind(this._apiLoaded), other_params:"sensor=false"});
	}
	if (this._requestState == 0) {
		this._requestState = 1;
		this._request();
	}

	if (!this._active) { return; }
	if (this._apiState != 2) { return; }
	if (this._requestState != 2) { return; }
	
	this._build();
}

Map.prototype._addEvent = function(marker, index) {
	var app = this.app;
	google.maps.event.addListener(marker, "click", function() {
		app.go(index);
	});
}

/**
 * Add polyline(s) if present
 */
Map.prototype._parseGPX = function(bounds) {
	var colors = ["yellow", "red", "blue"];
	var gpx = this._xml.getElementsByTagName("gpx");
	if (!gpx.length) { return; }
	
	var trks = gpx[0].getElementsByTagName("trk");
	for (var i=0;i<trks.length;i++) {
		var color = colors[i % colors.length];
		
		var trk = trks[i];
		var trksegs = trk.getElementsByTagName("trkseg");
		for (var j=0;j<trksegs.length;j++) {
			var trkseg = trksegs[j];
			var data = [];
			
			var trkpts = trkseg.getElementsByTagName("trkpt");
			for (var k=0;k<trkpts.length;k++) {
				var trkpt = trkpts[k];
				var lon = parseFloat(trkpt.getAttribute("lon"));
				var lat = parseFloat(trkpt.getAttribute("lat"));
				var coords = new google.maps.LatLng(lat, lon);
				bounds.extend(coords);
				data.push(coords);
			}
			
			var polyline = new google.maps.Polyline({path:data, strokeColor:color, strokeWeight:4});
			this._polylines.push(polyline);
		}
		
	}
}
