var BASE_URL = detectBaseUrl();

function detectBaseUrl() {
	var href = location.href;
	var urls = ["http://eatspot.jp", "http://192.168.11.11:8080/eatspot"];
	for (var i = 0; i < urls.length; i++) {
		if (href.indexOf(urls[i]) == 0) {
			return urls[i];
		}
	}
	return urls[0];
}

var LAT_PER_METER = 1 / 6378137 * 180 / Math.PI;
var MAX_RADIUS = 19;

var labels = {};
var map = null;
var geocoder = null;

var spotLat = 0;
var spotLng = 0;
var rankingCache = null;
var rankingShown = false;

var release = function() {
	if (GUnload) {
		try {
			GUnload();
		} catch(e) {
		}
	}
};

var initializeVariables = function(decoration) {
	var decStart = decoration ? "<span class=\"default\">" : "";
	var decEnd = decoration ? "</span>" : "";

	labels["radius"] = ["100m以内", "200m以内", "300m以内", "400m以内", "500m以内",
		"600m以内", "700m以内", "800m以内", "900m以内", "1km以内", "1.5km以内", "2km以内", "3km以内", "5km以内",
		"7km以内", "10km以内", "20km以内", "50km以内", "100km以内", "全国"];
	labels["minPrice"] = ["情報なし", decStart + "下限なし" + decEnd, "1000円以上", "2000円以上", "3000円以上", "4000円以上", "5000円以上", "6000円以上",
		"8000円以上", "10000円以上", "15000円以上", "20000円以上", "30000円以上"];
	labels["maxPrice"] = ["情報なし", "1000円未満", "2000円未満", "3000円未満", "4000円未満", "5000円未満", "6000円未満",
		"8000円未満", "10000円未満", "15000円未満", "20000円未満", "30000円未満", decStart + "上限なし" + decEnd];
	labels["minScore"] = [decStart + "下限なし" + decEnd, "3.0以上", "3.1以上", "3.2以上", "3.3以上", "3.4以上", "3.5以上",
		"3.6以上", "3.7以上", "3.8以上", "3.9以上", "4.0以上"];
	labels["maxScore"] = ["3.0未満", "3.1未満", "3.2未満", "3.3未満", "3.4未満", "3.5未満",
		"3.6未満", "3.7未満", "3.8未満", "3.9未満", "4.0未満", decStart + "上限なし" + decEnd];
	labels["situation"] = ["[指定なし]", "友人・同僚と", "デート", "接待", "宴会", "家族・子供と", "一人で"];
};

var initializeState = function() {
	var token = "";
	if (location.href.indexOf(BASE_URL + "/configure") >= 0) {
		if (location.href.indexOf("?token=") >= 0) {
			token = location.href.replace(/.*configure\?token=([0-9a-z]*).*/, "$1");
		}
	} else {
		token = location.href.replace(/.*\/([0-9a-z]*).*/, "$1");
	}
	$.getJSON(BASE_URL + "/init", { token: token }, function(json) {
		initializeControls(json);
	});
	return token;
};

var buildTileUrl = function(loc, zoom) {
	var p1 = new GPoint(loc.x * 256, loc.y * 256);
	var p2 = new GPoint((loc.x + 1) * 256, (loc.y + 1) * 256);
	var l1 = G_NORMAL_MAP.getProjection().fromPixelToLatLng(p1, zoom, false);
	var l2 = G_NORMAL_MAP.getProjection().fromPixelToLatLng(p2, zoom, false);
	var url = BASE_URL + "/tile";
	url += "?lat1=" + l1.lat();
	url += "&lng1=" + l1.lng();
	url += "&lat2=" + l2.lat();
	url += "&lng2=" + l2.lng();
	url += "&" + createRadiusParams();
	url += "&" + createCommonParams();
	if (iphone) {
		url += "&iPhone=1";
	}
	return url;
};

var createCommonParams = function() {
	var params = "";
	params += "zoom=" + getCurrentZoom();
	params += "&minPrice=" + getCurrentMinPrice();
	params += "&maxPrice=" + getCurrentMaxPrice();
	params += "&minScore=" + getCurrentMinScore();
	params += "&maxScore=" + getCurrentMaxScore();
	// avoid GTileLayer image URL encoding problem
	params += "&category=" + encodeURIComponent(getCurrentCategory()).replace(/%/g, "_");
	params += "&situation=" + encodeURIComponent(getCurrentSituation());
	return params;
};

var createRadiusParams = function() {
	var params = "";
	params += "radius=" + getCurrentRadius();
	if (getCurrentRadius() != MAX_RADIUS) {
		params += "&spotLat=" + spotLat;
		params += "&spotLng=" + spotLng;
	}
	return params;
}

var hitTest = function(p, callback) {
	if (!p) {
		return;
	}
	var bounds = map.getBounds();
	var latLngSize = bounds.toSpan();
	var pixelSize = map.getSize();
	var errorLat = 16 * latLngSize.lat() / pixelSize.height;
	var errorLng = 16 * latLngSize.lng() / pixelSize.width;

	var url = BASE_URL + "/info/hit";
	url += "?lat=" + p.lat();
	url += "&lng=" + p.lng();
	url += "&errorLat=" + errorLat;
	url += "&errorLng=" + errorLng;
	url += "&" + createRadiusParams();
	url += "&" + createCommonParams();

	$.getJSON(url, {}, function(json) {
		if (callback) {
			callback(json);
		}
	});
};

var spotCenter = function() {
	var c = map.getCenter();
	spotLat = c.lat();
	spotLng = c.lng();
	updateSpot(true);
};

var updateSpot = function(adjust) {
	if (adjust) {
		map.setCenter(new GLatLng(spotLat, spotLng));
		adjustZoom();
	} else {
		updateMapLayer();
	}

	var url = BASE_URL + "/info/list";
	url += "?" + createRadiusParams();
	url += "&" + createCommonParams();
	$.getJSON(url, {}, function(json) {
		updateRestaurantList(json, true);
	});
};

var findCachedRank = function(item) {
	if (!rankingCache) {
		return -1;
	}
	for (var i = 0; i < rankingCache.length; i++) {
		if (rankingCache[i].id == item.id) {
			return i + 1;
		}
	}
	return -1;
};

var formatScore = function(score) {
	var s = String(Math.floor(score * 100));
	return s.substring(0, 1) + "." + s.substring(1);
};

var openMarker = function(lat, lng, html) {
	var p = new GLatLng(lat, lng);
	map.openInfoWindowHtml(p, html);
};

var getCurrentRadiusInMeter = function() {
	var array = [100, 200, 300, 400, 500, 600, 700, 800, 900, 1000,
		1500, 2000, 3000, 5000, 7000, 10000, 20000, 50000, 100000, -1];
	return array[getCurrentRadius()];
};

var updateMapLayer = function() {
	map.setCenter(map.getCenter());
};

var adjustZoom = function() {
	var r = getCurrentRadiusInMeter();
	if (r < 0) {
		return;
	}
	var desiredHeightMeter = 2 * r;
	if (iphone) {
		desiredHeightMeter *= 0.9 * (416 / 320);
	}
	var desiredHeight = desiredHeightMeter * LAT_PER_METER;

	var span = map.getBounds().toSpan();
	var currentHeight = span.lat();
	var height = currentHeight;

	var newZoom = -1;
	for (var i = map.getZoom(); i <= 19; i++) {
		var nextHeight = height / 2;
		if (desiredHeight >= nextHeight && desiredHeight < height) {
			newZoom = i;
			break;
		}
		height = nextHeight;
	}
	if (newZoom == -1) {
		height = currentHeight;
		for (var i = map.getZoom() - 1; i >= 1; i--) {
			var nextHeight = height * 2;
			if (desiredHeight >= height && desiredHeight < nextHeight) {
				newZoom = i;
				break;
			}
			height = nextHeight;
		}
	}
	map.setZoom(newZoom);
}
