
var agiInitialRect;
var agiMapViewer;
var agiSubmitter;
var agiPan;
var agiMeasure;
var agiZoomBox;

var m_txtXCoord;
var m_txtYCoord;
var m_imgLoading;
var m_imgLogo;
var m_browsers;
var m_imgMapCanvas;
var m_imgOverviewCanvas;
var m_divOverviewBox;
var m_divDragBox;
var m_zoomBar;
var m_divCoords;
var m_divMeasure;
var m_tocTitle;
var m_bufferSelector;
var m_activeLayers;

var bufferUnits      = "";
var bufferDist       = "";
var bufferDrawParams = "";
var zoomToBuffer     = false;

var m_ExtentWidths = new Array(10); // The array that stores the level extent widths

var ZOOM_STEP_SCALE = .30;
var MAX_KMZ_DIM     = 2800;


// Determine browser type and platform.
var m_sClientBrowserType;           // Possible values: "IE", "Netscape", "Safari"
var m_sClientPlatform;              // Possible values: "Windows","Mac"

if      (navigator.userAgent.indexOf("Firefox") >=0)  m_sClientBrowserType = 'Netscape';
else if (navigator.userAgent.indexOf("MSIE")    >=0)  m_sClientBrowserType = 'IE';
else if (navigator.userAgent.indexOf("Safari")  >=0)  m_sClientBrowserType = 'Safari';
else                                                  m_sClientBrowserType = 'Netscape';

if      (navigator.userAgent.indexOf("Win") >= 0)  m_sClientPlatform = 'Windows';
else if (navigator.platform.indexOf("Mac")  >= 0)  m_sClientPlatform = 'Mac';


// Startup functiosn

function startUp() {
    window.name = "MapControl";

    // Handles to page widgets
    m_tocTitle          = document.getElementById("tocTitle");
    m_txtXCoord         = document.getElementById("txtXCoord");
    m_txtYCoord         = document.getElementById("txtYCoord");
    m_imgMapCanvas      = document.getElementById("imgMapCanvas");
    m_imgOverviewCanvas = document.getElementById("imgOverviewCanvas");
    m_imgLoading        = document.getElementById("imgLoading");
    m_imgLogo           = document.getElementById("imgLogo");
    m_browsers          = document.getElementById("browsers");
    m_divOverviewBox    = document.getElementById("divOverviewBox");
    m_divDragBox        = document.getElementById("divZoomBox");
    m_zoomBar           = document.getElementById("zoomBar");
    m_divCoords         = document.getElementById("divCoords");
    m_divMeasure        = document.getElementById("divMeasure");
    m_divMeasureButton  = document.getElementById("divMeasureButton");
    m_bufferSelector    = document.getElementById("bufferSelector");
    m_activeLayers      = document.getElementById("activeLayers");

    // Convert these into arrays
    layerViz             = parseVizString( layerViz.value );
    overviewViz          = parseVizString( overviewViz.value  );
    initialQueryLayerIds = initialQueryLayerIds.value.split( "^" );
    calendarDateCache    = parseCalendarDates( calendarDateCache.value );

    agiZoomBox = new ZoomBox( m_divDragBox );
    agiMeasure = new Measure( agiSubmitter );

    agiSubmitter = new Array();
    agiSubmitter.push( visibleLayersParams );
    agiSubmitter.push( calendarParams );
    agiSubmitter.push( highlightFeatureUrl );
    agiSubmitter.push( agiMeasure.agiMeasureUrl );

    agiMeasure.parseForPoints( initialMapPoints.value );
    agiSetZoombarExtentWidths();
    updateBufferDistance();
    resetMouseCursor();

    agiEventCoordinator   = new EventCoordinator();
    window.onresize       = scheduleDynamicLayout;
    m_imgMapCanvas.onload = afterImageLoad;

    // Delayed to give Telerik Panes the time they need to initialize
    scheduleDynamicLayout();
    setTimeout( initActiveLayers, 0 )
}

function parseVizString( vizString ) {
    var visibility = {};
    var vizPairs   = vizString.split( "^" );

    for (var i=0; i < vizPairs.length; i++) {
        var data     = vizPairs[i].split( "|" );
        var layerId  = data[0];
        var isOn     = data[1];
        var category = data[2];

        if (isOn == "1") {
            var ersatzNode      = {};
            ersatzNode.Value    = layerId
            ersatzNode.Checked  = true;
            ersatzNode.Category = category
            visibility[layerId] = ersatzNode;
        }
    }

    return visibility;
}

function parseCalendarDates( dateCacheString ) {
    var dateCache      = {};
    var layerDatePairs = dateCacheString.split( "^" );

    for (var i=0; i < layerDatePairs.length; i++) {
        var data           = layerDatePairs[i].split( "|" );
        var layerId        = data[0];
        var initialDate    = data[1];
        dateCache[layerId] = initialDate;
    }

    return dateCache;
}

function initActiveLayers() {
    queryLayerRows = {};
    if (initialQueryLayerIds.length > 1)
        multiQueryCheckbox.checked = true;
    for (var i=0; i < initialQueryLayerIds.length; i++)
        activateLayer( initialQueryLayerIds[i] );
}

function agiSetZoombarExtentWidths() {
    agiInitialRect    = new rect(agiInitMinX.value, agiInitMinY.value, agiInitMaxX.value, agiInitMaxY.value);
    var maxWidth      = agiInitialRect.getWidth();
    var scalar        = 1.0 - ZOOM_STEP_SCALE;
    m_ExtentWidths[0] = maxWidth * Math.pow(scalar, 9);
    m_ExtentWidths[1] = maxWidth * Math.pow(scalar, 8);
    m_ExtentWidths[2] = maxWidth * Math.pow(scalar, 7);
    m_ExtentWidths[3] = maxWidth * Math.pow(scalar, 6);
    m_ExtentWidths[4] = maxWidth * Math.pow(scalar, 5);
    m_ExtentWidths[5] = maxWidth * Math.pow(scalar, 4);
    m_ExtentWidths[6] = maxWidth * Math.pow(scalar, 3);
    m_ExtentWidths[7] = maxWidth * Math.pow(scalar, 2);
    m_ExtentWidths[8] = maxWidth * Math.pow(scalar, 1);
    m_ExtentWidths[9] = maxWidth * Math.pow(scalar, 0);
}


// Layer functions

function visibleLayersParams() {
    // return a string indicating the visibility of layers based on toc check boxes.
    return visibleLayersParam() + dynamicLayersParam() + externalLayersParam();
}

function visibleLayersParam()  { return getVizString( "&visibleLayers=",  layerViz,    "Layer"         ); } 
function dynamicLayersParam()  { return getVizString( "&dynamicLayers=",  layerViz,    "DynamicLayer"  ); } 
function externalLayersParam() { return getVizString( "&externalLayers=", layerViz,    "ExternalImage" ); }
function overviewLayersParam() { return getVizString( "&visibleLayers=",  overviewViz, "Layer"         ); } 

function getVizString( prefix, layers, category ) {
    var param     = "";
    var seperator = "^";

    for (var layerId in layers) {
        var node = layers[layerId];

        if (category == node.Category && node.Checked) {
            if (param != "")
                param += seperator;
            param += layerId + "|true";
        }
    }

    if (param != "")
        return prefix + param;
    return "";
}

function agiRemoveFromParams( params, removeParam ) {
    var allParams = params.split( "&" );
    for (var i=0; i < allParams.length; i++) {
        if (allParams[i].indexOf( removeParam ) > -1)
            return params.replace( "&" + allParams[i], "" );
    }
    return params;
}


// Button command functions

function clearMapOverlays() {
    // clear selections, hide report, clear query extent, hide right drag box, etc.
    agiMapViewer.setQueryExtent( agiMapViewer.getExtent() )
    agiZoomBox.hide();
    agiMeasure.clear();
    highlightLayerId.value   = "";
    highlightFeatureId.value = "";
    bufferDrawParams         = "";
    requestMap();
}

function addBookmark() {
    var title = 'Map Viewmark - ' + new Date().toLocaleString();
    var url   = "http://" + window.location.host + window.location.pathname + "?" +
                agiMapViewer.getExtentParams() +
                visibleLayersParams() +
                calendarParams() +
                highlightFeatureUrl() +
                agiMeasure.pointLabelParams();

    if (window.sidebar)    // Firefox
        window.sidebar.addPanel( title, url, "" ); 
    else if (document.all) // IE
        window.external.AddFavorite( url, title );
}


// Help functions.

function setMapHelp() {
    if (m_sClientBrowserType.indexOf( 'Safari' ) != -1)  setHelpPage( 2 );
    else                                                 setHelpPage( 1 );
}

function setTocHelp()    { setHelpPage( 0 ); } 
function setTabHelp()    { setHelpPage( 3 ); } 
function setQueryHelp()  { setHelpPage( 4 ); }

function handleTabMouseOver(   sender, eventArgs ) { setTabHelp();   }
function handleQueryMouseOver( sender, eventArgs ) { setQueryHelp(); }
function handleTabMouseOut(    sender, eventArgs ) { setTocHelp();   }
function handleQueryMouseOut(  sender, eventArgs ) { setTocHelp();   }

function setHelpPage( index ) {
    helpMultiPage.SelectPageByIndex( index );
}


// Active Layer UI functions

function activateLayer( layerID ) {
    // Clean out all query layers if only one is allowed
    if (!multiQueryCheckbox.checked) {
        for (id in queryLayerRows) {
            removeQueryLayer( id );
        }
    }

    if (!(layerID in queryLayerRows))
        addQueryLayer( layerID );

    resizeQueryPane();
}

function addQueryLayer( layerID ) {
    var body         = document.getElementById( "activeLayersBody" );
    var tr           = document.createElement( "TR" );
    var td           = document.createElement( "TD" );
    var deleteButton = document.createElement( "BUTTON" );
    var deleteImg    = document.createElement( "IMG" );
    var layerInput   = document.createElement( "INPUT" );

    body.insertBefore( tr, body.firstChild );
    tr.appendChild( td );

    deleteButton.id = "deleteButton " +layerID;
    deleteImg.id    = "deleteImg "    +layerID;
    layerInput.id   = "layerInput "   +layerID;

    deleteImg.src        = "AGIMapControls/images/eraser.jpg";
    deleteButton.title   = "Remove from Active Layers";
    deleteButton.onclick = onRemoveQueryLayer;
    deleteButton.appendChild( deleteImg );
    td.appendChild( deleteButton );

    layerInput.type     = "text";
    layerInput.readOnly = "true";
    layerInput.value    = layerID;  //!!! Convert to name!
    layerInput.size     = "33";
    td.appendChild( layerInput );

    queryLayerRows[layerID] = tr;
}

function onRemoveQueryLayer( evt ) {
    if (queryLayerCount() > 1) {
        var eventTarget = agiEventCoordinator.getEventTarget( evt );
        var layerID     = eventTarget.id.slice( "deleteButton ".length );
        removeQueryLayer( layerID );
    }
    else {
        alert( "You can't delete the last query layer!" )
    }
}

function removeQueryLayer( layerID ) {
    var elem = queryLayerRows[layerID];
    elem.parentNode.removeChild( elem );
    delete queryLayerRows[layerID];
    resizeQueryPane();
}

function resizeQueryPane() {
    oldQueryH = tocSplitter.GetPaneById( "MapControl_LayerPane" ).height;
    oldTocH   = tocSplitter.GetPaneById( "MapControl_TocPane" ).height;
    limitH    = (oldQueryH + oldTocH) / 2
    newQueryH = Math.min( limitH, 43 + 27 * queryLayerCount()     );
    newTocH   = Math.max( limitH, oldTocH + oldQueryH - newQueryH );

    tocSplitter.GetPaneById( "MapControl_LayerPane" ).SetHeight( newQueryH );
    tocSplitter.GetPaneById( "MapControl_TocPane" ).SetHeight( newTocH );
}

function queryLayerCount() {
    count = 0;
    for (p in queryLayerRows)
        count += 1;
    return count;
}


// Buffer functions

function editBufferDistance( evt ) {
    evt = agiEventCoordinator.getEvent( evt );
    if (evt.keyCode == "13")  // Enter
        updateBufferDistance();
}

function updateBufferDistance( evt ) {
    var unitsElement = document.getElementById( "bufferDistanceUnits" );
    bufferDist       = document.getElementById( "bufferDistance" ).value;
    bufferUnits      = unitsElement.options[unitsElement.selectedIndex].value;

    // Update map if a buffer is drawn
    if (bufferDrawParams != "") {
        setBufferParams();
        defaultOnBufferTab();
    }
}

function setBufferParams() {
    extent           = agiMapViewer.getQueryExtent();
    bufferDrawParams = "&bufferUnits=" + bufferUnits        +
                       "&bufferDist="  + bufferDist         +
                       "&qMinX="       + extent.getLeft()   +
                       "&qMaxX="       + extent.getRight()  +
                       "&qMinY="       + extent.getBottom() +
                       "&qMaxY="       + extent.getTop();
}


// Extensions to generics

Array.prototype.remove = function( s ){
  for (i=0; i < this.length; i++)
    if (s == this[i])
        this.splice( i, 1 );
}


