var map = null;
var geocoder = null; // the geocoding object
var tooltip = null;
var search_marker = null; // the marker that gets placed for address searches
var search_marker_pin = null; // the pin for the search marker
var basePin = null;

var svControl = null;
var svPan = null; // street view panoramic
var svOverlay = null; // street view overlay
var svMarker = null;
var svIcon = null;
var svOverlayAdded = false;

var current_zoom = null;
var zoomlevel_out = null;

function showTooltip(marker, text, mapdiv) {
    if (!document.getElementById("tooltip")) initTooltip();
    marker.tooltip = '<table cellspacing="0" class="tooltip"><tr><td class="tleft" width="14"><img src="/gfx/map/tooltip-front2.gif" /></td><td class="tmiddle">'+text+'</td><td class="tright" width="15"><img src="/gfx/map/tooltip-back2.gif" /></td></tr></table>';
    tooltip.innerHTML = marker.tooltip;
    var point=map.getCurrentMapType().getProjection().fromLatLngToPixel(map.fromDivPixelToLatLng(new GPoint(0,0),true),map.getZoom());
    var offset=map.getCurrentMapType().getProjection().fromLatLngToPixel(marker.getPoint(),map.getZoom());
    var anchor=marker.getIcon().iconAnchor;
    var width=marker.getIcon().iconSize.width;
    var height=tooltip.clientHeight;
    var pos = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(offset.x - point.x - anchor.x + width + 5, offset.y - point.y -anchor.y -height + 16));
    pos.apply(tooltip);
    
    var marker_right = findPos(tooltip,"left")+tooltip.offsetWidth;
    
    var themap = document.getElementById(mapdiv);
    var map_right = findPos(themap,"left")+themap.offsetWidth;
    //alert(marker_right);
    //alert(map_right);
    
    if (marker_right > map_right) {
        marker.tooltip = '<table cellspacing="0" class="tooltip"><tr><td class="tleft" width="14"><img src="/gfx/map/tooltip-back1.gif" /></td><td class="tmiddle">'+text+'</td><td class="tright" width="15"><img src="/gfx/map/tooltip-front1.gif" /></td></tr></table>';
        tooltip.innerHTML = marker.tooltip;
        var newpos = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(offset.x - point.x - anchor.x - tooltip.offsetWidth - 5, offset.y - point.y -anchor.y -height + 16)); 
        newpos.apply(tooltip);      
    }
    
    tooltip.style.visibility="visible";
}

function initTooltip() {
    tooltip = document.createElement("div");
    tooltip.style.height = "15px";
    map.getPane(G_MAP_FLOAT_PANE).appendChild(tooltip);
}

function hideTooltip() {
    tooltip.style.visibility = "hidden";
}

function getBrowser() {
    var browser = navigator.userAgent;
    if (browser.indexOf("Firefox") > -1) return "firefox";
    if (browser.indexOf("MSIE 7") > -1) return "ie7";
    if (browser.indexOf("MSIE 6") > -1) return "ie6";
}

// PAN THE MAP
function panMap(way){ switch (way) { case "north": map.panDirection(0,1);break; case "south": map.panDirection(0,-1);break; case "east": map.panDirection(-1,0);break; case "west": map.panDirection(1,0);break; } }
// RETURN TO THE PREVIOUS MAP POSITION
function returnMap() { map.returnToSavedPosition(); }
// ZOOM THE MAP
function zoomMap(way) {
    var currentzoom = map.getZoom();
    var way = parseInt(way);
    if (((currentzoom+way) >= min_zoom) && ((currentzoom+way) <= max_zoom)) {
        map.setZoom(map.getZoom()+parseInt(way));
    }
}
// CHANGE THE MAP TYPE
function viewMap(type) { switch(type) { case "road": map.setMapType(G_NORMAL_MAP);break; case "satellite": map.setMapType(G_SATELLITE_MAP);break; case "hybrid": map.setMapType(G_HYBRID_MAP);break; } }

function findPos(obj,pos) {
    var curleft = curtop = 0;
    if (obj.offsetParent) {
        curleft = obj.offsetLeft; curtop = obj.offsetTop;
        while (obj = obj.offsetParent) { curleft += obj.offsetLeft; curtop += obj.offsetTop;}
    }   
    //return [curleft,curtop];
    if (pos == "left") return curleft;
    if (pos == "top") return curtop;
}

function initZoomBars() {
    // create zoom bars
    createZoomBars();
    //save the map position
    map.savePosition();
    //save the inital zoom level
    current_zoom = map.getZoom();
    //set the zoom bars
    zoomLevels(current_zoom);
}

function createZoomBars() {
    var zoom_bars = "";
    for(var i=1; i<=12; i++) {
        var level = (min_zoom+i)-1;
        zoom_bars += "<a href=\"#\" onmouseout=\"zoomLevelsOut(current_zoom)\" onmouseover=\"zoomLevels("+level+")\" onclick=\"zoomBar("+level+");return false;\"><img id=\"image"+i+"\" alt=\"\" /></a>";
    }
    document.getElementById("zoombars").innerHTML = zoom_bars;
}

function formatZoomLevel(level) {
    var offset = min_zoom-1;
    return level-offset;
}

function zoomBar(level) {
    map.setZoom(level);
}

function zoomLevels(level) {
    level = formatZoomLevel(level);
    clearTimeout(zoomlevel_out);
    
    for (var i=1;i<=level;i++) {
        var img_src = document.getElementById("image"+i).src;
        if (img_src) {
            document.getElementById("image"+i).src = img_src.replace(/down/,"up");
        }
        else {
            document.getElementById("image"+i).src = "/gfx/map/zoom"+i+"-up.gif";
        }
    }
    
    for (var i=level+1;i<=12;i++) {
        var img_src = document.getElementById("image"+i).src;
        if (img_src) {
            document.getElementById("image"+i).src = img_src.replace(/up/,"down");
        }
        else {
            document.getElementById("image"+i).src = "/gfx/map/zoom"+i+"-down.gif";
        }
    }
    
}

function zoomLevelsOut(level) {
    zoomlevel_out = setTimeout("zoomLevels("+level+")",500);
}

/*--- ADDRESS SEARCH BOX ---*/
function addAddressSearch() {
    geocoder = new GClientGeocoder();  
    //geocoder.setBaseCountryCode('UK');      
    map.addControl(new AddressSearchControls());
}

function AddressSearchControls() { }
AddressSearchControls.prototype = new GControl(false, true);

AddressSearchControls.prototype.initialize = function(map) {
    // container
    var container = document.createElement("div");
    container.setAttribute("id", "address_search");
    container.innerHTML = "<form action='#' onsubmit='getAddress();return false;'><input type='text' class='address_input' id='address_field' value='postcode/street search' onfocus='if (this.value==\"postcode/street search\") { this.value=\"\"; this.style.color=\"#000000\"; }' /> <input type='image' src='/gfx/btn-search-sm.gif' class='address_submit' alt='Search' /></form>";
    
    map.getContainer().appendChild(container);
    return container;
}

AddressSearchControls.prototype.getDefaultPosition = function() {
    return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(2, 2));
}


/*--- Address Search Functions ---*/
function getAddress() {
    places = null;
    var address = $('#address_field').val();
    if (address != "") {
        // format the post code to try and get more accurate results
        var new_address = formatPostcode(address);
        geocoder.getLocations(new_address, findAddress);
    }
    else {
        alert("Please enter a post code or address first");
    }
    return false;
}

function findAddress(response) {
    var requested = response.name;
    if (!response || response.Status.code != 200) {
        alert("Sorry, the post code or address, "+response.name+", could not be found");
    }
    else {
        places = new Array();
        for (var i=0; i<response.Placemark.length; i++) {
            var place = response.Placemark[i];
            var place_address = place.address;
            var place_lat = place.Point.coordinates[1];
            var place_lng = place.Point.coordinates[0];
            
            var j = places.length;
            places[j] = new Array();
            places[j]['address'] = place_address;
            places[j]['lat'] = parseFloat(place_lat);
            places[j]['lng'] = parseFloat(place_lng);
            
        }
        if (places.length == 1) {
            showAddress(places[0]['lat'], places[0]['lng']);
        }
        else {
            showAddressPicker();
        }
    }
}

function showAddressPicker() {
    var picker = $('#picker');
    var picker_content = "<div id='pick_address'><p style='margin-bottom:0px'>Your search returned "+places.length+" results. Please choose from the list below:</p><p style='font-weight:normal;font-size:10px;margin-top:0px'>For more accurate results, try adding the city or country to the end of the address</p>";
    for (var i=0; i<places.length; i++) {
        picker_content += "<div";
        if (i%2 == 0) picker_content += " class='stripe'";
        picker_content += "><a href='#' onclick='tb_remove(); showAddress("+places[i]['lat']+", "+places[i]['lng']+"); return false;'>"+places[i]['address']+"</a></div>"
    }
    picker_content += "<div class='close'><input type='button' onclick='tb_remove(); return false;' value='close window' /></div></div>";
    picker.html(picker_content);
    
    var trigger = $('#picker_trigger');
    trigger.unbind("click");
    tb_init(trigger);    
    $('#picker_trigger').trigger('click');
}

function showAddress(lat, lng) {
    removeSearchMarker();
    var point = new GLatLng(lat, lng);
    search_marker = new GMarker(point, search_marker_pin);
    GEvent.addListener(search_marker, "click", function() {
        if (confirm("Do you want to remove the flag from the map?")) {
            map.removeOverlay(search_marker);
        }
    });
    map.addOverlay(search_marker);
    map.setCenter(point, 14);
}

function removeSearchMarker() {
    if (search_marker != null) {
        map.removeOverlay(search_marker);
    }
}

// FORMATS A POSTCODE TO REMOVE THE LAST TWO LETTERS
function formatPostcode(address) {
    new_address = address.replace(" ", "");
    var postcodes = new Array();
    // FULL POSTCODE
    postcodes[0] = /^[A-Za-z]{1,2}[0-9]{1,2}[A-Za-z]?[0-9][A-Za-z]{2}$/;
    // LAST LETTER MISSING
    postcodes[1] = /^[A-Za-z]{1,2}[0-9]{1,2}[A-Za-z]?[0-9][A-Za-z]{1}$/;    
    for (var i=0; i<postcodes.length; i++) {
        if (postcodes[i].test(new_address)) {
            if (i == 0) {
                address = address.substr(0, address.length-2);
            }
            else {
                address = address.substr(0, address.length-1);
            }
        }
    }
    return address;
}

function moveOverview() {
    var omap = document.getElementById("map_overview");
    if (omap) {
        var n_map = document.createElement("div");
        n_map.appendChild(omap);
        // re styling
        var firstdiv = $('div:first', omap);
        firstdiv.css("backgroundColor", "transparent").css("border","none");
        
        // remove minimise button
        $('img[src=http://maps.google.co.uk/intl/en_uk/mapfiles/mapcontrols2.png]', omap).remove();
        
        // Add the overview to the body of the document
        document.getElementById("smallmap").appendChild(n_map);
        
        // realign copyright message
        $('#map > div:eq(1)').css("right", "0px");
    }
    else {
        // The idea of this hack also comes from Mike Williams
        setTimeout(moveOverview, 50);
    }
}

function initSearchMarkerPin() {    
    // SET UP THE SEARCH MARKER PIN
    search_marker_pin = new GIcon();
    search_marker_pin.image = "/gfx/map/pin-location.png"
    search_marker_pin.shadow = "/gfx/map/pin-location-shadow.png";
    search_marker_pin.iconSize = new GSize(74, 52);
    search_marker_pin.shadowSize = new GSize(74, 52);
    search_marker_pin.iconAnchor = new GPoint(29, 52);
}

function initGeocoder(country) {
    geocoder = new GClientGeocoder();
    geocoder.setBaseCountryCode(country);
}

/**
 * STREET VIEW FUNCTIONS
 */
function initStreetView() {
    svOverlay = new GStreetviewOverlay();
    GEvent.addListener(svOverlay, "changed", function(has) {
        checkStreetView(has);
    });
    
    svPan = new GStreetviewPanorama(document.getElementById("streetview"));    
    GEvent.addListener(svPan, "initialized", moveStreetViewIcon);
    GEvent.addListener(svPan, "yawchanged", rotateStreetViewIcon);
    
	addStreetViewControl();
}

function addStreetViewHelp() {
	$('#streetview').html([
		'<div style="padding:5px;font-size:12px;">',
			'In order to start using Street View, please move the Street View marker (<img style="position:relative;top:20px;" src="/gfx/map/man_arrow-1.png"/> ) directly over a street marked with a blue outline.',
			'<br/><br/>',
			'If there are no streets marked with a blue outline then Street View is currently not available in this location.',
		'</div>'
	].join(''));
}

function StreetViewControl() {}
StreetViewControl.prototype = new GControl();
StreetViewControl.prototype.initialize = function(map) {
    var container = document.createElement("div");
    $(container).attr('id', 'streetviewcontrol');
    this.setButtonStyle(container);
    GEvent.addDomListener(container, "click", toggleStreetView);
    container.innerHTML = "Show Street View";
    map.getContainer().appendChild(container);
    return container;        
}    
StreetViewControl.prototype.getDefaultPosition = function() {
    return new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(2, 2));
}
StreetViewControl.prototype.setButtonStyle = function(button) {
    button.style.textDecoration = "underline";
    button.style.color = "#0000cc";
    button.style.backgroundColor = "white";
    button.style.font = "small Arial";
    button.style.border = "1px solid black";
    button.style.padding = "2px";
    button.style.marginBottom = "3px";
    button.style.textAlign = "center";
    button.style.width = "120px";
    button.style.cursor = "pointer";
}

function addStreetViewControl() {
    svControl = new StreetViewControl();
    map.addControl(svControl);
}
function removeStreetViewControl() {
    map.removeControl(svControl);
}

function toggleStreetView() {
    if (!svOverlayAdded) {
        svOverlayAdded = true;
        map.addOverlay(svOverlay);
        $('#streetviewcontrol').html('Hide Street View');
	    showStreetView(null, map.getCenter());
    }
    else {
        svOverlayAdded = false;
        $('#streetviewcontrol').html('Show Street View');
        map.removeOverlay(svOverlay);
        if (svMarker != null) map.removeOverlay(svMarker);
        svPan.remove();
        $('#streetview').slideUp();
    }
}

function showStreetView(overlay, latlng) {
    $('#streetview').slideDown("normal", function() {
	    if (svMarker == null) {
            svIcon = new GIcon();
		    svIcon.iconSize = new GSize(49, 52);
		    svIcon.iconAnchor = new GPoint(25, 35);
            svIcon.image = '/gfx/map/man_arrow-1.png';
	        svMarker = new GMarker(latlng, {
                icon: svIcon,
                draggable: true
            });
            GEvent.addListener(svMarker, "dragstart", function(latlng) {
               svMarker.setImage('/gfx/map/man_arrow-1.png');
            });
		    GEvent.addListener(svMarker, "dragend", function(latlng) {
               showStreetView(overlay, latlng);
            });
	    }
	    else {
	        map.removeOverlay(svMarker);
	        svMarker.setLatLng(latlng);
	    }
	    $('#streetview').show();
	    svPan.setLocationAndPOV(latlng);    
	    map.addOverlay(svMarker);
    	addStreetViewHelp();
    });
}

function moveStreetViewIcon(location) {
    svMarker.setLatLng(location.latlng);
}

function rotateStreetViewIcon(yaw) {
    niceYaw = parseInt(Math.round(yaw));
    while (niceYaw%24 != 0) {
        niceYaw--;
    }
    niceYaw = (niceYaw/24)+1;
    svMarker.setImage('/gfx/map/man_arrow-'+niceYaw+'.png');
}

function checkStreetView(has) {	
	if (false === has) {
		alert("Street view is not currently available in this area");
	}
}

function svHandleNoFlash(errorCode) {
    if (errorCode == 603) {
        alert("Error: Flash doesn't appear to be supported by your browser");
    }
}





