EVT_ON_RECEIVE_MARKER_DETAILS = "onReceiveMarkerDetails";

MapBalloon.Inherits(GControl);
function MapBalloon(parent) {
	this.Inherits(GControl, true, true);
	this.map = null;
	this.container = null;
	this.hiddenBalloon = true;
	this.tab_ids = new Array("tab1", "tab2");
	this.parent = parent;
}

MapBalloon.prototype.Inherits = function(parent)
{
	if(arguments.length > 1)
		parent.apply(this, Array.prototype.slice.call(arguments, 1));
	else
		parent.call(this);
}


MapBalloon.prototype.initialize = function (map) {
	var objThis = this;
	this.map = map;
	var container_id = "marker_details";
	this.container = document.getElementById("marker_details");
	this.container.style.width = "400px";
	this.container.style.height = "350px";

	map.getContainer().appendChild(this.container);
	GEvent.addListener(this, EVT_ON_RECEIVE_MARKER_DETAILS, function(req, latlng) {
		objThis.fillBalloonDetails(req, latlng);
	});
	
	this.loading = document.getElementById("marker_details_loading");
	return this.container;
}


//Default location for the control
MapBalloon.prototype.getDefaultPosition = function() {
	return new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(0, 0));
};

//Default location for the control
MapBalloon.prototype.hide = function() {
	if(this.container)
	{
		this.container.style.display = "none"
		this.hiddenBalloon = true;
	}
};


/**
 * Display the ballon around specified coordinates
 * @param latlng GLatLng where to show the ballon (smart placed arount this point)
 * @param id ID of the marker to load data for via Ajax
 */
MapBalloon.prototype.show = function(latlng, id) {
	var objThis = this;
	url = gSettings.xmlrpc_locationdetails_endpoint + "?id=" + id;
	AjaxRequest.get(
	{
		"url" : url,
		"onSuccess" : function(req) {
			GEvent.trigger(objThis, EVT_ON_RECEIVE_MARKER_DETAILS, req, latlng);
		},
		"onError" : this.loadPointDetailsCallbackError
	});
};

MapBalloon.prototype.fillBalloonDetails = function (req, latlng) {
	var item = req.responseXML.getElementsByTagName("location")[0];
	var id = item.getAttribute("id");
	var slug = item.getAttribute("slug");
	var name = item.getAttribute("name");
	var description = trim(item.getAttribute("description"));
	var address = trim(item.getAttribute("address"));
	var postal_code = trim(item.getAttribute("postal_code"));
	var id_country = item.getAttribute("id_country");
	var webpage = trim(item.getAttribute("webpage"));
	var contact = trim(item.getAttribute("contact"));
	var source = trim(item.getAttribute("source"));
	var id_location_type = item.getAttribute("id_location_type");
	var longitude = parseFloat(item.getAttribute("longitude"));
	var latitude = parseFloat(item.getAttribute("latitude"));
	var created = item.getAttribute("created");
	var latlng = new GLatLng(latitude, longitude);
	
	var contentCtrl = document.getElementById("marker_content_remote");
	contentCtrl.innerHTML = "";
	var html = "<h1>" + name + "</h1>";
	//if( description != "") html += "<p>" + description + "</p>";
	if( address != "") html += "<p>" + address + "</p>";
	var smLink = document.createElement("a");
	smLink.href="javascript:openMap('" + gSettings.base_url + "location_index?id=" + id + "')";
	smLink.appendChild(document.createTextNode("see more"));
	contentCtrl.appendChild(smLink);
	contentCtrl.innerHTML += html;

	var z = (this.map.getZoom() + 4);
	if(z > 17) z = 17;
	
	static_url = gSettings.static_map_url;
	static_url += "&center=" + latlng.lat() + "," + latlng.lng();
	static_url += "&zoom=" + z;
	static_url += "&size=328x128";
	static_url += "&markers=" + latlng.lat() + "," + latlng.lng();
	var minimapCtrl = document.getElementById("marker_minimap");
	minimapCtrl.src = static_url;
	minimapCtrl.style.width = "250px";
	minimapCtrl.style.height = "100px";
	
	var tt = item.getAttribute("tt");
	var tt_names = item.getAttribute("tt_names");
	var ttArr = tt.split(",");
	var tt_namesArr = tt_names.split(",");
	markerTTCtrl = document.getElementById("marker_tt");
	if (markerTTCtrl.hasChildNodes())
	{
		while(markerTTCtrl.childNodes.length >= 1)
		{
			markerTTCtrl.removeChild(markerTTCtrl.firstChild);
		}
	}
	for(i = 0; i < ttArr.length; i++) {
		var icon_url = this.parent.iconManager.getTTIconURL(id_location_type, ttArr[i]);
		var icon = document.createElement("img");
		icon.setAttribute("src", icon_url);
		icon.style.verticalAlign = "middle";
		icon.setAttribute("title", tt_namesArr[i]);
		markerTTCtrl.appendChild(icon);
	}
	if( contact != "") {
		var contactCtrl = document.getElementById("marker_contact");
		contactCtrl.innerHTML = contact;
	}
	
	if( webpage != "") {
		var webpageCtrl = document.getElementById("marker_webpage");
		webpage_url = webpage.indexOf("http") < 0 ? "http://" + webpage : webpage;
		webpageCtrl.innerHTML = "<strong>Webpage:</strong><a href=\"" + webpage_url + "\" target=\"_blank\">" + webpage + "</a>";
	}
	
	var rlCtrl = document.getElementById('related_locations');
	rlCtrl.innerHTML = '';
	if(id_location_type == gSettings.observatory_id) {
		rlCtrl.innerHTML = '<a href="javascript:gMapControl.showRelatedLocations();">See related locations</a>'; 
	}

	markerPixelPos = this.map.fromLatLngToContainerPixel(latlng);
	pos = this.smartPosition(markerPixelPos);
	this.container.style.display = "block";
	this.container.style.top = pos.y + "px";
	this.container.style.left = pos.x + "px";
	this.container.style.display = "block";
	this.hiddenBalloon = false;
	this.loading.style.display = "none";
}

MapBalloon.prototype.loadPointDetailsCallbackError = function (req) {
	log.fatal("[MapBalloon.loadPointDetailsCallbackError]Error loading location details. Server failure (" + req.statusText + ").\n" + req.responseText);
}

/////
/**
 * Find the smart position of the balloon
 */
MapBalloon.prototype.smartPosition = function(markerPosition) {
	ret = new GPoint();
	container_size = new GSize(parseInt(this.container.style.width), parseInt(this.container.style.height));
	map_bounds = this.map.getBounds();
	ne_px = this.map.fromLatLngToContainerPixel(map_bounds.getNorthEast());
	sw_px = this.map.fromLatLngToContainerPixel(map_bounds.getSouthWest());
	quadrants = Array();

	q0_w = ne_px.x - markerPosition.x;
	q0_h = markerPosition.y - ne_px.y;
	quadrants.push(new GSize(q0_w, q0_h));

	q1_w = q0_w;
	q1_h = sw_px.y - markerPosition.y;
	quadrants.push(new GSize(q1_w, q1_h));
	
	q2_w = markerPosition.x - sw_px.x;
	q2_h = q1_h;
	quadrants.push(new GSize(q2_w, q2_h))
	
	q3_w = q2_w;
	q3_h = q0_h;
	quadrants.push(new GSize(q3_w, q3_h))
	
	worked = false;
	best_q_idx = -1;
	best_q = new GSize(-1, -1);
	//Strategy is to choose the biggest quadrant
	for(i = 0; i < quadrants.length; i++) {
		q = quadrants[ i ];
		if(q.width >= best_q.width && q.height >= best_q.height) {
			best_q_idx = i;
			best_q = q;
			worked = true;
		}
	}
	if(worked) {
		var marker_c = document.getElementById("marker_content"); 
		switch(best_q_idx) {
			case 0:
				this.showCorner(0);
				marker_c.style.bottom = "0px";
				return new GPoint(markerPosition.x + 10, markerPosition.y - container_size.height + 30);
			case 1:
				this.showCorner(1);
				marker_c.style.bottom = "26px";
				return new GPoint(markerPosition.x, markerPosition.y - 20);
			case 2:
				this.showCorner(2);
				marker_c.style.bottom = "26px";
				return new GPoint(markerPosition.x - container_size.width + 10, markerPosition.y - 20);
			case 3:
				this.showCorner(3);
				marker_c.style.bottom = "0px";
				return new GPoint(markerPosition.x - container_size.width + 10, markerPosition.y - container_size.height + 40);
		}
	}
	log.debug( "Algorithm not worked, returning Quadrant 0");
	return new GPoint(markerPosition.x, markerPosition.y - container_size.height);
}


/**
 * Show the proper corner of the map balloon depending on quadrant appearing.
 * @param quadrant Quadrant where balloon will be displayed
 */
MapBalloon.prototype.showCorner = function(quadrant) {
	for(i = 3; i >= 0; i--) {
		corner = document.getElementById("marker_details_corner_" + i);
		switch(i) {
			case 0:
				corner.setAttribute("class", i == quadrant ? "down_left" : "down_left_empty");
				corner.setAttribute("className", i == quadrant ? "down_left" : "down_left_empty"); break;
			case 1:
				corner.setAttribute("class", i == quadrant ? "top_left" : "top_left_empty");
				corner.setAttribute("className", i == quadrant ? "top_left" : "top_left_empty"); break;
			case 2:
				corner.setAttribute("class", i == quadrant ? "top_right" : "top_right_empty");
				corner.setAttribute("className", i == quadrant ? "top_right" : "top_right_empty"); break;
			case 3:
				corner.setAttribute("class", i == quadrant ? "down_right" : "down_right_empty");
				corner.setAttribute("className", i == quadrant ? "down_right" : "down_right_empty"); break;
		}
	}
}
