var iphone = false;
var tooltipTimer = null;

var minPriceSlider = null;
var maxPriceSlider = null;
var minScoreSlider = null;
var maxScoreSlider = null;
var radiusSlider = null;

Ext.onReady(function() {
	Ext.BLANK_IMAGE_URL = BASE_URL + "/images/default/s.gif";
	initializeVariables(true);
	initializeState();
});

var initializeGMap = function(lat, lng, zoom) {
    if (!GBrowserIsCompatible()) {
        return;
    }
	geocoder = new GClientGeocoder();

    map = new GMap2($("#center").get(0));
	map.addControl(new GLargeMapControl());
	map.addControl(new GMapTypeControl());
	map.addControl(new GOverviewMapControl());
	map.addControl(new GScaleControl());
	map.enableScrollWheelZoom();
	map.disableContinuousZoom();
	map.disableDoubleClickZoom();

	var adjust = zoom == 0;
	map.setCenter(new GLatLng(lat, lng), adjust ? 13 : zoom);

	var layer = new GTileLayer(new GCopyrightCollection(), 5, 19);
	layer.getTileUrl = buildTileUrl;
	layer.isPng = function() { return true; }

	var overlay = new GTileLayerOverlay(layer);
	map.addOverlay(overlay);

	GEvent.addListener(map, "click", function(overlay, p) {
		hitTest(p, function(info) {
			if (!info) {
				if (rankingCache && !rankingShown) {
					updateRestaurantList(rankingCache, true);
				}
				return;
			}
			var e = info.content;
			if (info.type == "restaurant") {
				updateRestaurantList([e], false);
			} else if (info.type == "station") {
				spotLat = e.lat;
				spotLng = e.lng;
				updateSpot();
			}
		});
	});
	GEvent.addListener(map, "mousemove", function(p) {
		if(tooltipTimer) {
			clearTimeout(tooltipTimer);
		}
		tooltipTimer = setTimeout(
			"invokeTooltip(new GLatLng(" + p.lat() + ", " + p.lng() + "))",
			300);
	});
	GEvent.addListener(map, "mouseout", function() {
		if(tooltipTimer) {
			clearTimeout(tooltipTimer);
			tooltipTimer = null;
		}
	});
	updateSpot(adjust);
};

var invokeTooltip = function(p) {
	hitTest(p, function(info) {
		if (!info) {
			hideTooltip();
			return;
		}
		var html = "";
		var e = info.content;
		if (info.type == "restaurant") {
			html = buildRestaurantHtml(e, false, -1, findCachedRank(e));
		} else if (info.type == "station") {
			html = "<h2>" + e.name + "</h2>";
			html += e.line + "<br/>";
			html += "クリックでスポットします";
		} else {
			return;
		}

		var mp = G_NORMAL_MAP.getProjection().fromLatLngToPixel(
			p, map.getZoom());
		var bounds = map.getBounds();
		var nw = new GLatLng(bounds.getNorthEast().lat(),
			bounds.getSouthWest().lng());
		var op = G_NORMAL_MAP.getProjection().fromLatLngToPixel(
			nw, map.getZoom());
		var absolute = getAbsolutePosition($("#center").get(0));
		var x = absolute.left + (mp.x - op.x) + 8;
		var y = absolute.top + (mp.y - op.y) + 16;

		var tooltip = $("#tooltip").get(0);
		tooltip.innerHTML = html;
		tooltip.style.left = x + "px";
		tooltip.style.top = y + "px";
		tooltip.style.visibility = "visible";
		tooltip.style.display = "block";
	});
};

var hideTooltip = function() {
	$("#tooltip").hide();
};

var updateRestaurantList = function(items, ranked) {
	var html = "";
	var ranks = [];
	$.each(items, function(i, e) {
		var rank = ranked ? i + 1 : findCachedRank(e);
		ranks.push(rank);
		html += "<div class=\"restaurant\">";
		html += buildRestaurantHtml(e, true, i, rank);
		html += "</div>";
	});
	var list = $("#list").get(0);
	list.innerHTML = html;
	list.scrollTop = "0";
	$.each(items, function(i, e) {
		var lat = e.lat;
		var lng = e.lng;
		var html = buildRestaurantHtml(e, false, -1, ranks[i]);
		registerMarker($("#marker" + i).get(0), lat, lng, html);
	});
	rankingShown = ranked;
	if (rankingShown) {
		rankingCache = items;
	}
};

var registerMarker = function(elem, lat, lng, html) {
	elem.onclick = function(event) {
		openMarker(lat, lng, html);
		return false;
	};
};

var buildRestaurantHtml = function(r, detail, index, rank) {
	var html = "";
	if (detail) {
		html += "<div class=\"restaurantHeader\">";
	}
	html += "<h2>";
	if (rank && rank >= 1) {
		html += "<img src=\"images/rank" + rank + ".png\"/>";
		html += " <span class=\"unit\">位</span> ";
	}
	if (detail) {
		html += "<a target=\"_blank\" href=\"" + r.url + "\" title=\"食べログ.comで詳細情報を見る\">";
		html += r.name;
		html += "</a>";
	} else {
		html += r.name;
	}
	html += "</h2>";
	if (r.category) {
		if (detail) {
			html += "<div class=\"category\">" + r.category + "</div>";
		} else {
			html += "<div class=\"linedCategory\">" + r.category + "</div>";
		}
	}
	if (detail) {
		html += "</div>";
		html += "<div class=\"restaurantContent\">";
	}
	if (r.totalScore > 0) {
		html += "<div class=\"name\">評価:</div><div class=\"score\"><big>" + formatScore(r.totalScore) + "</big></div>";
	}
	if (r.lunchPrice) {
		html += "<div class=\"name\">予算(昼):</div><div class=\"value\">" + r.lunchPrice + "</div>";
	}
	if (r.dinnerPrice) {
		html += "<div class=\"name\">予算(夜):</div><div class=\"value\">" + r.dinnerPrice + "</div>";
	}
	if (detail) {
		if (r.businessHours) {
			html += "<div class=\"name\">営業:</div><div class=\"value\">" + r.businessHours + "</div>";
		}
		if (r.tel) {
			html += "<div class=\"name\">TEL:</div><div class=\"value\">" + r.tel + "</div>";
		}
		if (r.address) {
			html += "<div class=\"name\">住所:</div><div class=\"value\">" + r.address + "</div>";
		}
		if (r.station) {
			html += "<div class=\"name\">最寄駅:</div><div class=\"value\">" + r.station + "</div>";
		}
		html += "<div class=\"marker\">";
		html += "<a id=\"marker" + index + "\" class=\"marker\" href=\"javascript:void(0);\">";
		html += "地図上で表示</a>";
		html += "</div>";
	}
	if (detail) {
		html += "</div>";
	}
	return html;
};

var search = function() {
	var query = $("#query").get(0).value;
	if (query.length == 0) {
		return;
	}
	geocoder.getLatLng(query, function(p) {
		if(p) {
			spotLat = p.lat();
			spotLng = p.lng();
			updateSpot(true);
			var html = "<h2 class=\"marker\">" + query + "</h2>";
			openMarker(spotLat, spotLng, html);
		} else {
			alert("位置情報が見つかりませんでした。別のキーワードで再度検索してください。");
		}
	});
};

var listenSlider = function(slider, listener) {
	var dragging = false;
	var defValue = null;
	slider.on("dragstart", function() {
		dragging = true;
		defValue = slider.getValue();
	});
	slider.on("dragend", function() {
		dragging = false;
		var value = slider.getValue();
		if (defValue != value) {
			listener(value);
		}
	});
	slider.on("change", function(source, value) {
		if (!dragging) {
			listener(value);
		}
	});
};

var createSlider = function(name, v, customOnChange, listener, w) {
	var slider = new Ext.Slider({
		renderTo: name + "Slider",
		width: w,
		animate: false,
		increment: 1,
		minValue: 0,
		maxValue: labels[name].length - 1,
		value: v
	});
	slider.on("change", function(source, value) {
		$("#" + name + "Label").html(labels[name][value]);
		if (customOnChange) {
			customOnChange(source, value);
		}
	});
	listenSlider(slider, listener);
	$("#" + name + "Label").html(labels[name][v]);
	return slider;
};

var initializeControls = function(options) {
	var viewport = new Ext.Viewport({
	    layout:"border",
	    items: [{
			contentEl: "north",
	        region: "north",
			autoHeight: true,
			border: false,
	        margins: "0 0 0 0"
		},
		{
			contentEl: "south",
	        region: "south",
			border: false,
	        margins: "0 0 0 0"
	    },
		{
			contentEl: "west",
	        region:"west",
			split: true,
			border: false,
	        margins: "0 0 0 0",
	        cmargins: "0 0 0 0",
	        width: 288,
	        minSize: 72,
	        maxSize: 576,
			autoScroll: true
	    },
		{
			contentEl: "center",
	        region:"center",
			border: false,
	        margins: "0 0 0 0"
	    }]
	});

	var listener = function(value) { updateSpot(); };

	minPriceSlider = createSlider("minPrice", options.minPrice,
		function(slider, value) {
			if (value > getCurrentMaxPrice()) {
				maxPriceSlider.setValue(value);
			}
		},
		listener
	);
	maxPriceSlider = createSlider("maxPrice", options.maxPrice,
		function(slider, value) {
			if (value < getCurrentMinPrice()) {
				minPriceSlider.setValue(value);
			}
		},
		listener
	);
	minScoreSlider = createSlider("minScore", options.minScore,
		function(slider, value) {
			if (value > getCurrentMaxScore()) {
				maxScoreSlider.setValue(value);
			}
		},
		listener
	);
	maxScoreSlider = createSlider("maxScore", options.maxScore,
		function(slider, value) {
			if (value < getCurrentMinScore()) {
				minScoreSlider.setValue(value);
			}
		},
		listener
	);
	radiusSlider = createSlider("radius", options.radius, null,
		function() { updateSpot(true); }, 240
	);

	updateCategoryComboBoxes(options.categoryInfo);
	$("#situation").get(0).value = options.situation;

	spotLat = options.spotLat;
	spotLng = options.spotLng;

	viewport.doLayout();
	initializeGMap(options.lat, options.lng, options.zoom);
};

var getCurrentZoom = function() {
	return map.getZoom();
};

var getCurrentCategory = function() {
	var s = "";
	for (var i = 0; i < 4; i++) {
		var id = "#category" + i;
		var elem = $(id).get(0);
		if (!elem) {
			break;
		}
		if (i > 0) {
			s += ",";
		}
		s += elem.value;
	}
	return s;
};

var getCurrentSituation = function() {
	return $("#situation").get(0).value;
};

var getCurrentRadius = function() {
	return radiusSlider.getValue();
};

var getCurrentMinPrice = function() {
	return minPriceSlider.getValue();
};

var getCurrentMaxPrice = function() {
	return maxPriceSlider.getValue();
};

var getCurrentMinScore = function() {
	return minScoreSlider.getValue();
};

var getCurrentMaxScore = function() {
	return maxScoreSlider.getValue();
};

var categoryChanged = function(index) {
	for (var i = index + 1; i < 4; i++) {
		var id = "#category" + i;
		$(id + "Container").html("");
	}
	var s = getCurrentCategory();
	$.getJSON(BASE_URL + "/info/category", { name: s }, function(json) {
		updateCategoryComboBoxes(json);
	});
	updateSpot();
};

var updateCategoryComboBoxes = function(info) {
	var categories = info.categories;
	var selectedCategories = info.selectedCategories;
	for (var i = 0; i < 4; i++) {
		var id = "#category" + i;
		if (i < categories.length) {
			$(id + "Container").html(createCategoryComboBoxHtml(
				i, categories[i], selectedCategories[i]));
		} else {
			$(id + "Container").html("");
		}
	}
};

var createCategoryComboBoxHtml = function(index, items, selectedItem) {
	var id = "category" + index;
	var html = "<select id=\"" + id + "\" onchange=\"categoryChanged(" + index + ")\">";
	$.each(items, function(i, e) {
		if (e == selectedItem) {
			html += "<option value=\"" + e + "\" selected=\"selected\">";
		} else {
			html += "<option value=\"" + e + "\">";
		}
		html += e;
		html += "</option>";
	});
	html += "</select>";
	return html;
};

var getAbsolutePosition = function(elem) {
	var p = { left: 0, top: 0 };
	while(elem) {
		p.left += elem.offsetLeft;
		p.top  += elem.offsetTop;
		elem = elem.offsetParent;
	}
	return p;
};

var bookmark = function() {
	var url = BASE_URL + "/info/bookmark";
	url += "?" + createRadiusParams();
	var c = map.getCenter();
	url += "&lat=" + c.lat();
	url += "&lng=" + c.lng();
	url += "&" + createCommonParams();

	$.getJSON(url, {}, function(json) {
		var resultUrl = BASE_URL + "/" + json;
		var html = "<a target=\"_blank\" href=\"" + resultUrl + "\">";
		html += resultUrl;
		html += "</a>";
		$("#bookmarkResult").html(html);
	});
};

