var geocoder = null;
var map = null;
var startPoint;
var endPoint;
var lastInput;
var areaRoute = false;
var radius = null;
var circleLine = null;
var center = null;
var driver;
var passenger;
var mapId;
var geocodingComplete = true;
var sent = false;

var reasons=[];
reasons[G_GEO_SUCCESS]            = "Success";
reasons[G_GEO_MISSING_ADDRESS]    = "Please enter an address.";
reasons[G_GEO_UNKNOWN_ADDRESS]    = "That address is not valid.";
reasons[G_GEO_UNAVAILABLE_ADDRESS]= "Sorry, PickupPal can't service that address.";
reasons[G_GEO_BAD_KEY]            = "Sorry, PickupPal can't service your location.";
reasons[G_GEO_TOO_MANY_QUERIES]   = "Sorry, PickupPal can't accept any more locations today.";
reasons[G_GEO_SERVER_ERROR]       = "Sorry, PickupPal could not successfully process your request.";

function setElementDisplay(elementId, display) {
    var el = document.getElementById(elementId);
    if (el) {
        el.style.display = display;
    }
}

function hideCalloutSquare() {
    setElementDisplay("calloutSquare", "none");
}

function showCalloutSquare() {
    setElementDisplay("calloutSquare", "block");
}

function hideMap() {
    setElementDisplay("map", "none");
    setElementDisplay("close", "none");
}

function showMap() {
    setElementDisplay("map", "block");
    setElementDisplay("close", "block");
}

function hideError() {
    setElementDisplay("errorDisplay", "none");
}

function showError() {
    setElementDisplay("errorDisplay", "block");
}

function initialize(mapId) {
    if (GBrowserIsCompatible()) {
	if(document.getElementById("radius"))
            radius = document.getElementById("radius").value;

        map = new GMap2(document.getElementById(mapId), {size: new GSize(300,300)} );
        map.addControl(new GSmallMapControl());
        var imgBase = "http://www.pickuppal.com/pup/images/";

        //TODO These need to be changed to the actual image paths
        blueStartIcon = new GIcon(G_DEFAULT_ICON);
        blueStartIcon.image = imgBase + "startblue.png";
        blueStartMarkerOptions = { icon:blueStartIcon };

        orangeStartIcon = new GIcon(G_DEFAULT_ICON);
        orangeStartIcon.image = imgBase + "startorange.png";
        orangeStartMarkerOptions = { icon:orangeStartIcon };

        blueEndIcon = new GIcon(G_DEFAULT_ICON);
        blueEndIcon.image = imgBase + "endblue.png";
        blueEndMarkerOptions = { icon:blueEndIcon };

        orangeEndIcon = new GIcon(G_DEFAULT_ICON);
        orangeEndIcon.image = imgBase + "endorange.png";
        orangeEndMarkerOptions = { icon:orangeEndIcon };

        map.setCenter(new GLatLng(0,0), 13);
        geocoder = new GClientGeocoder();
        showCalloutSquare();
        hideMap();
        hideError();
        hideMapIcon("start");
        hideMapIcon("end");
        lastInput = "";
    }
}

function addMapTypeControl(){
    map.addControl(new GMapTypeControl());
}

function createStartMap(){
    hideCalloutSquare();
    hideError();
    showMap();
    map.checkResize();
    map.panTo(startPoint);
    if(mapId)
        updateMap(mapId);
}

function createEndMap(){
    hideCalloutSquare();
    hideError();
    showMap();
    map.checkResize();
    map.panTo(endPoint);
    if(mapId)
        updateMap(mapId);
}

function closeMap(){
    showCalloutSquare();
    hideError();
    hideMap();
}

function showMapIcon(id){
    setElementDisplay(id + "MapIcon", "inline");
}

function hideMapIcon(id){
    setElementDisplay(id + "MapIcon", "none");
}

    // TODO: Displays the coordinates to be sent in a popup (comment or remove.)
    //function test(){
    //	alert("Coords: "+document.getElementById("startLat").value+" "+document.getElementById("startLng").value+", "+document.getElementById("endLat").value+" "+document.getElementById("endLng").value);
    //}

function alterMapRouteType(routeType){
    if (routeType == "CENTRED") {
        areaRoute = true;
    } else {
        areaRoute = false;
        drawCircle(true);
    }

    if(mapId)
        updateMap(mapId);
}

function alterMapRadius(r){
    radius = r;
    if(mapId)
        updateMap(mapId);
}

function isGeocodingComplete(){
	return geocodingComplete;
}

function isSent(){
	return sent;
}

function setSent(sent){
	this.sent = sent;
}

function showAddress(id) {
	geocodingComplete = false;
    mapId = id;
    driver = false;
    passenger = false;
    var name = document.getElementById(id).name;
    if(name == "start.typedIn" || name == "end.typedIn")
        driver = true;
    if(name == "waybill.bidRequest.origin.typedIn" || name == "waybill.bidRequest.destination.typedIn")
        passenger = true;

    var address=document.getElementById(id).value;
    if (address == "") {
        document.getElementById(id + "Lat").value = "";
        document.getElementById(id + "Lng").value = "";
        geocodingComplete = true;
        return;
    }

    if (geocoder && (lastInput != address)) {
        geocoder.getLocations(
            address,
            function(response){
                if(response.Status.code == G_GEO_SUCCESS){
                    removeClass(document.getElementById(id), "error");
                    place = response.Placemark[0];
                    point = new GLatLng(place.Point.coordinates[1],
                                        place.Point.coordinates[0]);
                    lastInput = address;
                    document.getElementById(id).value=place.address;
                    document.getElementById(id+"Lat").value=point.lat();
                    document.getElementById(id+"Lng").value=point.lng();
                    showMapIcon(id);
                    updateMap(id);
                }
                else{
                    document.getElementById(id + "Lat").value = "";
                    document.getElementById(id + "Lng").value = "";

                    hideCalloutSquare();
                    hideMap();
                    showError();
                    hideMapIcon(id);
                    addClass(document.getElementById(id), "error");
                }
            }
        );
    }
    geocodingComplete = true;
}

function updateMap(id){
    if(id=="start"){
        startPoint = new GLatLng(document.getElementById(id+"Lat").value, document.getElementById(id+"Lng").value);
        center = startPoint;
    }
    if(id=="end")
        endPoint = new GLatLng(document.getElementById(id+"Lat").value, document.getElementById(id+"Lng").value);
    map.clearOverlays();
    if(driver){
        if(startPoint){
            var startMarker = new GMarker(startPoint, orangeStartMarkerOptions);
            map.addOverlay(startMarker);
            if(areaRoute){
                drawCircle(false);
            }
        }
        if(endPoint && !areaRoute)
            map.addOverlay(new GMarker(endPoint, orangeEndMarkerOptions));
    }
    if(passenger){
        if(startPoint)
            map.addOverlay(new GMarker(startPoint, blueStartMarkerOptions));
        if(endPoint)
            map.addOverlay(new GMarker(endPoint, blueEndMarkerOptions));
    }
}

function removeClass(el, className) {
    if (!(el && el.className)) {
        return;
    }
    var cls = el.className.split(" ");
    var ar = new Array();
    for (var i = cls.length; i > 0;) {
        if (cls[--i] != className) {
            ar[ar.length] = cls[i];
        }
    }
    el.className = ar.join(" ");
};

function addClass(el, className) {
    removeClass(el, className);
    el.className += " " + className;
};

function drawCircle(clear){
    if(circleLine)
        map.removeOverlay(circleLine);

    if(clear)
        return;

    var normalProj = G_NORMAL_MAP.getProjection();

    var testPoint = new GLatLng(center.lat() + 1.0, center.lng());
    var testDistance = center.distanceFrom(testPoint);

    var radiusPoint = new GLatLng(center.lat() + (radius / testDistance),
                                  center.lng());

    //console.log(center.distanceFrom(radiusPoint));

    var zoom = map.getZoom();
    var centerPt = normalProj.fromLatLngToPixel(center, zoom);
    var radiusPt = normalProj.fromLatLngToPixel(radiusPoint, zoom);

    var circlePoints = Array();

    with (Math) {

        var bounds = new GLatLngBounds();
        var r = floor(sqrt(pow((centerPt.x-radiusPt.x),2) + pow((centerPt.y-radiusPt.y),2)));

        for (var a = 0 ; a < 361 ; a+=5 ) {
            var aRad = a*(PI/180);
            var y = centerPt.y + r * sin(aRad)
                var x = centerPt.x + r * cos(aRad)
                var p = new GPoint(x,y);
            circlePoints.push(normalProj.fromPixelToLatLng(p, zoom));
            bounds.extend(normalProj.fromPixelToLatLng(p, zoom));
        }

        map.setCenter(center, map.getBoundsZoomLevel(bounds));
        circleLine = new GPolyline(circlePoints, "#F7841E", null, 0.4 );
        map.addOverlay(circleLine);
    }
}

