/*
 * Code shared between the suggestion editor and view suggestion page to
 * control the map and footprint display.
 */

/*global GEvent,GLatLon,SuggestionMap,MOCfootprints,CTXfootprints,CRISMfootprints,RDRfootprints,HiTfootprints */

// the map instance
var suggestionMap;
var submittable = false;

/**
 * A footprint type has been toggled, update the map.
 */
function toggleFootprints()
{
    [ 'HiT', 'RDR', 'MOC', 'CTX', 'CRISM' ].forEach
    (
        function(key)
        {
            suggestionMap.updateFootprints(key, $('#show' + key).attr('checked'));
        }
    );
}

/**
 * The map has been moved, update the page.
 */
function updateLocation()
{
    var html = 'View is centered at ' + suggestionMap.map.getCenter().toHTML();
    
    var delta = suggestionMap.footprintZoomMin - suggestionMap.map.getZoom();
    
    if (delta > 1)
    {
        html += '. Zoom in by ' + delta + ' steps to display footprints.';
    }
    else if (delta == 1)
    {
        html += '. Zoom in by one step to enable footprints.';
    }
    
    $('#loc').html('<i>' + html + '</i>');   
}

function resizeMap()
{
	var pw = $('#map').parent().width();
	
	if ($('#map').width() < pw)
	{
		$('#map').width(pw);
		$('#map').height(Math.ceil(pw/2.0));
	}
	else
	{
		$('#map').width(480);
		$('#map').height(300);	
		resizeMap();
	}
}

function preparePage()
{
    
    // don't allow form submit until we've got what's needed
    $('#suggestionForm').submit
    (
       function()
       {
          return submittable;
       }
    );
    
    // initialize all the help dialogs
    $('.help').dialog({ autoOpen: false });

    
    // initialize drop-down autocomplete widget
    $('#locate').autocomplete
    (
        '/hiwish/locate/', 
        { 
            // minChars: 2,
            formatItem: function(row) { return row[0].split(',')[0]; },
            formatResult: function(row) { return this.formatItem(row); }
        }
    ); 
    
    $('#locate').blur
    (
        function()
        {
            var coord = $('#locate').val().match(/([\-\+\.\d]+)\s*,\s*([\-\+\.\d]+)/);   
            if (coord != null)
            {
                relocate(new GLatLng(coord[1], coord[2]));
            }
        }
    );
    
    $('#locate').result
    (
        function(event, data, formatted) 
        {
            var coord = null;
            
            if (data.length > 0)
            {
                coord = data[0].split(',');
            }
            else
            {
                return;
            }
            
            if (coord == null)
            {
                return;
            }
            
            relocate(new GLatLng(coord[1], coord[2]));
        }
    );    
    
    if (suggestionMap.map.getZoom() >= suggestionMap.footprintZoomMin)
    {
        for (var key in suggestionMap.footprints)
        {
            $('#show' + key).removeAttr('disabled');
        }        
    }       
    
}

/**
 * Initialize the map.
 * @param edit true if map will be editable
 */
function prepareMap(edit)
{
	if (!GBrowserIsCompatible())
	{
		alert("Your browser does not support Google Maps");
		return;
	}
	
    var center = new GLatLng($('#lat').val(), $('#lon').val());
    
    resizeMap();
	suggestionMap = new SuggestionMap('map', center, Number($('#zoom').val()), edit);

	$(window).resize
	(
		function()
		{
			resizeMap();
			suggestionMap.map.checkResize();
		}
    );
     
    // move includes zoom events
    GEvent.addListener
    ( 
		suggestionMap.map, 
		'moveend', 
		function()
		{
	        updateLocation();			
			suggestionMap.mapMoved();
		}
    );   

    GEvent.addListener
    (
        suggestionMap.map,
        'move',
        function()
        {
           updateLocation();
        }
    );

    GEvent.addListener
    (
        suggestionMap.map,
        'nudge',
        function()
        {
           updateLocation();
        }
    );
    
    GEvent.addListener
    (
        suggestionMap.map,
        'click',
        function(marker)
        {
           if (marker && marker.parent)
           {
               marker.parent.markerClicked(marker);
           }
        }
    );
 	 
    GEvent.addListener
    (
        suggestionMap.map,
        'zoomend',
        function()
        {
            // enable or disable the footprint buttons
            if (suggestionMap.map.getZoom() < suggestionMap.footprintZoomMin) 
            {    
                $('div#control input[type="checkbox"]').each(function(i, elem) { $(elem).attr('disabled', 'disabled'); });
            }
            else
            {
            	$('div#control input[type="checkbox"]').each(function(i, elem) { $(elem).removeAttr('disabled'); });
            }
        }
    );
      
    toggleFootprints();
    
    $('div#control input[type="checkbox"]').each(function(i, elem) { $(elem).bind('change', toggleFootprints); });
}

/**
 * Clone the suggestion
 * 
 * @param id Suggestion ID number
 */
function clone(id)
{
    var url = '../clone/' + id;

    window.location.href = url;
}

/**
 * Move to a specific latitude and longitude
 * @param gll GLatLng
 */
function relocate(gll)
{
    GEvent.trigger(suggestionMap.map, 'click', null, gll);
}

/**
 * Create a new suggestion in the same location
 * 
 * @param lat Latitude
 * @param lng Longitude
 */
function create(lat, lng)
{
    var url = '../new';
    url += '?lat=' + lat.toFixed(3);
    url += '&lon=' + lng.toFixed(3);
    url += '&zoom=' + Math.abs(lat) < 65 ? 7 : 5;

    window.location.href = url;
}

/**
 * Search for suggestions located within the map window area
 */
function search()
{
    var box = suggestionMap.getBoundingBox(1.0);
    var cen = box.getCenter();
    var spn = box.toSpan();
    
    var url = '../search';
    url += '?cenLat=' + cen.lat().toFixed(1);
    url += '&cenLon=' + cen.lng().toFixed(1);
    url += '&latRange=' + Number(spn.lat()/2).toFixed(1);
    url += '&lonRange=' + Number(spn.lng()/2).toFixed(1);

    window.location.href = url;
}

/*
 * Configures a click listener for the map
 * so that a target is place or moved 
 * when the user clicks, and the map moves 
 * when the user drags.
 */
function setNormalListeners()
{
    //clear away any old listeners
    GEvent.clearListeners(suggestionMap.map, 'click');
    GEvent.clearListeners(suggestionMap.map, 'nudge');
    
    //handle clicks on the map, target and other markers
    // if the user clicks on the map, go there and place a target there
    // if the user clicks on the target, show the target stretch slider and message
    // if the user clicks on a marker that is not the target, show information about it
    GEvent.addListener
    (
        suggestionMap.map, 
        'click',    
        //either marker or point will be defined, but never both
        function (marker, point)
        { 
            if (marker)
            {
                if (marker.type == undefined)
                {
                    clickedTarget(marker);
                }
                else 
                {
                    marker.parent.markerClicked(marker); //in footprints.js
                }
            } 
            else
            {
                clickedMap(point); 
            }
        }
    );

    GEvent.addListener
    (
        suggestionMap.map,
        'dragend',
        function (marker, point)
        {
        	if (marker)
        	{
        		clickedMap(point);
        	}
        }
    );
    
    //if the user drags, adjust the labels that show where the map is
    GEvent.addListener
    (
        suggestionMap.map,
        'nudge',
        function (gll)
        {
            $('#roi').val(suggestionMap.getTargetAsString());
            $('#lat').val(gll.lat());
            $('#lon').val(gll.lng());                
            $('#goto').html("Target located at " + gll.toHTML());
            updateLocation();
            checkSubmit();                
        }
    );
}

/*
 * Configures the click listener for the map
 * while the target stretcher is shown
 */
function setStretchListeners()
{
    //clear the event listener list so
    // the other event handlers don't fire
    // when the user clicks
    GEvent.clearListeners(suggestionMap.map, 'click');
    GEvent.clearListeners(suggestionMap.map, 'nudge');

    removeStretchOnNextClick = false;
    GEvent.addListener
    ( 
        suggestionMap.map, 
        'click',
        clickedMapDuringStretch
    );
    
    //if the user starts to drag the map, then hide the stretch
    // dialog and control
    GEvent.addListener
    (
        suggestionMap.map, 
        'dragstart',
        function (point)
        {
            var removeAll = true;
            clickedMapDuringStretch(removeAll);
        }
    );
    //if the user starts to drag the marker, then hide the stretch dialog
    // and control
    GEvent.addListener 
    (
        suggestionMap.marker, 
        'dragstart',
        function (point)
        {
            var removeAll = true;
            clickedMapDuringStretch(removeAll);
        }
    );
    
    GEvent.addListener
    (
        suggestionMap.map,
        'nudge',
        function (gll)
        {
            $('#roi').val(suggestionMap.getTargetAsString());              
        }
    );    
}

/*
 * when the user clicks the target, show the message about how to use the target stretcher, 
 * show the target stretcher, and set up event listeners.
 */
function clickedTarget(marker)
{
    var point = marker.getLatLng();
    var markerOffset = suggestionMap.map.fromLatLngToDivPixel (point);
    
    $("#stretch-dialog").appendTo(suggestionMap.map.getPane(G_MAP_FLOAT_PANE));
    suggestionMap.map.panTo(point);
    $("#stretch-dialog").fadeIn().css( {top:markerOffset.y-100, left:markerOffset.x+25} );
    suggestionMap.map.addControl ( stretchControl );
    setStretchListeners();
    stretchControl.setStretchLines (suggestionMap.numberLines);
}

//the event handler for a click on the map
function clickedMap(point)
{	
	var zoom = suggestionMap.map.getZoom();	    
	suggestionMap.setCenter(point, zoom < 7 ? 7 : zoom);
	if (suggestionMap.editable == false)
	{
		return;
	}
	new Footprints(HiT).checkOverlap
    (
       point, 
       confirmTarget
    );
}

function confirmTarget(point, overlap)
{
	var confirmed = false;
	
    if (overlap)
    {
    	confirmed = confirm("A suggestion has already been made here. Proceed anyway?");	
    }   
    else if (suggestionMap.target.getVertexCount() > 3)
    {
    	confirmed = confirm('Move your target to here?');
    }
    else
    {
    	confirmed = confirm('Place a new target here?');
    }
	
    if (! confirmed) return;
    
    //place the target
    suggestionMap.placeTarget(point);
    $('#roi').val(suggestionMap.getTargetAsString());
    point = suggestionMap.marker.getLatLng();
    $('#lat').val(point.lat());
    $('#lon').val(point.lng());
    $('#goto').html("Target located at " + point.toHTML());
    
    updateLocation();
    checkSubmit();    
}

/*
 * If the user clicks for the first time, 
 * then hide the dialog box.
 * 
 * If the user clicks the second time, 
 * then hide the slideControl and go back 
 * to normal browsing (clicking places the marker)
 * 
 * If removeAll is true, then both the dialog box
 * and the stretchControl are removed and the user
 * returns to normal browsing, no matter if 
 * the user has clicked before
 */
function clickedMapDuringStretch(removeAll)
{
    if (removeStretchOnNextClick || removeAll)
    {
        setNormalListeners();
        $('#stretch-dialog').fadeOut();
        suggestionMap.map.removeControl (stretchControl); 
    }
    else 
    {
        removeStretchOnNextClick = true;
        $("#stretch-dialog").fadeOut();
    }
}

