/* -*- Mode: js2-mode; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: sw=2 ts=2 et :*/

$(document).ready(function() {
    // Center the map to a default location
    resetMap();

    // Display 'add new location' form
    $('#new_location_form').load('/addlocation-form/', hideAddLocationSections);
    // $('#new_location_form').load(hideAddLocationSections());

    // Display 'search' form
    $('#mod_search').load('/searchlocation/', searchBarLoaded);

    // Bind function to 'Add Location' form's submit button
    $('#addlocation').live('submit', function(event){
        event.preventDefault();

        // At least one location type must be selected
        if ($('#addlocation input:checked').length == 0){
            alert('Please select at least one location type before submitting!');
            return false;
        }

        // No more than 3 location types at a time.
        if ($('#addlocation input:checked').length > 3){
            alert('Please select less than 3 location types!');
            return false;
        }

        // Confirm location on map before submitting
        if ($("input[name=normal-latitude]").val() == ''){
            alert('Please confirm address on map before submitting!');
            return false;
        }

        var formData = $(this).serialize();     // Serialize form data
        $.post('/addlocation-form/', formData, function(data){
            // On success, replace the form content with new HTMl.
            // The new HTML could be form errors or success
            $('#addlocation').replaceWith(data);
            $('#addlocation input:checkbox').removeAttr('checked');
            $('.location_selected').removeClass('location_selected');
            hideAddLocationSections();
        });

    });

    // Bind event handler to submit button of "Search Address"
    $('#geocode').live('submit', function(event){
        event.preventDefault();

        var address = $("input[class='search text'][name='search_address']").val();
        searchAddress(address);
    });

    // Bind event handler to collapse/expand location search types on mouse click
    $("input[name='search_address_button']").live('click', function(event){
       $('#search_location_types').slideUp();
    });

    // Confirm address on map before submitting
    $("input[type='button'][name='confirm']").live('click', function(){
        address = $("#addlocation input[id*='address'][name*='address']").val();
        confirmAddress(address);
    });

    // Display this dialog when an address cannot be found
    $("#dialog-message").dialog({
        autoOpen: false,
         modal: true,
         buttons: {
             Ok: function() {
                 $(this).dialog('close');
             }
         }
    });

    // When a location type is clicked save state in a form
    $('.location_button > a').live('click', function(event){
        event.preventDefault();

        buttonId = $(this).attr('href')
        locationSelected(buttonId);
    });
});

// =============
// = Functions =
// =============
searchBarLoaded = function(){
    // Hide location types below search bar
    $('#search_location_types').hide();

    // Remove default text (if exists) on mouse hover
    $('#searchinput').hover(function(){
        var search_text = $(this).val();
        if (search_text.search('Enter a Zip') >= 0) {
            default_text = search_text;
            $(this).val('');
        }
    },
    function(){
        if ($(this).val().length == 0) {
            $(this).val(default_text);
        }
    });
}

hideAddLocationSections = function(){
    // Hide location types checkboxes
    $('#addlocation > * > ul').not('.errorlist').hide();
    $('#addlocation > * > ul:.errorlist').show();

    // Hide some of the labels
    $("input[name=normal-latitude]").parent().hide();
    $("input[name=normal-longitude]").parent().hide();
    $("label[for=id_normal-location_type_0]").parent().hide();

    // Hide sponsor area of the addlocation form
    $('#staff_only').hide();

    // Bind function to checkbox to show or hide the sponsorship fields
    $('input[name=sponsor-sponsor]').change( function(){
       if ($(this).attr('checked').valueOf()) {
           $('#staff_only').show();
       } else {
           $('#staff_only').hide();
       }
    });
}

locationSelected = function(buttonId){
    // Search locations - form
    var selector = "input[name='location_type'][value='" + buttonId + "']";
    var checked = $('#geocode').find(selector).attr('checked');
    $('#geocode').find(selector).attr('checked', !checked);

    // Add locations - form
    selector = "input[name='normal-location_type'][value='" + buttonId + "']";
    checked = $('#addlocation').find(selector).attr('checked');
    $('#addlocation').find(selector).attr('checked', !checked);

    // Set the image size in 'Choose location type' box to indicate selection
    loc_title = $(".location_button > a[href='" + buttonId + "'] + .location_button_title");
    $(loc_title).toggleClass('location_selected');

    // Show selected location types text above add-location form
    var locations = $('#addlocation input:checkbox:checked').parent().map(function(){
        return $(this).text();
    }).get().join(',');
    $('#selected_types').text(locations);

   // Update the map to show the new locations
  showLocations(getEnabledLocationTypes());
};

var getEnabledLocationTypes = function () {
  // Grab selected location types
  var arr = new Array();
  var types;

  var selector = "input[name='location_type']:checked";
  $("#geocode").find(selector).each(function(){
    var f = $(this).parent().text();
    arr.splice(0, 0, f);
  });
  types = arr.join(',');
  return types;
};

var searchAddress = function(address){
    $.getJSON('/json/crcsapp.geocode', {'address':address}, function(data){
        // If no results then inform user appropriately
        if (data.result.valueOf() == "ZERO_RESULTS".valueOf()) {
            resetMap();
            $('#dialog-message').dialog('open');
        } else {
            // Update map to new location.
            $('#map_canvas').googleMaps({
                latitude: data.result.latitude,
                longitude: data.result.longitude
            });

            // Fetch location markers.
            showLocations(getEnabledLocationTypes());
        }

    });
};

confirmAddress = function(address){
    $.getJSON('/json/crcsapp.geocode', {'address':address}, function(data){
        // If no results then inform user appropriately
        if(data.result.valueOf() == "ZERO_RESULTS".valueOf()) {
            resetMap();
            $('#dialog-message').dialog('open');
        } else {
            addDefaultMarker(data, updateMarkerCoords);
        }
    });
}

addDefaultMarker = function(data, callbackFn){
    // Add a default marker
    $('#map_canvas').googleMaps({
        latitude : data.result.latitude,
        longitude: data.result.longitude,
        markers: {
            latitude : data.result.latitude,
            longitude: data.result.longitude,
            draggable: true,
            callback: callbackFn // event listener for when this marker (overlay) is added
        }
    });
}

// Show locations of specific types within the bounding box of the map
var showLocations = function(locationTypes){
    var swLat = $.googleMaps.gMap.getBounds().getSouthWest().lat();
    var swLng = $.googleMaps.gMap.getBounds().getSouthWest().lng();
    var neLat = $.googleMaps.gMap.getBounds().getNorthEast().lat();
    var neLng = $.googleMaps.gMap.getBounds().getNorthEast().lng();

    $.getJSON('/json/crcsapp.getlocationsshort', {'swLat':swLat, 'swLng':swLng, 'neLat':neLat, 'neLng':neLng, 'types':locationTypes}, function(data){
        // $.extend(data.result, {'depth': $.googleMaps.getDepth()});      // Keep current zoom level
        // First insert 'info' attribute. The info attribute consists of text to display for a particular marker as well as callback function calls for open and close.
        var index = data.result.markers.length;
        while(index--) {
            marker = data.result.markers[index];
            content = '<div id="location_brief"><h3 id="' + marker.id + '">' + marker.title + '</h3>' +
                       marker.address + '</div>'
            data.result.markers[index].info = {
                location_brief : content,
                maxTitle : '<h1>Location Details</h1>',
                maxContent : '<div id="location_details"></div>',
                onOpenFn : openInfoWindow,
                onCloseFn : closeInfoWindow
            };
        }

        $('#map_canvas').googleMaps({
            latitude: $.googleMaps.getLatitude(),
            longitude: $.googleMaps.getLongitude(),
            depth: $.googleMaps.getDepth(),
            markers: data.result.markers
        });

        addInfoWindowListener();
        addZoomAndMoveListeners();
    });
};

openInfoWindow = function(){
    MARKER_ID = $('#location_brief h3').attr('id');

    // Display sponsor in the sponsor box
    displaySponsor(MARKER_ID);

    // Save map center
    MAP_CENTER = $.googleMaps.gMap.getCenter();
}

closeInfoWindow = function(){
    // Restore map center since opening the info window would have panned the map.
    $.googleMaps.gMap.setCenter(MAP_CENTER);
}

addInfoWindowListener = function(){
    // When the info window is maximized add event listener for maximize event
    var listener = GEvent.addListener($.googleMaps.gMap.getInfoWindow(), 'maximizeend', function(){
        $('#location_details').html('<h2 class="location_title">Loading...</h2>');
        $('#location_details').load('/locationdetails/' + MARKER_ID + '/');
    });
}

displaySponsor = function(data){
    $('#mod_location_sponsor').load('/sponsor/' + data.toString() + '/ a');
}

resetMap = function(){
    // Load a default map first so that it is not empty while waiting for permission
    // from user.
    $.getJSON('/json/crcsapp.getmapcenter', function(data){
        $('#map_canvas').googleMaps({
            latitude: data.result.latitude,
            longitude: data.result.longitude
        });
    });

    if(navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(function(position) {
          $('#map_canvas').googleMaps({
              latitude: position.coords.latitude,
              longitude: position.coords.longitude
          });
        });
    }
}

updateAddress = function(data){
    $("input[name='normal-address']").val(data);
}

updateMarkerCoords = function(arg){
    $("input[name=normal-latitude]").val(arg.latitude);
    $("input[name=normal-longitude]").val(arg.longitude);

    // Update the address input field
    latCommaLng = arg.latitude + ',' + arg.longitude;
    $.getJSON('/json/crcsapp.reversegeocode', {'latlng':latCommaLng}, function(data){
         $("input[name='normal-address']").val(data.result);
    });
};

var addZoomAndMoveListeners = function() {
  var map = $.googleMaps.gMap;
  var updateMarkersMoved =  function() {
    var locTypes = getEnabledLocationTypes();

    // Don't update the locations if the map has to resize for the info panel.
    if (locTypes !== "" && map.infoWindowEnabled() !== true) {
      showLocations(locTypes);
    }
  };

  GEvent.addListener(map, "moveend", updateMarkersMoved);
  GEvent.addListener(map, "zoomend", updateMarkersMoved);
};




