/**
 * Map.js
 * @version 1.0
 */

var brom = brom || {};

brom.eventHandler = new gpx.utils.eventHandler();
brom.EVENT = {
	MAP_INIT: 100,
	MAP_SEARCH: 101,
	MAP_MARKER_CLICK: 102,
	MAP_CHANGE: 103,
	MAP_DATA_LOADED: 107
};

brom.map = {};
// const
brom.map.PIN_BIG = 1;
brom.map.PIN_SMALL = 3;
brom.map.ZOOM_MAX = 15;
brom.map.ZOOM_MIN = 5;
brom.map.REMOVE_ALL = true;
// vars
brom.map.options = {
	center: new google.maps.LatLng(45.946949, 24.9804),// Romania
	zoom: 7,
	mapTypeId: google.maps.MapTypeId.TERRAIN,
	streetViewControl: false,
	scrollwheel: false,
	mapTypeControl: true,
	mapTypeControlOptions: {
		style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
	},
	navigationControl: true,
	navigationControlOptions: {
		style: google.maps.NavigationControlStyle.SMALL
	}
};
brom.map.container = $('#map');
brom.map.loadUrl = null;
brom.map.markers = [];
brom.map.geocoder = null;
brom.map.clusterer = null;
brom.map.clustererOptions = {
	maxZoom: 13,
	gridSize: null,
	styles: [{
		url: '/img/pin_2.png',
		width: 43,
		height: 50,
		anchor: [7, 0],
		textColor: '#000000',
		textSize: 12
	}/*, {
		url: 'http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/images/conv40.png',
		height: 36,
		width: 40,
		opt_anchor: [6, 0],
		opt_textColor: '#ff0000',
		opt_textSize: 11
	}, {
		url: 'http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/images/conv50.png',
		width: 50,
		height: 45,
		opt_anchor: [8, 0],
		opt_textSize: 12
	}*/]
};

// functions
brom.map.zoomIn = function() {
	var zoom = this.instance.getZoom();
	if(zoom < this.ZOOM_MAX) {
		zoom++
		this.instance.setZoom(zoom);
	}
}

brom.map.zoomOut = function() {
	var zoom = this.instance.getZoom();
	if(zoom > this.ZOOM_MIN) {
		zoom--
		this.instance.setZoom(zoom);
	}
}

brom.map.resize = function() {
	google.maps.event.trigger(this.instance, "resize");
	this.instance.setCenter(this.options.center);
}

brom.map.fromlatLngToPoint = function(latLng) {
	var scale = Math.pow(2, this.instance.getZoom());
	var nw = new google.maps.LatLng(
		this.instance.getBounds().getNorthEast().lat(),
		this.instance.getBounds().getSouthWest().lng()
	);
	var worldCoordinateNW = this.instance.getProjection().fromLatLngToPoint(nw);
	var worldCoordinate = this.instance.getProjection().fromLatLngToPoint(latLng);
	return new google.maps.Point(
		Math.floor((worldCoordinate.x - worldCoordinateNW.x) * scale),
		Math.floor((worldCoordinate.y - worldCoordinateNW.y) * scale) + brom.CONST.TOP_BAR_HEIGHT
	);
}

brom.map.search = function(q) {
	var region = 'RO';

	if(!this.geocoder) {
		this.geocoder = new google.maps.Geocoder();
	}

	var geocoderRequest = {
		address: q,
		region: region
	}
	var self = this;
	this.geocoder.geocode(geocoderRequest, function(results, status) {
		if (status == google.maps.GeocoderStatus.OK && results.length > 0) {
			self.options.center = results[0].geometry.location;
			brom.eventHandler.run(brom.EVENT.MAP_SEARCH);
			// zoom in to the result
			var bounds = new google.maps.LatLngBounds();
			bounds.union(results[0].geometry.viewport);
			self.instance.fitBounds(bounds);
		}
	});
}

brom.map.getPinIcon = function(size) {
	var icon;
	switch (size) {
		case this.PIN_BIG:
			icon = new google.maps.MarkerImage(
				'/img/pin_1.png',
				new google.maps.Size(43,50),
				new google.maps.Point(0,0),
				new google.maps.Point(21,38)
				);
			break;
		case this.PIN_SMALL:
		default:
			icon = new google.maps.MarkerImage(
				'/img/pin_3.png',
				new google.maps.Size(21,25),
				new google.maps.Point(0,0),
				new google.maps.Point(9,16)
				);
			break;
	}
	return icon;
}

brom.map.removeMarker = function(removeAll) {
	// remove all or remove last added?
	var all = removeAll ? true : false;
	if(all) {
		for (var i = 0, marker; marker = this.markers[i]; i++) {
			marker.setMap(null);
		}
	} else {
		var last = this.markers.pop();
		last.setMap(null);
	}
}

brom.map.load = function(filters) {
	var self = this;
	if(!this.loadUrl) {
		return false;
	}
	$.get(this.loadUrl, filters, function(response, status) {
		if(status == 'success' && response.status === true) {
			self.markers = [];
			$.each(response.data, function(i, item) {
				var marker;
				item = response.data[i];
				marker = new google.maps.Marker({
					position: new google.maps.LatLng(item.lat, item.lng),
					icon: self.getPinIcon(self.PIN_SMALL)
				});
				marker.id = item.id;
				google.maps.event.addListener(marker, 'click', function(e) {
					brom.eventHandler.run(brom.EVENT.MAP_MARKER_CLICK, marker);
				});
				self.markers.push(marker);
			});
			if(self.clusterer != null) {
				self.removeMarker(self.REMOVE_ALL);
				self.clusterer.clearMarkers();
			}
			self.clusterer = new MarkerClusterer(self.instance, self.markers, self.clustererOptions);
			brom.eventHandler.run(brom.EVENT.MAP_DATA_LOADED, response);
		}
	});
	return true;
}

brom.map.init = function() {
	this.instance = new google.maps.Map(this.container.get(0), this.options);
	// register handlers
	var self = this;

	$('#search_form').bind('submit', function(e) {
		for(var i = this.elements.length - 1; i >= 0; i--) {
			if(this.elements[i].type == 'text') {
				brom.map.search(this.elements[i].value);
				break;
			}
		}
		e.preventDefault();
	});

	brom.eventHandler.run(brom.EVENT.MAP_INIT, this, function() {
		self.load();
	});

	var bounds_changed_fired = false;
	google.maps.event.addListener(brom.map.instance, "bounds_changed", function(e) {
		if(!bounds_changed_fired) {
			bounds_changed_fired = true;
			var _to = setTimeout(function() {
				bounds_changed_fired = false;
				brom.eventHandler.run(brom.EVENT.MAP_CHANGE);
				clearTimeout(_to);
			}, 300)
		}
	});
	google.maps.event.addListener(brom.map.instance, "click", function(e) {
		if(self.addMode) {
			var marker = new google.maps.Marker({
				map: self.instance,
				position: e.latLng,
				icon: self.getPinIcon(self.PIN_BIG)
			});
			google.maps.event.addListener(marker, 'click', function(e) {
				brom.eventHandler.run(brom.EVENT.MAP_ADD_MARKER_CLICK, marker);
			});
			google.maps.event.trigger(marker, 'click');
			self.disableAddMode();
		}
	});
}

brom.detailWindow = {};
brom.detailWindow.instance = $('#detailWindowWrapper');
brom.detailWindow.content = $('#detailWindow');
brom.detailWindow.marker = null;
brom.detailWindow.isOpened = false;
brom.detailWindow.open = function() {
	if(this.marker != null /*&& !this.isOpened*/) {
		$('#add_info').addClass('hidden');
		var params = this.marker.id != null ? {id: this.marker.id} : null;
		var self = this;
		this.content.load('/detail', params, function() {
			self.moveToPoint();
			self.instance.show();
			self.isOpened = true;
			$('#detailClose').bind('click', function(e) {
				self.close();
				e.preventDefault();
			});
		});
	}
}
brom.detailWindow.close = function() {
	if(this.isOpened) {
		this.content.empty();
		this.instance.hide();
		this.isOpened = false;
		if(this.marker != null) {
			this.marker = null;
		}
	}
}
brom.detailWindow.moveToPoint = function(point) {
	if(point == null && this.marker != null) {
		point = brom.map.fromlatLngToPoint(this.marker.getPosition());
	}
	this.instance.css({
		top: point.y,
		left: point.x
	});
}
brom.detailWindow.init = function() {
	var self = this;
	brom.eventHandler.add(brom.EVENT.MAP_MARKER_CLICK, function(marker) {
		self.marker = marker;
		brom.map.instance.setCenter(marker.getPosition());
		self.open();
	});
	brom.eventHandler.add(brom.EVENT.MAP_CHANGE, function() {
		if(self.isOpened) {
			self.moveToPoint();
		}
	});
}


//brom.eventHandler.add(brom.EVENT.MAP_SEARCH, function() {
//
//});
// update the filter results and operator filters, if required
//brom.eventHandler.add(brom.EVENT.MAP_DATA_LOADED, function(response) {
//
//});


/**
 * Run Forest, run!
 */
if(brom.map.container.get(0)) {
	brom.map.init();
}
//brom.detailWindow.init();
