﻿var Sprites=new Array();
var SpriteMarkersOnMap = new Array();

var MapModeToReturnToAfterInsertingSprite=PathEditMode;

/*
 * Enters sprite insert mode, which allows the user to pick from a list of sprites to be placed
 * on the map. After the user selects a sprite type they will enter into another mode that lets
 * them select a position on the map.
 */
function EnterSpriteInsertMode()
{
    // Remember the map mode to which we should return
    MapModeToReturnToAfterInsertingSprite = MapMode;
    
    // Switch to sprite insert mode
    MapMode = SpriteInsertMode;
    
    // Reload the map and context help
    RefreshMap(LastCursorPosition);
}

/*
 * Exits out of sprite insert or select position mode. This call will return to the mode that
 * the user was in before entering sprite insert mode.
 */
function LeaveSpriteInsertMode(LatLng)
{
    MapMode = MapModeToReturnToAfterInsertingSprite;
    RefreshMap(LatLng);
}

var SpriteTypeBeingInserted;

/*
 * After a user selects a sprite type they should enter into select position mode through this
 * function.
 */
function EnterSpriteInsertSelectPositionMode(SpriteTypeToBePlacedOnTheMap)
{
    // Remember which sprite type the user selected
    SpriteTypeBeingInserted=SpriteTypeToBePlacedOnTheMap;
    
    // Switches
    MapMode = SpriteInsertSelectPositionMode;
    RefreshMap(LastCursorPosition);
}

/*
 * The Sprite object represents something on the map with a custom marker.
 *      Properties:
 *          SpriteType      - See AppCode/SpriteTypes.cs
 *          Caption         - A nice readable version of the sprite type. Like "Water Fountain"
 *          Location        - A GLatLng specifying the location on the map for this sprite
 *          ImageFilename   - The filename of the icon for this sprite (not the button icon)
 *          Note            - Note to be displayed for this sprite
 */
function Sprite(SpriteType,LatLng,Note)
{
    this.SpriteType = SpriteType;
    this.Note = Note;
    this.Location = LatLng;
}
Sprite.prototype =
{
    /*
     * Gets the caption for this sprite type
     */
    getCaption: function()
    {
        switch(getSpriteType())
        {
            case "WaterFountain":
                return "Water Fountain";
            case "Parking":
                return "Parking Area";
            default:
                return getSpriteType();
        }
    },
    
    /*
     * Gets or sets the SpriteType
     */
    getSpriteType: function()
    {
        return this.SpriteType;
    },
    setSpriteType: function(value)
    {
        this.SpriteType = value;
    },
    
    /*
     * Gets or sets the Note property
     */
    getNote: function()
    {
        if(this.Note==null)
            return "";
        return this.Note;
    },
    
    setNote: function(value)
    {
        this.Note = value;
    },
    
    /*
     * Gets or sets the Location property, a GLatLng indicating the position of the sprite on the map
     */
    getLocation: function()
    {
        return this.Location;
    },
    setLocation: function(value)
    {
        this.Location = value;
    },
    
    /*
     * Gets the filename of the icon that will be displayed for this sprite
     */
    getImageFilename: function()
    {
        return this.getSpriteType() + ".GIF";
    }
}

/*
 * Refreshes sprites on the map
 */
function RefreshMapSprites(LatLng)
{
    if(!ShowMapMarkers)
        return;

    SpriteMarkersOnMap = new Array();
 
    for(var i=0;i<Sprites.length;i++)
    {
        // Figure out the URL to the icon to use for this spirte
        var Filename = Sprites[i].getImageFilename();
        var MarkerIconImageUrl = 'css/app/Sprites/' +  Filename;
 
        // Create a new GIcon
        var NewIcon = new GIcon();
        NewIcon.image = MarkerIconImageUrl;
        NewIcon.iconSize = new GSize(33, 33);
        NewIcon.shadowSize = new GSize(0, 0);
        NewIcon.iconAnchor = new GPoint(16.5, 30);
        NewIcon.infoWindowAnchor = new GPoint(9, 2);
        NewIcon.infoShadowAnchor = new GPoint(18, 25);

        // Create a new GMarker for the sprite
        var Location = Sprites[i].getLocation();
        var NewMarker = new GMarker(Location,
            {
                title: Sprites[i].Caption,
                clickable: true,
                draggable: true,
                bouncy: true,
                icon: NewIcon
            });
        NewMarker.enableDragging();
        
                // Set up an event handler for the marker's drag event
        GEvent.addListener(NewMarker, "drag", SpriteMarker_OnDrag);
        GEvent.addListener(NewMarker, "dragstart", SpriteMarker_OnDragStart);
        GEvent.addListener(NewMarker, "dragend", SpriteMarker_OnDragEnd);
        GEvent.addListener(NewMarker, "click", SpriteMarker_OnClick);
        
        map.addOverlay(NewMarker);
    }
}

var IndexOfSpriteMarkerBeingDragged=0;

/*
 * Event handler for a sprite drag handler
 *      - Each sprite will call this drag handler. Reference this to get the Marker map object
 */
function SpriteMarker_OnDrag()
{    
    // We don't want to process this event if there is an info window being displayed
    if(InfoWindowBeingDisplayed)
        return;

    Sprites[IndexOfSpriteMarkerBeingDragged].setLocation(this.getLatLng());
}

var IndexOfSpriteBeingClicked; // This will be used by the txtNote.onchanged event handler

/*
 * Handles the Click event fired from sprite markers
 */
function SpriteMarker_OnClick(LatLng)
{
    // We don't want to process this event if there is an info window being displayed
    if(InfoWindowBeingDisplayed)
        return;

    // Figure out which sprite marker was clicked
    IndexOfSpriteBeingClicked = -1;
    for(var i=0;i<Sprites.length;i++)
        if(Sprites[i].getLocation().x==this.getLatLng().x
            && Sprites[i].getLocation().x==this.getLatLng().x)
            IndexOfSpriteBeingClicked=i;
    if(IndexOfSpriteBeingClicked<0)
        throw "Can't determine which sprite marker is being clicked. Please report this error.";

    // Pop up an info window for the sprite that allows the user to remove it or add a note
    var Html='<div style="padding-top: 5px;">You can move this marker around by dragging<br />it to a different location on the map.</div>';
    Html += '<br />';
    Html += '<b>Notes:</b><br />';
    Html += '<textarea id="txtNote" cols="30" rows="3" style="border: solid black 1px;" onchange="SaveTextFromSpriteInfoPopup();">'
    Html += Sprites[IndexOfSpriteBeingClicked].getNote();
    Html += '</textarea><br />';
    Html += '<a href="" onclick="RemoveSpriteAtIndex(' + IndexOfSpriteBeingClicked + '); return false;"';
    Html += '">Remove this marker</a>';
    Html += '<br />';
    Html += '<a href="" onclick="map.closeInfoWindow(); return false;">Close this popup</a>';
    InfoWindowBeingDisplayed=true;
    map.openInfoWindowHtml(this.getLatLng(),Html,{onCloseFn: SpriteInfoWindow_OnClose, noCloseOnClick: true});
    setTimeout("$get('txtNote').focus();",500);
}

/*
 *
 */
function SpriteInfoWindow_OnClose()
{
    map.closeInfoWindow();
    setTimeout("InfoWindowBeingDisplayed=false;",200);
}

/*
 * Handles the onchanged event for the text area that's in the info
 */
function SaveTextFromSpriteInfoPopup()
{
    var NoteText = $get('txtNote').value;
    Sprites[IndexOfSpriteBeingClicked].setNote(NoteText);
}

/*
 * Handles the DragStart event fired from map markers
 */
function SpriteMarker_OnDragStart()
{
    // We don't want to process this event if there is an info window being displayed
    if(InfoWindowBeingDisplayed)
        return;

    // We're dragging!
    DragIsInProgress=true;

    // Find which marker is being dragged
    var LatLng = this.getLatLng();
    for(var i=0;i<Sprites.length;i++)
    {
        var ThisSpriteLocation = Sprites[i].getLocation();
        if(ThisSpriteLocation.x==LatLng.x
            && ThisSpriteLocation.y==LatLng.y)
        {
            // We've found the index of the sprite being dragged
            IndexOfSpriteMarkerBeingDragged=i;
            return;
        }
    }
    return;
}

/*
 * Handles the DragEnd event fired from sprite markers
 */
function SpriteMarker_OnDragEnd()
{
    // We don't want to process this event if there is an info window being displayed
    if(InfoWindowBeingDisplayed)
    {
        RefreshMap(this.getLatLng());
        return;
    }

    Sprites[IndexOfSpriteMarkerBeingDragged].setLocation(this.getLatLng());    

    // Drag's over
    DragIsInProgress=false;

    RefreshMap(this.getLatLng());
}

/*
 * Removes the sprite at the specified index
 */
function RemoveSpriteAtIndex(index)
{
    // Copy all sprites except the one the user wants removed
    var NewSprites = new Array();
    for(var i=0;i<Sprites.length;i++)
        if(index!=i)
            NewSprites.push(Sprites[i]);
        
    // The new become the old
    Sprites=NewSprites;
    
    // Refresh the map
    RefreshMap(LastCursorPosition);
}