var animateX = -20;
var animateInterval = 24;

var currentPage = null;
var currentDialog = null;
var currentWidth = 0;
var currentHash = location.hash;
var hashPrefix = "#_";
var pageHistory = [];
var map;
var lyrMarkers;
var currentAssetId;
var lastMove = new Date().getTime();
var useGeoLocation;

var resultsValid;

addEventListener("load", function(event)
{
	useGeoLocation = geo_position_js.init();
	
	var body = document.getElementsByTagName("body")[0];
    for (var child = body.firstChild; child; child = child.nextSibling)
    {
        if (child.nodeType == 1 && child.getAttribute("selected") == "true")
        {
            showPage(child);
            break;
        }
    }
	
	// an event for handling orientation change?
	window.onorientation = function (){
		alert('orientation change');
	}
	
	// fill in the neighborhood list
	populateNeighborhoods();

	// set up the search map
	var aoOptions = {
		maxExtent: new OpenLayers.Bounds(-8408769.979606524, 4810537.727413016, -8325692.989193542, 4907460.882894828),
		maxResolution: 276.9233013766053,
		minResolution: 1.19432856685505,
		projection: "EPSG:900913",
		units: 'm',
		controls: [new OpenLayers.Control.Navigation(), new OpenLayers.Control.BigZoom()]
	};
    var aoBaseLayer = new OpenLayers.Layer.ArcGIS93Rest("ArcOnline", 
		"http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/export", 
		{ format:'jpg' }, 
		{ buffer:0, displayOutsideMaxExtent:true });
    	
    lyrMarkers = new OpenLayers.Layer.Markers("Photos");

    map = new OpenLayers.Map('searchMap', aoOptions);
	
	map.addLayers([aoBaseLayer, lyrMarkers]);
	map.zoomToMaxExtent();
	
	map.events.register('moveend', map, function(e){
		resultsValid = false;
		lastMove = new Date().getTime();
		setTimeout(doSearch, 1200);
	});
		
    hook_touch_to_mouse(map.div);

    setInterval(checkOrientAndLocation, 300);
    setTimeout(scrollTo, 0, 0, 1);
}, false);



addEventListener("click", function(event)
{
    event.preventDefault();

    var link = event.target;
    while (link && link.localName && link.localName.toLowerCase() != "a")
        link = link.parentNode;

    if (link && link.hash)
    {
        var page = document.getElementById(link.hash.substr(1));
        showPage(page);
    }
}, true);

function checkOrientAndLocation()
{
    if (window.outerWidth != currentWidth)
    {
        currentWidth = window.outerWidth;

        var orient = currentWidth == 320 ? "profile" : "landscape";
        document.body.setAttribute("orient", orient);
    }

    if (location.hash != currentHash)
    {
        currentHash = location.hash;

        var pageId = currentHash.substr(hashPrefix.length);
        var page = document.getElementById(pageId);
        if (page)
        {
            var index = pageHistory.indexOf(pageId);
            var backwards = index != -1;
            if (backwards)
                pageHistory.splice(index, pageHistory.length);
                
            showPage(page, backwards);
        }
    }
}
    
function showPage(page, backwards)
{
    if (currentDialog)
    {
        currentDialog.removeAttribute("selected");
        currentDialog = null;
    }

    if (page.className.indexOf("dialog") != -1)
        showDialog(page);
    else
    {        
        location.href = currentHash = hashPrefix + page.id;
        pageHistory.push(page.id);

        var fromPage = currentPage;
        currentPage = page;

        var pageTitle = document.getElementById("pageTitle");
        
		if (page.title === "Image") {
			pageTitle.style.display = 'none';
		}
		else {
			pageTitle.style.display = 'block';
		}
        pageTitle.innerHTML = page.title || "";
        pageTitle.setAttribute("class", page.id);

        var homeButton = document.getElementById("homeButton");
        if (homeButton)
            homeButton.style.display = ("#"+page.id) == homeButton.hash ? "none" : "inline";

        if (fromPage)
            setTimeout(swipePage, 0, fromPage, page, backwards);
    }
}

function swipePage(fromPage, toPage, backwards)
{
	if (fromPage === toPage) {
		return;
	}
    toPage.style.left = "100%";
    toPage.setAttribute("selected", "true");
    scrollTo(0, 1);
    
    var percent = 100;
    var timer = setInterval(function()
    {
        percent += animateX;
        if (percent <= 0)
        {
            percent = 0;
            fromPage.removeAttribute("selected");
            clearInterval(timer);
        }

        fromPage.style.left = (backwards ? (100-percent) : (percent-100)) + "%"; 
        toPage.style.left = (backwards ? -percent : percent) + "%"; 
    }, animateInterval);
}

function showDialog(form)
{
    currentDialog = form;
    form.setAttribute("selected", "true");
    
    form.onsubmit = function(event)
    {
        event.preventDefault();
        form.removeAttribute("selected");

        var index = form.action.lastIndexOf("#");
        if (index != -1)
            showPage(document.getElementById(form.action.substr(index+1)));
    }

    form.onclick = function(event)
    {
        if (event.target == form)
            form.removeAttribute("selected");
    }
}

function populateNeighborhoods(){
	var eSplit, minx, miny, maxx, maxy;
	// clear the list
    $('#NeighborhoodMenu').empty();
	$.ajax({
		url: config.handlerBase + "Regions.ashx",
		type: 'GET',
		dataType: 'json',
		success: function(data) {
			$.each(data.regions, function(i, region){
				eSplit = region.extent.split(',');
				minx = eSplit[0];
				miny = eSplit[1];
				maxx = eSplit[2];
				maxy = eSplit[3];
				$('#NeighborhoodMenu').append('<li>' + 
						'<a onclick="goToMap(' + minx + ',' + miny + ',' + maxx + ',' + maxy + ');">' + region.name + '</a>' + 
					'</li>');
			});
		},
		error: function(resp) {
		}
	});
}

function goToMap(minx, miny, maxx, maxy){
	if (minx && miny && maxx && maxy){
		map.zoomToExtent(new OpenLayers.Bounds(minx, miny, maxx, maxy));
	}
	doSearch();
	// go to the map page
	showPage(document.getElementById('Map'));
}

function doLocationSearch(location){
	// get the location from the geocoding handler
	$.ajax({
		url: getFullHandlerUrl("GeoCode.ashx"),
		dataType: "json",
		type: "POST",
		data: {
			address: location
		},
		success: function(data){
			var centerX = data.matches[0].xcoord,
				centerY = data.matches[0].ycoord;
			goToMap(+centerX - config.mapBuf,
					+centerY - config.mapBuf,
					+centerX + config.mapBuf,
					+centerY + config.mapBuf);
		}
	});
}

function showBusy(on){
	if (on === true){
		$("#resultCountDesc").html("<img src='ajax-loader.gif' />");
	}
	else{
	}
}

function doSearch(){
	var now = new Date().getTime();
	if (resultsValid === true || lastMove > now - config.searchWait){
		return;
	}
	showBusy(true);
	$.ajax({
		url: config.handlerBase + "Thumbnails.ashx",
		dataType: "json",
		type: "POST",
		data: {
			type: "area",
			urlqs: buildQs(),
			start: 0,
			limit: config.markerLimit,
			request: "Images"
		},
		success: function(searchResponse){
			var marker, icon, loc, i, item, locSplit, resultCountDesc;

			// Set the description of how many results came back from the search.
			if (searchResponse.totalImages > config.markerLimit){
				resultCountDesc = "Showing first " + config.markerLimit + " of " + searchResponse.totalImages + " results";
			}
			else if (searchResponse.totalImages === 0){
				resultCountDesc = "No results for search area";
			}
			else if (searchResponse.totalImages === 1){
				resultCountDesc = "Found 1 result";
			}
			else {
				resultCountDesc = "Found " + searchResponse.totalImages + " results";
			}
				
			$("#resultCountDesc").html(resultCountDesc);

			// Add the markers resulting from the search.
			destroyMarkers();
			for (i = Math.min(config.markerLimit, searchResponse.images.length) - 1; i >= 0; i--) {
				item = searchResponse.images[i];
				locSplit = item.loc.split("?");
				loc = new OpenLayers.LonLat(locSplit[0], locSplit[1]);
				icon = new OpenLayers.Icon(
					'icon_label.png',
					new OpenLayers.Size(30,30),
					new OpenLayers.Pixel(-30,-30)
				);
				icon.assetId = item.assetId;
				marker = new OpenLayers.Marker(loc, icon);
				marker.events.register( "click", marker, function(e) {
					showDetails(e.object.icon.assetId);
	            }); 
				lyrMarkers.addMarker(marker);
			}
			resultsValid = true;
			showBusy(false);
		}
	});
}

function buildQs(){
	var bounds = map.getExtent();
	return "type=area&minx=" + bounds.left + "&maxx=" + bounds.right + "&miny=" + bounds.bottom + "&maxy=" + bounds.top + "&updateDays=0&sortOrderP=Distance";
}

function showDetails(assetId){
	// set the details
	setDetails(assetId);
	
	// go to the detail page
	showPage(document.getElementById('Details'));
}

function getFullHandlerUrl(handlerUrl){
	return (config.handlerUrlEncrypt === true) ?
	config.handlerBase + escape(handlerUrl) :
	config.handlerBase + handlerUrl;
}

function setDetails(assetId){
	currentAssetId = assetId;
	var newHtml = "<img class='assetImg' src='" + getFullHandlerUrl("MediaStream.ashx?SC=2&assetId=" + assetId) + "' />";
	$('#detailImage').html(newHtml);
	$.ajax({
		url: config.handlerBase + "Details.ashx",
		data: { assetId: assetId },
		dataType: "json",
		type: "POST",
		beforeSend: function(request, b, c){
			var req = request;
		},
		success: function(assetInfo){	
			var asset, dateParts, dateText;
			asset = assetInfo.assets[0];
			dateParts = asset.date.split('*');
			if (dateParts.length > 1){
				dateText = dateParts[1];
			}
			$('#title').html(asset.title);
			$('#collId').html(asset.collId);
			$('#address').html(asset.address);
			$('#date').html(dateText);
			$('#description').html(asset.desc);
		}
	});
}

function destroyMarkers(){
	var markers = lyrMarkers.markers;
	var i;
	lyrMarkers.clearMarkers();
	for (i = 0; i < markers.length; i++){
		markers[i].destroy();
	}
}

function setFullImage(){
	$("#FullImage").html("<img src='" + getFullHandlerUrl("MediaStream.ashx?SC=2&assetId=" + currentAssetId) + "' />");
}

function doLocateAndSearch(){
	if(useGeoLocation){
		geo_position_js.getCurrentPosition(success_callback,error_callback,{enableHighAccuracy:true});
	}
	else{
		alert("Functionality not available");
	}
}

function success_callback(p) {
	var centerX = p.coords.longitude,
		centerY = p.coords.latitude;
		
	var src = new Proj4js.Proj('EPSG:4326');
	var dest = new Proj4js.Proj('EPSG:900913');
	var point = new Proj4js.Point(centerX, centerY);
	Proj4js.transform(src, dest, point);
	var pointLonLat = new OpenLayers.LonLat(point.x, point.y);

	if (map.maxExtent.containsLonLat(pointLonLat)) {
		goToMap(point.x - config.mapBuf, point.y - config.mapBuf, point.x + config.mapBuf, point.y + config.mapBuf);
	} else {
		alert("Your location was reported outside of the application area.");
	}
}

function success_callback2(p)
{
	var centerY = p.coords.latitude, 
		centerX = p.coords.longitude;
	var source = new Proj4js.Proj('EPSG:4326');
	var dest = new Proj4js.Proj('EPSG:102100');
	var projPoint = new Proj4js.Point(+centerX, +centerY);
	Proj4js.transform(source, dest, projPoint);
	if (map.maxExtent.containsLonLat(new OpenLayers.LonLat(projPoint.x, projPoint.y))){
		goToMap(+projPoint.x - config.mapBuf,
				+projPoint.y - config.mapBuf,
				+projPoint.x + config.mapBuf,
				+projPoint.y + config.mapBuf);
	}
	else{
		alert("Your location was reported outside of the application area.");
	}
}

function error_callback(p)
{
	alert('error='+p.message);
}	
