$(function() {
    $(".dialog").dialog( {
        width: 500,
        modal: true,
        autoOpen: false
    });

    initialize();   
});


var map;
var pos;
var locations = new Array();
var geocoder;
var sportList;
var icons;


function initialize() {
    if (!GBrowserIsCompatible()) {
        return;
    }

    var mapTitle = $("#map-container").attr("title");
    $("#map-container").attr("title", "");
    if (mapTitle && mapTitle=="edit") {
        sk_initEdit();
        return;
    }
    if (mapTitle && mapTitle=="view_point") {
        sk_initViewPoint();
        return;
    }
    
    if (mapTitle && mapTitle=="view_suburb") {
        sk_initViewSuburb();
        return;
    }
    
    if (mapTitle && mapTitle=="main") {
    	sk_initMain();
    	return;
    }
    

}

function sk_initViewSuburb() {
    map = new GMap2(document.getElementById("map-container"));
    map.setCenter(new GLatLng(-29, 133), 4);
//    map.setCenter(new GLatLng(-33.859972, 151.21111), 14)
    map.setUIToDefault();
    
    geocoder = new GClientGeocoder();
    

    GEvent.addListener(map, "click", function(overlay, latlng) {
        if (map.getZoom()<14) {
            return;
        }

        if (!latlng) {
            return;
        }
    
        pos = latlng;
        var createLocation = "<a href='javascript:;' onclick='sk_openDialog()'>Add a location here</a>";
        map.openInfoWindowHtml(latlng, createLocation);
    });
    
    // load sport list
    sk_loadSportList();
    
    sk_loadLocationList();
}

function sk_loadLocationList() {
    var data = {
            "ajaxFunction": "getLocationList"
    };
    var callback = function(response, textStatus) {
        sk_showSearchResults(response, true);
    };  
    $.post(location.href, data, callback, 'json');

    
}

function sk_initViewPoint() {
    map = new GMap2(document.getElementById("map-container"));
    map.setCenter(new GLatLng(-33.859972, 151.21111), 15)
    map.setUIToDefault();
    
    geocoder = new GClientGeocoder();
    
    // get the location lat and lng if possible
    var lat = $("#input-lat").val();
    var lng = $("#input-lng").val();
    if (lat==0 && lng==0) {
        // geocode the address for edit
        var addr = $("#input-address").val();
        geocoder.getLatLng(addr, function(point) {
            if (point) {
                sk_showPosition(point, false);
            }
        });
        return;
    }
    
    var point = new GLatLng(lat, lng);
    sk_showPosition(point, false);
}

function sk_initEdit() {
    map = new GMap2(document.getElementById("map-container"));
    map.setCenter(new GLatLng(-33.859972, 151.21111), 15)
    map.setUIToDefault();
    
    geocoder = new GClientGeocoder();
    
    // get the location lat and lng if possible
    var lat = $("#input-lat").val();
    var lng = $("#input-lng").val();
    if (lat==0 && lng==0) {
        // geocode the address for edit
        var addr = $("#input-address").val();
        geocoder.getLatLng(addr, function(point) {
            if (point) {
                $("#input-lat").val(point.lat());
                $("#input-lng").val(point.lng());
                sk_showPosition(point, true);
            }
        });
        return;
    }
    
    var point = new GLatLng(lat, lng);
    sk_showPosition(point, true);
    
    // load sport list
    var postFunction = function() {
        sk_setupSuggestion("input-sport-more", "div-sport-more");
    };
    sk_loadSportList(postFunction);
}

function sk_editLocationMore() {
    $('#table-more').show();
    $('#a-more').hide();
    tinyMCE.init({
        theme : "advanced",
        mode: "exact",
        elements : "input-description",
//      plugins : "media",
        theme_advanced_toolbar_location : "top",
        theme_advanced_toolbar_align : "left",
        theme_advanced_buttons1 : "bold,italic,underline,strikethrough,separator,"
        + "justifyleft,justifycenter,justifyright,justifyfull,formatselect,"
        + "bullist,numlist,outdent,indent",
        theme_advanced_buttons2 : "link,unlink,anchor,image,separator,"
        +"undo,redo,cleanup,code,separator,sub,sup,charmap,separator,media",
        theme_advanced_buttons3 : "",
        height:"200px",
        width:"400px"
      });
    
}
function sk_showPosition(point, editable) {
    var marker = new GMarker(point, {draggable: editable});
    if (editable) {
        GEvent.addListener(marker, "dragend", function(newPoint) {
            $("#input-lat").val(newPoint.lat());
            $("#input-lng").val(newPoint.lng());
//          alert($("#input-lat").val() + ", " + $("#input-lng").val());
        });
    }
    map.addOverlay(marker);
    map.panTo(point);
}

function sk_initMain() {
    map = new GMap2(document.getElementById("map-container"));
    map.setCenter(new GLatLng(-29, 133), 4);
//    map.setCenter(new GLatLng(-33.859972, 151.21111), 14)
    map.setUIToDefault();
    
    geocoder = new GClientGeocoder();
    

    GEvent.addListener(map, "click", function(overlay, latlng) {
        if (map.getZoom()<14) {
            return;
        }

        if (!latlng) {
            return;
        }
    
        pos = latlng;
        var createLocation = "<a href='javascript:;' onclick='sk_openDialog()'>Add a location here</a>";
        map.openInfoWindowHtml(latlng, createLocation);
    });
    
    // load sport list
    sk_loadSportList();
    
    $("#table-search").hide();
    
    // try the first search if possible
    // check the input value to see if we are going to do an on load search
    if ($("#input-search").val()) {
        sk_search(1, "", true);
    }
}

function sk_loadSportList(postFunction) {
    var data = {
            "ajaxFunction": "getSportList"
    };
    var callback = function(response, textStatus) {
        sportList = response.sportList;
        if (postFunction) {
            postFunction();
        }
    };  
    $.post(location.href, data, callback, 'json');
}


function sk_openDialog() {
    map.closeInfoWindow();
    
    var needConfirm = false;
    for (var i=0; i<locations.length; i++) {
        if (!locations[i].latlng) {
            // some location does not have latlng ready
            continue;
        }
        var dist = locations[i].latlng.distanceFrom(pos);
        if (dist<1000) {
            needConfirm = true;
            break;
        }
    }
    if (needConfirm) {
        if (!confirm("An existing sport location is close to this position.\n Are you sure this is a different sport location?")) {
            return;
        }
    }
    $(".dialog").html("Loading...");    
    $(".dialog").dialog('option', 'title', '');
    $(".dialog").dialog('open');
    
    // load the dialog content from the server
    var data = {
        'ajaxFunction': 'getDialog'
    };
    
    var callback = function(response, textStatus) {
        sk_showDialog(response, textStatus);
        sk_setupSuggestion("input-sport-more", "div-sport-more");
    };
    $.post(location.href, data, callback, 'json');
}

function sk_setupSuggestion(textBox, beforeDiv) {
    var formatSportItem = function(item) {
        return item.name;
    };
    var completeResult = function(event, item) {
        var str = "<div style='float: left; width: 120px'>";
        str += "<label><input type='checkbox' class='input-sp' checked='checked' name='sports[]' value='"+item.id+"' id='input-sport-"+item.id+"' />";
        str += item.name + "</label></div>";
        $("#"+beforeDiv).before(str);
        $("#"+textBox).val("");
    };
    
    $("#"+textBox).autocomplete(sportList, {'formatItem': formatSportItem}).result(completeResult);
}

function sk_showDialog(data, textStatus) {
    if (data.title) {
        $(".dialog").dialog('option', 'title', data.title);
    }
    $(".dialog").html(data.body);
}

function sk_addLocation() {
    var ret = sk_validateLocationInput();
    if (ret) {
        $("#add-msg").html(ret);
        return;
    }
    
    
    $(".dialog").dialog('close');

    if (!pos) {
        return;
    }
    
    // make ajax call to add the location
    var data = {
        'ajaxFunction': 'saveLocation',
        'lat': pos.lat(),
        'lng': pos.lng()
    };
    
    // TODO: make the return value consistent with the search result
    var callback = function(data, textStatus) {
        var newLoc = {
            'latlng': pos,
            'summary': data
        };
        locations[locations.length] = newLoc;
        sk_showLocation(newLoc, true);
        
    };
    var options = {
        'data': data,
        'success': callback
    };
    $("#form-add").ajaxSubmit(options);
}

function sk_validateLocationInput() {
    // name can not be empty
    if (jQuery.trim($("#input-name").val())=='') {
        return "Please input name";
    }
    
    // need to select at least one sport
    var spLen = $('.input-sp:checked').length;
    if (spLen==0) {
        return "Please choose at least one suitable sport for this location";
    } else if (spLen>5) {
        return "Please choose up to FIVE most suitable sports for this location";
    }
}

function sk_saveLocation() {

    var ret = sk_validateLocationInput();
    if (ret) {
        $("#edit-msg").html(ret);
        return;
    }
    
    var editor = tinyMCE.get('input-description');
    if (editor) {
        $("#input-description").val(editor.getContent());
    }

    // make ajax call to add the location
    var data = {
        'ajaxFunction': 'saveLocation'
    };
    
    // inform user the location has been edited and saved
    var callback = function(data, textStatus) {
        $("#edit-msg").html(data.msg);
        if (data.result) {
            $("input").attr("disabled", "disabled");
            $("select").attr("disabled", "disabled");
            $("#a-more").hide();
        }
    };
    
    var options = {
        'data': data,
        'success': callback,
        'dataType': 'json'
    };
    $("#input-ok").attr("disabled", "disabled");
    $("#form-edit").ajaxSubmit(options);
}


function sk_showLocation(locationData, infoWindow) {
    // check if we need to create the marker
    if (!locationData.marker) {
        if (!locationData.latlng) {
            // creat the latlng
            locationData.latlng = new GLatLng(locationData.obj.lat, locationData.obj.lng);
        }
        // use custom icon
        var markerIcon = G_DEFAULT_ICON;
        if (locationData.obj) {
            markerIcon = sk_getIcon(locationData.obj.type);
        }
        
        var marker = new GMarker(locationData.latlng, {icon:markerIcon});
        map.addOverlay(marker);
        GEvent.addListener(marker, "click", function(){
            var content = locationData.summary;
            marker.openInfoWindowHtml(content);
        });
        locationData.marker = marker;
    }
    
    // check if we need to show the info window
    if (infoWindow) {
        locationData.marker.openInfoWindowHtml(locationData.summary);
    }
}

function sk_getIcon(typeNum) {
    if (!icons) {
        icons = {};
    }
    var typeKey = "type_"+typeNum;
    if (!icons[typeKey]) {
        var typeMap = {
            type_4: "track_36.png",
            type_2: "beach_36.png",
            type_7: "trail_36.png",
            type_14: "reserve_36.png",
            type_3: "oval_field_36.png",
            type_8: "summit_36.png",
            type_0: "unknown_36.png",
            type_12: "river_36.png",
            type_5: "stadium_36.png",
            type_6: "club_36.png",
            type_9: "garden_36.png",
            type_11: "courts_36.png",
            type_1: "park_36.png"};
        var mapIcon = G_DEFAULT_ICON;
        if (typeNum!=0) {
            mapIcon = new GIcon(G_DEFAULT_ICON);
            var iconImage = "images/icons/location_types/" + typeMap[typeKey];
            mapIcon.image = iconImage;
            mapIcon.iconSize = new GSize(28, 36);
        }
        icons[typeKey] = mapIcon;
    }
    return icons[typeKey];
}


function sk_guessAddress() {
    if (!pos) {
        return;
    }
    geocoder.getLocations(pos, sk_populateAddress);
}

function sk_populateAddress(response) {
    if (!response || response.Status.code != 200) {
        $("#add-msg").html("No luck in guessing the address");
    } else {
        place = response.Placemark[0];
        point = new GLatLng(place.Point.coordinates[1],place.Point.coordinates[0]);
        orig = GLatLng.fromUrlValue(response.name);
        dist = Math.round(orig.distanceFrom(point));
        $("#add-msg").html("The guessed address is about " + dist + " meters away from your picked point");
        // populate some fields
        if (place.address) {
            $("#input-address").val(place.address);
        }
        if (place.AddressDetails.Country.AdministrativeArea.Locality.PostalCode.PostalCodeNumber) {
            $("#input-postcode").val(place.AddressDetails.Country.AdministrativeArea.Locality.PostalCode.PostalCodeNumber);
        }
        if (place.AddressDetails.Country.AdministrativeArea.Locality.LocalityName) {
            $("#input-suburb").val(place.AddressDetails.Country.AdministrativeArea.Locality.LocalityName);
        }
        if (place.AddressDetails.Country.AdministrativeArea.AdministrativeAreaName) {
            $("#input-state").val(place.AddressDetails.Country.AdministrativeArea.AdministrativeAreaName);
            $("#row-state").show();
        }
        if (place.AddressDetails.Country.CountryName) {
            $("#input-country").val(place.AddressDetails.Country.CountryName);
            $("#row-country").show();
        }
    }
}

function sk_search(page, dir, onLoad) {
    $("#table-search").show();
    $("#div-world-map").hide();
    var pageNo = 1;
    var direction = '';
    if (page) {
        pageNo = page;
    }
    if (dir) {
        direction = dir;
    }
    var data = {
        'ajaxFunction': 'searchLocations',
        'page': pageNo,
        'direction': direction
    };
    
    if (!onLoad) {
        $("#container-try-address").html("");
        $("#container-results").html("Searching...");
    }
    
//    location.hash = $("#input-search").val(); 
    var callback = function(response, textStatus) {
        
        // track the search if possible
        if (typeof pageTracker != "undefined" && !onLoad) {
            var content = "/location/search/" + $("#input-search").val();
            content += "/"+pageNo;
            if (direction!='') {
                content += "/"+direction;
            }
            pageTracker._trackPageview(content);
        }
        
        if (pageNo==1 && response.result && response.list.length==0) {
            sk_searchAddress();
        } else {
            if (pageNo==1) {
                sk_trySearchAddress();
            }
            sk_showSearchResults(response, onLoad);
        }
    };
    var options = {
        'data': data,
        'success': callback,
        'dataType': 'json'
    };
    $("#form-search").ajaxSubmit(options);
}

function sk_trySearchAddress() {
    var addr = $("#input-search").val();
    geocoder.getLocations(addr, function(response) {
        if (!response || response.Status.code!=200) {
            // can not find anything
            $("#container-try-address").html("");
        } else {
            var place = response.Placemark[0];
            var point = new GLatLng(place.Point.coordinates[1],
                        place.Point.coordinates[0]);
            var strhtml = "Did you mean the address: <a href='javascript:;' id='a-address' onclick='sk_gotoAddress()'>"+place.address+"</a>?";
            $("#container-try-address").html(strhtml);
            pos = point;
        }
    });
}

function sk_demo(addr) {
    $("#input-search").val(addr);
    sk_search();
}

function sk_searchAddress() {
    var addr = $("#input-search").val();
    geocoder.getLocations(addr, function(response) {
        if (!response || response.Status.code!=200) {
            // can not find anything
            $("#container-results").html("We could not find anything for <b>"+addr+"</b>.");
        } else {
            var place = response.Placemark[0];
            var point = new GLatLng(place.Point.coordinates[1],
                        place.Point.coordinates[0]);
            pos = point;
            sk_gotoAddress(place.address);
        }
    });

}

function sk_gotoAddress(addr) {
    if (!addr) {
        addr = $("#a-address").html();
    }
    
    var strhtml = "<p>The map shows the address of <b>"+addr+"</b>.</p>";
    strhtml +="<p>If any locatins found near this address, it will be marked on the map.</p>";
    strhtml +="<p><i>You can add more locations at/near this address by clicking on the map.</i></p>"
    $("#container-results").html(strhtml);

    if (map.getZoom()<14) {
        map.setZoom(14);
    }
    map.closeInfoWindow();
    // pos should be pointing to that address
    map.panTo(pos);
    sk_getLocationsInMap();
}


function sk_showSearchResults(response, onLoad) {
    // XXX clean the previous search results and the possible markers on the map
//  locations = new Array();
    map.clearOverlays();
    
    if (response.result) {
        locations = response.list;
        var htmlString = "";
        for (var i=0; i<locations.length; i++) {
            if (locations[i].obj.lat!=0 && locations[i].obj.lng!=0) {
                locations[i].latlng = new GLatLng(locations[i].obj.lat, locations[i].obj.lng);
            }
            htmlString += locations[i].link;
        }
        if (response.extra) {
            htmlString += response.extra;
        }
        if (!onLoad) {
            // do not set the html value if it is the first time to load the page
            $("#container-results").html(htmlString);
        }
        if (locations[0]) {
            sk_moveTo(locations[0].obj.id);
        }
    }
}

function sk_moveTo(locationId) {
    
    if (typeof(locationId)=="object") {
        var theOne = locationId;
        if (map.getZoom()<14) {
            // zoom to level 14
            map.setZoom(14);
        }
        
        // highlight this result entry
        $(".result-entry").removeClass("result-selected result-in-map");
        $("#result-"+theOne.obj.id).addClass("result-selected");
        map.panTo(theOne.latlng);
        sk_showLocation(theOne, true);
        sk_getLocationsInMap();
        return;
        
    }

    var theOne = null;
    for (var i=0; i<locations.length; i++) {
        if (locations[i].obj.id==locationId) {
            theOne = locations[i];
            break;
        }
    }
    
    if (theOne) {
        if (theOne.latlng) {
            sk_moveTo(theOne);
        } else {
            // geocode the location and show it
            geocoder.getLatLng(theOne.obj.address, function(point) {
                if (point) {
                    theOne.latlng = point;
                    sk_moveTo(theOne);
                }
            });
        }
    }
}

function sk_getLocationsInMap() {
    // only do this when zoom in enough
    if (map.getZoom()<14) {
        return;
    }
    var bounds = map.getBounds();
    var data = {
        'ajaxFunction': 'getLocationsInMap',
        'sw_lat': bounds.getSouthWest().lat(),
        'sw_lng': bounds.getSouthWest().lng(),
        'ne_lat': bounds.getNorthEast().lat(),
        'ne_lng': bounds.getNorthEast().lng()
    };
    
    var callback = function(response, textStatus) {
        sk_showLocationsInMap(response);
        
    };
    $.post(location.href, data, callback, 'json');
}

function sk_showLocationsInMap(response) {
    if (!response.result) {
        return;
    }
    
    // TODO: use a cache to hold locations in map and manage it effectively
    for (var i=0; i<response.list.length; i++) {
        var found = false;
        var idx = 0;
        for (; idx<locations.length; idx++) {
            if (locations[idx].obj.id==response.list[i].obj.id) {
                found = true;
                break;
            }
        }
        if (found) {
            sk_showLocation(locations[idx]);
        } else {
            sk_showLocation(response.list[i]);
        }
        
        $("#result-"+response.list[i].obj.id).addClass("result-in-map");
    }
}

function sk_openReportDialog(locationId) {
    map.closeInfoWindow();
    
    $(".dialog").html("Loading...");
    $(".dialog").dialog('option', 'title', '')    
    $(".dialog").dialog('open');
    
    // load the dialog content from the server
    var data = {
        'ajaxFunction': 'getDialog',
        'type': 'report_location',
        'locationId': locationId
    }
    $.post(location.href, data, sk_showDialog, 'json');

}

function sk_reportLocation() {
    // sanity check
    var error;
    if ($("#input-reason").val()==0) {
        error = "Please choose your reason.";
    } else if (jQuery.trim($("#input-reporter").val())=='') {
        error = "Please enter your name.";
        $("#input-reporter").focus();
    } else if (jQuery.trim($("#input-reporter_email").val())=='') {
        error = "Please enter your email address.";
        $("#input-reporter_email").focus();
    }
    if (error) {
        $("#report-msg").html(error);
        return;
    }
    
    // make ajax call to report the location
    var data = {
        'ajaxFunction': 'reportLocation'
    };
    
    var callback = function(data, textStatus) {
        if (data.result) {
            $("#form-report").hide();
            $("#report-msg").html("We received your report. Thank you!");
        } else if (data.msg) {
            $("#report-msg").html(data.msg);
        }
    };
    
    var options = {
        'data': data,
        'success': callback,
        'dataType': 'json'
    };
    $("#form-report").ajaxSubmit(options);
    
}

function sk_openFeedbackDialog() {
    if (map) {
        map.closeInfoWindow();
    }
    
    $(".dialog").html("Loading...");
    $(".dialog").dialog('option', 'title', '')    
    $(".dialog").dialog('open');
    
    // load the dialog content from the server
    var data = {
        'ajaxFunction': 'getDialog',
        'type': 'give_feedback'
    }
    $.post(location.href, data, sk_showDialog, 'json');
}

function sk_saveFeedback() {
    // sanity check
    var error;
    if ($("#input-summary").val()==0) {
        error = "Please enter the summary.";
        $("#input-summary").focus();
    } else if (jQuery.trim($("#input-content").val())=='') {
        error = "Please enter the detailed content.";
        $("#input-content").focus();
    } else if (jQuery.trim($("#input-email").val())=='') {
        error = "Please enter your email address.";
        $("#input-email").focus();
    }
    if (error) {
        $("#msg").html(error);
        return;
    }
    
    // make ajax call to report the location
    var data = {
        'ajaxFunction': 'saveFeedback'
    };
    
    // saving feedback
    var callback = function(data, textStatus) {
        if (data.result) {
            $("#form-suggest").hide();
            $("#msg").html("We received your feedback. Thank you!");
        } else if (data.msg) {
            $("#msg").html(data.msg);
        }
    };
    
    var options = {
        'data': data,
        'success': callback,
        'dataType': 'json'
    };
    $("#form-suggest").ajaxSubmit(options);
}