﻿/* ================================================================== */
/* SensorMapPanels                                                    */
/*                                                                    */
/* This file contains all functions and handlers for panels in the    */
/* SensorMap UI.                                                      */
/*                                                                    */
/* There are four panels used in SensorMap (v2) UI:                   */
/* (1) Manage Views Panel                                             */
/* (2) Context Menu (which appears on right click)                    */
/* (3) SensorManagement Panel                                         */
/* (4) Permalink Panel                                                */
/*                                                                    */
/* The non-dynamic markup for these panels can be found in            */
/* Default.aspx.cs.  This file contains dynamic markup for these      */
/* panels along with handlers for events that occur when the user     */
/* interacts with the panels in the UI.                               */
/*                                                                    */
/* ================================================================== */

/* ============================================================ */
/* SensorMap Manage Views Panel                                 */
/* ============================================================ */

var taskArea = null;        // task area (left pane containing view management)
var savedViewListID = "savedViewListUL";

var mvMargin = 5;
var mvWidth = 200;

function MV_InitPanel() {
    var temp = new Array();
    temp.push('<table border="0" cellpadding="2px" cellspacing="0">');
    var sensorTypeNameWithUnit = '';
    for (var i in sensorTypeListByUri) {
        if (sensorTypeListByUri[i].inView) {
            temp.push('<tr><td align="left"><input id="');
            temp.push('showType' + sensorTypeListByUri[i].id);
            temp.push('" type="checkbox" ');
            if (smModel.filterTypes[sensorTypeListByUri[i].uri] != 0)
                temp.push('checked="checked" ');
            temp.push('onclick="javascript:MV_UpdateFilterTypes()" /></td>');
            temp.push('<td align="center"><img alt="');
            temp.push(sensorTypeListByUri[i].name);
            temp.push('" src="');
            temp.push(sensorTypeListByUri[i].icon);
            temp.push('" /></td><td>');
            if (sensorTypeListByUri[i].unit != '')
		        sensorTypeNameWithUnit = sensorTypeListByUri[i].name + ' (' + sensorTypeListByUri[i].unit + ')'
		    else
		        sensorTypeNameWithUnit = sensorTypeListByUri[i].name; 
            temp.push(sensorTypeNameWithUnit);
            temp.push('</td></tr>');
        }
    }
    temp.push('</table>');
    $get('filterByTypeTable').innerHTML = temp.join('');
}

function MV_PlacePanel()
{
    var mapdims = GetMapDimensions();
    
    // mvContainer is the "Manage Views" div (visual manifestation of task area)
    var mvContainer = $get('SM_ManageViewsPanel');
    
    // set where mvContainer should be placed
    var mvContainer_Left = mapdims.width - mvWidth - mvMargin;
    var mvContainer_Top = bannerheight + menubarheight + mvMargin;
    mvContainer.style.top = mvContainer_Top + "px";
    mvContainer.style.left = mvContainer_Left + "px";
    mvContainer.style.width = mvWidth + "px";
    
    MV_ShowPanel();
}

function MV_HidePanel()
{
    var mvContainer = $get('SM_ManageViewsPanel');
    mvContainer.style.display = "none"; 
}

function MV_ShowPanel()
{
    MV_SetFilterTypes();
    MV_SetSearchFilterTerms();
    if (mySavedViews == null)
    {
        MV_InitializeSavedViews();
    }
    MV_PopulateSavedViewsListPanel();

    var mvContainer = $get('SM_ManageViewsPanel');
    mvContainer.style.display = "block";
}

/*
 * MV_SetFilterTypes
 *
 * Sets sensor types check box values to those values held in the model's types.
 */
function MV_SetFilterTypes()
{
    var sensorTypeCheckBox = null;
    
    for (var ii in sensorTypeListByUri)
    {
        sensorTypeCheckBox = 
            $get("showType" + sensorTypeListByUri[ii].id);
        if (sensorTypeCheckBox)
            sensorTypeCheckBox.checked = smModel.filterTypes[ii];
    }
}

/*
 * MV_UpdateFilterTypes 
 *
 * Handler that handles when a sensor type filter has been checked/unchecked.
 */
function MV_UpdateFilterTypes(event)
{
    for (var ii in sensorTypeListByUri)
    {
        sensorTypeCheckBox = 
            $get("showType" + sensorTypeListByUri[ii].id);
        if (sensorTypeCheckBox)
            smModel.filterTypes[ii] = sensorTypeCheckBox.checked;
        else 
            smModel.filterTypes[ii] = -1;
    }

    UpdateSensorMap(SM_Event.FILTER_BY_TYPE);
}

/*
 * MV_SetSearchFilterTerms
 *
 * Sets sensorSearch text box value to the search terms in the model.
 */
function MV_SetSearchFilterTerms()
{
    var sensorSearch_textBox = $get("sensorSearchText");
    
    if ((sensorSearch_textBox != null) && (sensorSearch_textBox.value != null))
    {
        sensorSearch_textBox.value = smModel.filterTerms;
    }
}

/*
 * MV_GetSearchFilterTerms 
 *
 * Returns the search terms that have been entered in the sensorSearch text 
 * box.
 */
function MV_GetSearchFilterTerms()
{
    var sensorSearch_textBox = $get("sensorSearchText");

    if ((sensorSearch_textBox != null) && (sensorSearch_textBox.value != null))
    {
        return sensorSearch_textBox.value;
    }
    else
    {
        return "";
    }
}

/*
 * FilterBySearch 
 *
 * Handles event raised when user types something in search box.
 */
function MV_FilterBySearch(event)
{    
    UpdateSensorMap(SM_Event.FILTER_BY_SEARCH);
}


/* ------------------------------------------------------------ */
/* SavedView Handling Functions                                 */
/*                                                              */
/* A saved view is a SensorMapModel cookie.                     */
/* ------------------------------------------------------------ */

/*
 * SavedView globals.
 */
var savedViewListID = "savedViewListUL";
var currentSavedViewCookieStr = "microsoft_sensormap_view_current";
var mySavedViews = null;
var smCookiePrefix = "SensorMap$";

/*
 * MV_InitializeSavedViews 
 *
 * Initializes saved views by reading in all saved cookies user has stored on 
 * the client (NOTE: this assumes all SensorMap cookies represent saved views).
 */
function MV_InitializeSavedViews()
{
    mySavedViews = new Object();
    
    var cookies = ReadAllCookies();

	for (var ii = 0; ii < cookies.length; ii++) 
	{
		var cookieName = GetCookieName(cookies[ii]);
		
		if (cookieName.indexOf(smCookiePrefix) != -1)
		{
		    var svName = cookieName.substring(smCookiePrefix.length + 1);
		    mySavedViews[svName] = GetCookieValue(cookies[ii]);
		}
	}
}

/*
 * MV_PopulateSavedViewsListPanel 
 *
 * Generates html for panel under "Manage Views" title (either with be panel
 * with empty saved view list message or list of saved views).
 */
function MV_PopulateSavedViewsListPanel()
{
    // if repopulating list, delete all old dhtml nodes before populate saved 
    // views list    
    if ($get(savedViewListID) != null)
    {
        $get(savedViewListID).removeNode(true);
    }
    else if ($get("emptyMessagePanel") != null)
    {
        $get("emptyMessagePanel").removeNode(true);
    }

    // if no saved views, put default text
    if (NumSavedViews() == 0)
    {
        MV_PopulateSavedViewsListEmpty();
    }
    // else add list of saved views to panel
    else
    {
        MV_PopulateSavedViewsList();
    }
}

/*
 * MV_PopulateSavedViewsListEmpty 
 *
 * Generates html for panel under "Manage Views" title when no saved views.
 */
function MV_PopulateSavedViewsListEmpty()
{
    var savedViewsDiv = $get("savedViewsSection");
    
    var emptyMessagePanel = document.createElement("div");
    emptyMessagePanel.setAttribute("id", "emptyMessagePanel");
    emptyMessagePanel.className = "emptyMessage";

    var p1 = document.createElement('p');
    p1.appendChild(document.createTextNode(
        'You have no saved SensorMap views.'));
        
    var p2 = document.createElement('p');
    p2.appendChild(document.createTextNode(
        'A SensorMap saved view saves your SensorMap settings ' + 
        '(e.g., map location and sensor types being viewed).'));
        
    var p3 = document.createElement('p');
    p3.appendChild(document.createTextNode(
        'To save a SensorMap view, enter a name for the view above and ' +
        'click \'Save View\'.'));
    
    emptyMessagePanel.appendChild(p1);
    emptyMessagePanel.appendChild(p2);
    emptyMessagePanel.appendChild(p3);
    
    savedViewsDiv.appendChild(emptyMessagePanel);  
}

/*
 * MV_PopulateSavedViewsList 
 *
 * Generates html for panel under "Manage Views" title when the user has 
 * saved views.
 */
function MV_PopulateSavedViewsList()
{
    var savedViewsDiv = $get("savedViewsSection");
    
    var savedViewList = document.createElement("ul");
    savedViewList.setAttribute("id", savedViewListID);
    
    if (mySavedViews != null)
    {
        var savedViewItem = null;
        var savedViewListItem = null;
        var savedViewListItemText = null;
        var savedViewItemToolbar = null;
        var savedViewItemToolbarRemoveItem = null;
    
        for (var savedViewName in mySavedViews)
        {   
            // create h4 with saved view name
            savedViewListItemText = document.createElement("h4");
            savedViewListItemText.onclick = MV_SavedViewSelected;
            savedViewListItemText.arg = savedViewName; 
            savedViewListItemText.appendChild(document.createTextNode(savedViewName));
            
            // create savedViewItem toolbar that allows user to delete saved view
            savedViewItemToolbar = document.createElement("div");
            savedViewItemToolbar.className = "savedViewItemToolbar";
            savedViewItemToolbar.id = "savedViewItemToolbar$" + savedViewName;
            savedViewItemToolbarRemoveItem = document.createElement("div");
            savedViewItemToolbarRemoveItem.className = "toolRemoveItem";
            savedViewItemToolbarRemoveItem.id = "toolRemoveItem$" + savedViewName;
            savedViewItemToolbarRemoveItem.onclick = MV_RemoveSavedView;
            savedViewItemToolbar.appendChild(savedViewItemToolbarRemoveItem);
            
            // create list item that contains h4 and savedViewItem toolbar
            savedViewListItem = document.createElement("li");
            savedViewListItem.id = "savedViewItem$" + savedViewName; 
            savedViewListItem.onmouseover = MouseOverSavedViewListItem;
            savedViewListItem.onmouseout = MouseOutSavedViewListItem
            savedViewListItem.appendChild(savedViewListItemText);
            savedViewListItem.appendChild(savedViewItemToolbar);
            
            // add list item to saved view list
            savedViewList.appendChild(savedViewListItem);
        }
    }
    
    savedViewsDiv.appendChild(savedViewList);
}

function MouseOverSavedViewListItem(event)
{
    var savedViewId = this.id.substr(this.id.indexOf("$") + 1);
    var savedViewItemToolbar = $get("savedViewItemToolbar$" + savedViewId);
    savedViewItemToolbar.style.visibility = "visible";
}

function MouseOutSavedViewListItem(event)
{
    var savedViewId = this.id.substr(this.id.indexOf("$") + 1);
    var savedViewItemToolbar = $get("savedViewItemToolbar$" + savedViewId);
    savedViewItemToolbar.style.visibility = "hidden";
}

/*
 * MV_SaveView 
 *
 * Handles event raised when user clicks "Save View" button.
 */
function MV_SaveView()
{
    var savedViewName = $get("newSavedViewName").value;
    $get("newSavedViewName").value = "";
    
    // make sure name entered is valid
    if ((savedViewName == null) || (savedViewName == ""))
    {
        alert("Must enter a name for the SensorMap view you want to save.");
        return;
    }

    if (mySavedViews[savedViewName] != null)
    {
        alert("You already have a saved view with this name.  Please choose a unique name for the saved view.");
        return;
    }

    // save the view in state and serialize
    mySavedViews[savedViewName] = smModel.toString();
    WriteCookie(smCookiePrefix + savedViewName, mySavedViews[savedViewName]);
    MV_PopulateSavedViewsListPanel();
}

/*
 * MV_RemoveSavedView 
 *
 * Handles event raised when user clicks on 'x' of one of their saved views.
 */
function MV_RemoveSavedView(event)
{
    var savedViewName = this.id.substr(this.id.indexOf("$") + 1);
    
    var confirmResponse = confirm("Are you sure you want to remove the saved " +
        "view '" + savedViewName + "'?");
        
    if (confirmResponse)
    {
        DeleteCookie(smCookiePrefix + savedViewName, mySavedViews[savedViewName]);
        delete mySavedViews[savedViewName];
        MV_PopulateSavedViewsListPanel();
    }
}

/*
 * MV_SavedViewSelected 
 *
 * Handles event raised when user clicks on one of their saved views.
 */
function MV_SavedViewSelected(event)
{
    var savedViewName = this.arg;

    // set model to be that serialized in the savedview string
    smModel.fromString(mySavedViews[savedViewName]);
    
    // update map with new model info
    UpdateSensorMap(SM_Event.SAVED_VIEW);
}

/*
 * NumSavedViews 
 *
 * Returns number of saved views user has.
 */
function NumSavedViews()
{
    var ii = 0;
    
    for (var sv in mySavedViews)
    {
        ii++;
    }
    
    return ii;
}


/* ============================================================ */
/* SensorMap_ContextMenu Panel                                  */
/* ============================================================ */
var ContextDef = {
    MAP          : 0,
    SENSOR       : 1
};

/*
 * SensorMap_ContextMenu 
 *
 * Constructor for SensorMap context menu object.  Creates a FloatPanel for the 
 * menu and hides it.
 */
function SensorMap_ContextMenu()
{
    // private variables
    this.contextMenu = new FloatPanel("SM_contextMenu", "SM_contextMenu");
    this.contextMenu_body = null;
    this.hide();
}
    
/*
 * SensorMap_ContextMenu.prototype.show  
 *
 * Adds appropriate options to the menu and sets the context menu container
 * to be visible.
 */
SensorMap_ContextMenu.prototype.show = function(context, parameters)
{    
    // create body of context menu
    this.createBody();

    // if clicked on map, generate appropriate map options
    if (context == ContextDef.MAP)
    {
        this.showMapOptions(parameters.mapXPixel, parameters.mapYPixel);
    }
    
    this.contextMenu.setPosition(parameters.mapXPixel + (contextPinSize / 2), 
        parameters.mapYPixel - contextPinSize);
        
    this.contextMenu.show();
}

/*
 * SensorMap_ContextMenu.prototype.hide
 *
 * Removes menu body and sets the context menu container to be hidden.
 */
SensorMap_ContextMenu.prototype.hide = function()
{
    var contextMenuBody = $get("contextMenu_body");
    
    if (contextMenuBody != null)
    {
        contextMenuBody.removeNode(true);
    }
    
    this.contextMenu.hide();
}

SensorMap_ContextMenu.prototype.getPosition = function()
{
    return this.contextMenu.getPosition();
}

/*
 * SensorMap_ContextMenu.prototype.createBody
 *
 * Creates the body for the context menu by appending an empty div to the 
 * context menu float panel.
 */
SensorMap_ContextMenu.prototype.createBody = function()
{
    // remove any previous context menu body (as menu items might have changed
    if ($get("contextMenu_body") != null)
    {
        $get("contextMenu_body").removeNode(true);
    }
 
    // generate html of div that is context menu body container
    this.contextMenu_body = document.createElement("div");
    this.contextMenu.getElement().appendChild(this.contextMenu_body);
    this.contextMenu_body.setAttribute("id", "contextMenu_body");
}

/*
 * SensorMap_ContextMenu.prototype.showMapOptions
 *
 * If the user right clicks on the map, context menu should contain:
 * 1. Map information options (i.e. coordinates that correspond to where the 
 *    user clicked),
 * 2. Filter point options (i.e. Add, Delete, and Move filter points), and
 * 3. If the user is a publisher, publisher actions.
 */
SensorMap_ContextMenu.prototype.showMapOptions = function(pixelX, pixelY)
{
    // create table body that will contain menu options
    var contextMenu_table = document.createElement("table");
    contextMenu_table.cellPadding = 0;
    contextMenu_table.cellSpacing = 0;
    this.contextMenu_body.appendChild(contextMenu_table);
    var contextMenu_tbody = document.createElement("tbody");
    contextMenu_table.appendChild(contextMenu_tbody);
    
    // Map Information 
    coordRow = document.createElement("tr");
    contextMenu_tbody.appendChild(coordRow);
    coordCell = document.createElement("td");
    coordRow.appendChild(coordCell);
    
    var userClickLocation = smMap.PixelToLatLong(new VEPixel(pixelX, pixelY));
    coordsText = 
        "Coordinates: <br>&nbsp;&nbsp;<span id='userClickLocLat'>" + userClickLocation.Latitude + "</span>&deg; <br>" 
        +"<span id='userClickLocLon'>"+ userClickLocation.Longitude + "</span>&deg;";    
    var coordPanel = document.createElement("div");
    coordPanel.className = "text";
    coordPanel.innerHTML = coordsText;
    
    coordCell.appendChild(coordPanel);
    this.addHR(contextMenu_tbody);
    
    // Filter Point Actions
    this.addFilterPointActions(contextMenu_tbody);
    
    // Sensor Publisher Actions
    /*
    if (IsUserPublisher())
    {
        this.addHR(contextMenu_tbody);
        this.addMapActions(contextMenu_tbody);
    }
    */
}

/*
 * SensorMap_ContextMenu.prototype.addFilterPointActions
 *
 * Generates html for context menu's filter point options.
 */
SensorMap_ContextMenu.prototype.addFilterPointActions = function(contextMenu_tbody)
{
    contextMenu_tbody.appendChild(
        this.createContextMenuItem("Add Filter Point", "addFilterPoint"));
    contextMenu_tbody.appendChild(
        this.createContextMenuItem("Delete All Filter Points", "deleteAllFilterPoints"));
}

/*
 * SensorMap_ContextMenu.prototype.addMapActions
 *
 * Generates html for context menu's sensor publishing options.
 */
SensorMap_ContextMenu.prototype.addMapActions = function(contextMenu_tbody)
{
    contextMenu_tbody.appendChild(
        this.createContextMenuItem("Add Sensor", "addSensor"));
}

/*
 * SensorMap_ContextMenu.prototype.createContextMenuItem
 *
 * Creates a single context menu item, given the item label and the action that 
 * should occur if the item is selected.
 */
SensorMap_ContextMenu.prototype.createContextMenuItem = function(itemLabel, itemAction)
{
    // make new table row
    menuItemRow = document.createElement("tr");
    
    // make new table cell
    menuItemCell = document.createElement("td");
    menuItemRow.appendChild(menuItemCell);
    
    // make new link
    menuItemLink = document.createElement("a");
    menuItemCell.appendChild(menuItemLink);
    menuItemLink.href = 
        "javascript:sm_contextMenu.contextMenuActionHandler('" + itemAction + "')";
    menuItemLink.appendChild(document.createTextNode(itemLabel));
    
    return menuItemRow;
}

/*
 * SensorMap_ContextMenu.prototype.addHR
 *
 * Generates a horizontal row or divider for the context menu's table body.  
 * This is used to group different groups of options.
 */
SensorMap_ContextMenu.prototype.addHR = function(contextMenu_tbody)
{
    hrRow = document.createElement("tr");
    contextMenu_tbody.appendChild(hrRow);
    hrCell = document.createElement("td");
    hrRow.appendChild(hrCell);
    hr = document.createElement("hr");
    hrCell.appendChild(hr);
}

/*
 * SensorMap_ContextMenu.prototype.contextMenuActionHandler
 *
 * Handles the selection of a context menu option.
 */
SensorMap_ContextMenu.prototype.contextMenuActionHandler = function(action)
{
    var args = new Object();
    
    if (action == "addFilterPoint")
    {
        UpdateSensorMap(SM_Event.FILTER_PIN_ADDED);
    }
    else if (action == "deleteAllFilterPoints")
    {
        UpdateSensorMap(SM_Event.POLYGON_DELETED);
    }
    else if (action == "addSensor")
    {
        var parameters = new Object;
        parameters.latitude = contextPin.LatLong.Latitude;
        parameters.longitude = contextPin.LatLong.Longitude;
        ShowPanelSensorManagement(parameters, ManagementOperation.NEW);
    }
        
    this.hide();
}

/* ============================================================ */
/* SensorMap Sensor Management Panel Variables and Handlers     */
/* ============================================================ */

var ManagementOperation = {
    NEW     : 0,
    DISPLAY : 1,
    UPDATE  : 2,
    DELETE  : 3,
    MANAGE  : 4
};

function GetSensorManagementPanel()
{
    return $get("SM_SensorManagementPanel");
}

/*
 * ShowPanelSensorManagement
 *
 * Makes the sensor management container visible with appropriate fields and 
 * values for the given operation.
 */
function ShowPanelSensorManagement(parameters, operation)
{
    var sensorManagementContainer = GetSensorManagementPanel();
    sm_contextMenu.hide();
    window.ero.hide();
    
    var sensorMgmtTitle = $get("sensorMgmtTitleText");
    var sensorNameInput = $get("sensorNameInput");
    var sensorTypeDDL = $get("sensorTypeInput");
    var fileTypeDDL = $get("fileTypeInput");
    var latitudeInput = $get("latitudeInput");
    var longitudeInput = $get("longitudeInput");
    var imageURIInput = $get("imageURIInput");
    var keywordTextArea = $get("keywordTextArea");
    var sensorDescTextArea = $get("sensorDescTextArea");
    var actionButton = $get("actionButton");
    
    switch (operation) {
     
        case ManagementOperation.NEW :
            sensorManagementContainer.style.top = sm_contextMenu.getPosition().y + "px";
            sensorManagementContainer.style.left = sm_contextMenu.getPosition().x + "px";
            
            sensorMgmtTitle.innerText = "Publish Sensor";
            latitudeInput.value = parameters.latitude;
            longitudeInput.value = parameters.longitude;
            actionButton.value = "Publish";
            actionButton.onclick = SensorManagementInsert;
            
            sensorTypeDDL.disabled = false;
            fileTypeDDL.disabled = false;
            
            break;
            
        case ManagementOperation.UPDATE :    
        
            var sensorToUpdate = sensorsInViewport[parameters.sensorIndex];
            
            var smLocation = smMap.LatLongToPixel(sensorToUpdate.vePushpin.LatLong);
            sensorManagementContainer.style.top = 
                (smLocation.y + bannerheight + menubarheight) + "px";
            sensorManagementContainer.style.left = smLocation.x + 20 + "px";
        
            sensorMgmtTitle.innerText = "Update Sensor";
            sensorNameInput.value = sensorToUpdate.name;

            if (sensorToUpdate.constructor == VideoCameraSensor)
            {

                sensorTypeDDL.selectedIndex = 0;
                PopulateFileTypeDDList();

                if (sensorToUpdate.unit = "jpeg")
                {
                    fileTypeDDL.selectedIndex = 0;
                }
                else if (sensorToUpdate.unit = "gif")
                {
                    fileTypeDDL.selectedIndex = 1;
                }
            }
            else if (sensorToUpdate.constructor == GenericSensor)
            {
                sensorTypeDDL.selectedIndex = 1;
                PopulateFileTypeDDList();
                fileTypeDDL.selectedIndex = 0;
            }            

            sensorTypeDDL.disabled = true;
            fileTypeDDL.disabled = false;
            
            latitudeInput.value = sensorToUpdate.latitude;
            longitudeInput.value = sensorToUpdate.longitude;
            imageURIInput.value = sensorToUpdate.uri;
            keywordTextArea.value = sensorToUpdate.keywords;
            sensorDescTextArea.value = sensorToUpdate.desc;
            
            actionButton.value = "Update";
            actionButton.onclick = SensorManagementUpdateSave;
            actionButton.index = parameters.sensorIndex;
        
            break;
                 
        default:
            break;
    }   
    
    sensorManagementContainer.style.display = "block"; 
}

/*
 * HideSensorManagement
 *
 * Hides the sensor management container and resets all of its fields' values.
 */
function HideSensorManagement()
{
    var sensorManagementContainer = GetSensorManagementPanel();
    sensorManagementContainer.style.display = "none"; 
    $get("sensorNameInput").value = "";
    $get("fileTypeInput").value = "";
    $get("latitudeInput").value = "";
    $get("longitudeInput").value = "";
    $get("imageURIInput").value = "";
    $get("keywordTextArea").value = "";
    $get("sensorDescTextArea").value = "";
    HideContextPin();
}

/*
 * SensorManagementInsert
 *
 * Inserts new sensor using values given in sensor management container.
 */
function SensorManagementInsert()
{
    var swID = GetUserLogin();
    var sensorName = $get("sensorNameInput").value;
    var sensorTypeDDL = $get("sensorTypeInput");
    var sensorType = "";
    var fileTypeDDL = $get("fileTypeInput");
    var fileType = "";
    var latitude = $get("latitudeInput").value;
    var longitude = $get("longitudeInput").value;
    var uri = $get("imageURIInput").value;
    var keywords = $get("keywordTextArea").value;
    var sensorDescription = $get("sensorDescTextArea").value;


    if (sensorTypeDDL.selectedIndex == 0)
    {
        sensorType = Sensor.type["VIDEO_CAMERA"].typeURI;
    }
    else if (sensorTypeDDL.selectedIndex == 1)
    {
        sensorType = Sensor.type["GENERIC"].typeURI;
    }
    
    fileType = fileTypeDDL.options[fileTypeDDL.selectedIndex].value;

    if ((sensorName == null || sensorName == '' ) || 
        (latitude == null || latitude == '' ) ||
        (longitude == null || longitude == '' ) ||
        (uri == null || uri == '' ))
    {
        alert("You have forgotten to fill in some required fields.  Please fill " +
              "in a name, an image type, the latitude, the longitude, and the " +
              "url for where the latest image from your video camera is stored.");
    }
    else
    {
    
        latitude = parseFloat(latitude);
        longitude = parseFloat(longitude);

        SenseWeb.SensorManagement.RegisterSensor(
            sensorName, sensorType, fileType,
            latitude, longitude, 0.0,
            keywords, sensorDescription, uri, 
            SensorManagementComplete,
            SensorManagementTimeout);
          
    }
    
}

/*
 * SensorManagementDelete
 *
 * Deletes sensor at the given index in the viewport.
 */
function SensorManagementDelete(index)
{
    var sensorToDelete = sensorsInViewport[index];
    
    var deleteConfirm = 
        confirm("Are you sure you want to delete the sensor '" 
                + sensorToDelete.name + "'?");
                
    if (deleteConfirm)
    {
        /*
        SenseWeb.SensorManagement.RemoveSensor(sensorToDelete.name, 
            sensorToDelete.latitude, sensorToDelete.longitude,
            sensorToDelete.publisher,
            SensorManagementComplete,
            SensorManagementTimeout);
        */
        SenseWeb.SensorManagement.RemoveSensor(sensorToDelete.name,
            SensorManagementComplete,
            SensorManagementTimeout);
        
    }
}

/*
 * SensorManagementMove
 *
 * Shows sensor management move panel move a sensor and sets mouse to 
 * crosshair.
 */
function SensorManagementMove(index)
{
    mapContainer.childNodes[0].style.cursor = "crosshair";
    movingPushpin = index;
    VEPushpin.Hide();
}

/*
 * SensorManagementUpdate
 *
 * Shows sensor management panel to update a sensor.
 */
function SensorManagementUpdate(index)
{
    var parameters = new Object();
    parameters.sensorIndex = index;
    
    ShowPanelSensorManagement(parameters, ManagementOperation.UPDATE);
}

function SensorManagementMoveSave(newLat, newLong)
{
    var sensorUpdated = sensorsInViewport[movingPushpin];
    movingPushpin = null;
    
    var oldLatitude = sensorUpdated.latitude;
    var oldLongitude = sensorUpdated.longitude;   

    sensorUpdated.latitude = newLat;
    sensorUpdated.longitude = newLong;

    /*
    SenseWeb.SensorManagement.UpdateSensor(
        sensorUpdated.name, oldLatitude, oldLongitude,
        sensorUpdated.name, sensorUpdated.unit, sensorUpdated.latitude, 
        sensorUpdated.longitude, sensorUpdated.keywords, 
        sensorUpdated.desc, sensorUpdated.uri, 
        SensorManagementComplete,
        SensorManagementTimeout);
    */
    SenseWeb.SensorManagement.UpdateSensorLocation(
        sensorUpdated.name,
        sensorUpdated.latitude, sensorUpdated.longitude, 0.0,
        SensorManagementComplete,
        SensorManagementTimeout);
}

/*
 * SensorManagementUpdateSave
 *
 * Saves changes made to sensor through sensor management panel.
 */
function SensorManagementUpdateSave(event)
{
    var sensorUpdated = sensorsInViewport[this.index];
    
    var oldSensorName = sensorUpdated.name;
    var oldLatitude = sensorUpdated.latitude;
    var oldLongitude = sensorUpdated.longitude;   
    var sensorName = $get("sensorNameInput").value;
    var imageType = $get("fileTypeInput").value;
    var latitude = $get("latitudeInput").value;
    var longitude = $get("longitudeInput").value;
    var uri = $get("imageURIInput").value;
    var keywords = $get("keywordTextArea").value;
    var sensorDescription = $get("sensorDescTextArea").value;

    if ((sensorName == null || sensorName == '' ) ||
        (imageType == null || imageType == '' ) ||    
        (latitude == null || latitude == '' ) ||
        (longitude == null || longitude == '' ) ||
        (uri == null || uri == '' ))
    {
        alert("You have forgotten to fill in some required fields.  Please fill " +
              "in a name, an image type, the latitude, the longitude, and the " +
              "url for where the latest image from your video camera is stored.");
    }
    else
    {
        sensorUpdated.name = sensorName;
        sensorUpdated.unit = imageType;
        sensorUpdated.latitude = parseFloat(latitude);
        sensorUpdated.longitude = parseFloat(longitude);
        sensorUpdated.uri = uri;
        sensorUpdated.keywords = keywords;
        sensorUpdated.desc = sensorDescription;
    
        /*
        SenseWeb.SensorManagement.UpdateSensor(
            oldSensorName, oldLatitude, oldLongitude,
            sensorUpdated.name, sensorUpdated.unit, sensorUpdated.latitude, 
            sensorUpdated.longitude, sensorUpdated.keywords, 
            sensorUpdated.desc, sensorUpdated.uri, 
            SensorManagementComplete,
            SensorManagementTimeout);
        */
        SenseWeb.SensorManagement.UpdateSensorLocation(
            sensorUpdated.name,
            sensorUpdated.latitude, sensorUpdated.longitude, 0.0,
            SensorManagementComplete,
            SensorManagementTimeout);
        
    }
}

/*
 * SensorManagementComplete
 *
 * Handler for when call to SensorManagement web service completes.
 */
function SensorManagementComplete(result) 
{
    HideSensorManagement();
    UpdateSensorMap();
}

/*
 * SensorManagementTimeout
 *
 * Handler for when call to SensorManagement web service times out.
 */
function SensorManagementTimeout(result) 
{
    alert("Timed out: The sensor management function you just tried to " +
          "perform did not complete.  Try again soon.");
}

/*
 * PopulateFileTypeDDList
 *
 * Populates file type drop down list depending on which sensor type has been 
 * selected in the sensor management panel.
 */
function PopulateFileTypeDDList()
{
    // get sensortype dropdown
    var sensorTypeInput = $get("sensorTypeInput");

    // get filetype dropdown
    var fileTypeInput = $get("fileTypeInput");

    // remove old file type options
    for (ii = fileTypeInput.options.length - 1; ii >=0; ii--)
    {
        // fileTypeInput.options.remove(ii);
        fileTypeInput.options[ii] = null;
    }
    
    // add appropriate new file type options
    if (sensorTypeInput.selectedIndex == 0)
    {
        var opt1Var = document.createElement("option");
        opt1Var.text = "jpeg";
        opt1Var.value = "jpeg";

        var opt2Var = document.createElement("option");
        opt2Var.text = "gif";
        opt2Var.value = "gif";

        fileTypeInput.options[0] = opt1Var;
        fileTypeInput.options[1] = opt2Var;
    }
    else
    {
        var opt3Var = document.createElement("option");
        opt3Var.text = "html";
        opt3Var.value = "html";
        
        fileTypeInput.options[0] = opt3Var;
    }
}

/* ============================================================ */
/* Permalink Panel Functions and Handlers                       */
/* ============================================================ */
function GetPermalinkPanel()
{
    return $get("SM_PermalinkPanel");
}

function ShowPermalink()
{

    // build and insert link
    var link = location.protocol + "//" + location.host + location.pathname
        + "?" + smModel.toString();
       
    var linkEl = $get("SM_Permalink");
    linkEl.href = link;

    // show panel
    var permalinkPanelContainer = GetPermalinkPanel();
    permalinkPanelContainer.style.display = "block";
    permalinkPanelContainer.style.height = '125px';
    permalinkPanelContainer.style.width = '800px';
}

function CopyPermalink()
{
    var permalink = $get("SM_Permalink");
    window.clipboardData.setData("Text", permalink.href);
}

function GoToLocation()
{
    var whereTextBox = $get("whereTextBox");
    var place = whereTextBox.value;
    //whereTextBox.value = "";
    UpdateSensorMap(SM_Event.GO_TO_LOCATION, place);
}

function SetSensorMapLink()
{
    var linkEl = $get("smLinkFrmESM");
    linkEl.href = window.location.href.toLowerCase().replace('embedsensormap.aspx','default.aspx');
}