﻿/* **********************************************************************************************************************
FILE: permalink.js
DIRECTORY: scripts/rest
PROJECT: GeoEye
DATE: July 23, 2008
AUTHORS: CH2M Hill
DESCRIPTION: Creates PermaLink, Executes new search when PermaLink is loaded
********************************************************************************************************************** */

// Read URL permalink, parse and execute new catalog search based on params.
function PermaLinkLoadFromQueryString() {
    if (window.location.search.substring(1)) {
        // Take everything after 'Map.aspx'
        var request = window.location.search.substring(1);
        // Split remainder of URL into 5 variables.
        var vars = request.split("&");

        // check for external reference
        if ((vars[0].split("=")[0] != null)
            && (vars[0].split("=")[0].length > 0)
            && (vars[0].split("=")[0] == "xref")
            && (vars[0].split("=")[1] != null)
            && (vars[0].split("=")[1].length > 0)) {
            // External reference has been found in query string.  Decode.
            var externalReferenceURI = decodeURIComponent(vars[0].split("=")[1]);

            // cancel map alert if any
            CancelMapAlert();

            // Clear the results grid
            _searchResultsGrid.Clear();

            // enable clear button
            $("uxClearCell2").innerHTML = '<img alt="Clear Results" style="cursor:pointer" src="images/button-global-clear.png" onclick="ClearEverything()"/>';

            //Display Loading image & text
            ShowLoadingDisplay("External Reference");

            //Show Search Tab
            SwitchTab("search");

            // Add dynamic script to page
            var headID = document.getElementsByTagName("head")[0];
            var newScriptObject = document.createElement('script');
            newScriptObject.type = 'text/javascript';
            newScriptObject.src = externalReferenceURI;
            newScriptObject.onload = processExternalReference // executes on load function
            headID.appendChild(newScriptObject);
        }
        else // process permalink
        {
            // Only store the variable values, not names.
            var v1 = vars[0].split("=");
            var v2 = vars[1].split("=");
            var v3 = vars[2].split("=");
            var v4 = vars[3].split("=");
            var v5 = vars[4].split("whereClause=");

            var geometryType = v1[1];
            var geometry1 = v2[1];
            var mapCenter = v3[1].split(",");
            var zoomLevel = v4[1];
            var whereClause = decodeURIComponent(v5[1]);

            var aVertices = geometry1.split(",");

            // if permalink includes only location (i.e. x,y and zoom), zoom user..no search
            if ((geometryType == null) || (geometryType.length == 0)) {
                // Zoom to the AOI
                ZoomToPoint(mapCenter[0], mapCenter[1], parseInt(zoomLevel));
            }
            else {
                // FOR MARKER
                if (geometryType == "marker") {

                    // Get Custom Icon
                    var customMarker = getIcon();
                    markerOptions = { icon: customMarker };

                    // Set Geometry
                    var geometry = new GLatLng(aVertices[0], aVertices[1]);
                    var marker = new GMarker(geometry, markerOptions);
                    _searchGeometryObject.SetGeometry(marker, "marker");    // set global geometry variable
                }
                // FOR POLYGON & ENVELOPE
                else {
                    var points = new Array();
                    for (var i = 0; i < aVertices.length; i++) {
                        var j = i + 1;
                        // Add the vertices as new points to an array
                        points.push(new GLatLng(aVertices[i], aVertices[j]));
                        i++;
                    }
                    // Create a polygon object based on this points array.
                    var geometry = new GPolygon(points, "#ff0000", 2, 0.7, "#ff0000", 0);
                    _searchGeometryObject.SetGeometry(geometry, "polygon")
                }

                // Freeze display to stop user interaction
                LockDownDisplay(geometryType);
                // Zoom to the AOI
                ZoomToPoint(mapCenter[0], mapCenter[1], parseInt(zoomLevel));

                var prefs = new Preferences();
                prefs.SetPrefs(whereClause);

                //Set up params for the REST Query.
                var returnGeometry = true;
                var outFields = [_imageNameColumn, _dateColumn, _imageURL, _imageLL_Lat, _imageLL_Lon, _imageUR_Lat, _imageUR_Lon, _spacecraftColumn, _cloudCoverColumn, _dataOwnerColumn, _tiltAngleColumn, _resolutionColumn, _fullProductURL, _fullMetadataURL]; //Column names stored in preferences.js
                ExecuteRESTQuery(geometry, whereClause, returnGeometry, outFields);
                return true;
            }
        }
    }
}

// Displays a Map Alert Error
function displayPermalinkLoadError() {
    MapAlert("<font style=\"color:red;\"><b>An error has occured with your Permalink</b></font>.  Your search will not be recreated.");
}

// Rebuilds application state from javascript varaibles
// discovered in the page load
function PermaLink() {
    try {
        // validate all variables exist
        if ((geometryType != null) && (geometryWKT != null) && (mapCenterWKT != null)
            && (zoomLevel != null) && (whereClauseObjectsArray != null)) {
            // Extract X,Y from OGC Well Known Text (WKT) POINT(X Y)
            var mapCenter = mapCenterWKT.substring(7, mapCenterWKT.length - 1).split(' ');
            // Zoom to AOI Y,X,Zoom
            ZoomToPoint(mapCenter[1], mapCenter[0], parseInt(zoomLevel));

            var geometryMapObject;
            if (geometryType == "marker") {
                // Extract geometrytext from OGC WKT POINT(X Y)
                var geometrytext = geometryWKT.substring(7, geometryWKT.length - 1);
                // Split into coordinate X,Y
                var coordinateSplit = geometrytext.split(' ');
                
                // Get Custom Icon
                var customMarker = getIcon();
                markerOptions = { icon: customMarker };

                // Set Geometry
                var geometryMapObject = new GLatLng(coordinateSplit[1], coordinateSplit[0]);
                var marker = new GMarker(geometryMapObject, markerOptions);
                _searchGeometryObject.SetGeometry(marker, "marker");    // set global geometry variable
            }
            else if ((geometryType == "polygon") || (geometryType == "envelope")) {
                // Extract Geometry Object from OGC WKT to GeoFUSE OnlineMaps
                var geometrytext = geometryWKT.substring(10, geometryWKT.length - 2);
                var coordinates = geometrytext.split(',');

                var points = new Array();
                for (var i = 0; i < coordinates.length; i++) {
                    // Add the vertices as new points to an array
                    if (coordinates[i].split(' ')[0].length > 0)
                        points.push(new GLatLng(coordinates[i].split(' ')[1], coordinates[i].split(' ')[0]));
                    else
                        points.push(new GLatLng(coordinates[i].split(' ')[2], coordinates[i].split(' ')[1]));
                }

                // Create a polygon object based on this points array.
                geometryMapObject = new GPolygon(points, "#ff0000", 2, 0.7, "#ff0000", 0);
                _searchGeometryObject.SetGeometry(geometryMapObject, "polygon");
            }

            // Freeze display to stop user interaction
            LockDownDisplay(geometryType);

            var returnGeometry = true;
            var outFields = [_imageNameColumn, _dateColumn, _imageURL, _spacecraftColumn, _cloudCoverColumn, _dataOwnerColumn, _tiltAngleColumn, _resolutionColumn, _fullProductURL, _fullMetadataURL]; //Column names stored in preferences.js

            // Set Search Prefernces
            //Currently Allowed: CLOUD_COVER_PERCENT, COLLECTION_VEHICLE_LONG, COLLECTION_DATE_START, COLLECTION_DATE_END
            _searchPrefs.SetPrefs(whereClauseObjectsArray[0],
                whereClauseObjectsArray[1],
                whereClauseObjectsArray[2],
                whereClauseObjectsArray[3]);

            //Execute Query
            ExecuteRESTQuery(geometryMapObject, _searchPrefs.CreateWhereClause(), returnGeometry, outFields);

            // Clear Map Alert and display executing message
            MapAlert("Your GeoFUSE search request has been restored.  Executing Search Request.");
        }
        else {
            // Let the application load normally as there is no permalink requested.
        }
    }
    catch (e) {
        displayPermalinkLoadError();
    }
}

// Freeze the display while searching catalog.
function LockDownDisplay(geometryType) {

    // Clear the results grid
    _searchResultsGrid.Clear();

    //Visibly change button image
    $("mapPan").style.backgroundImage = "url(images/button-map-drag-disabled.gif)";
    $("mapMarker").style.backgroundImage = "url(images/button-map-pin-disabled.gif)";
    $("mapPoly").style.backgroundImage = "url(images/button-map-polygon-disabled.gif)";
    $("mapExtent").style.backgroundImage = "url(images/button-map-map-extent-disabled.gif)";

    //Turn on Freeze Div to disable application interaction while searching
    $("wrapper-searchingCover").style.display = "inline";

    //Display Loading image & text
    ShowLoadingDisplay(geometryType);

    //Show Search Tab
    SwitchTab("search");

}

// Creates a PermaLink based on search criteria when user clicks the link
// Uses 5 params for format the URL
function CreatePermaLink() {
    // open modal
    OpenPermaLink();

    // Only display the permalink if the SearchGeometry has been defined.
    if (_searchGeometryObject.GeometryType != undefined) {
        // Set the 4 params.
        var geometryType = _searchGeometryObject.GeometryType;
        //var mapCenter = _map.getCenter().y + "," + _map.getCenter().x;
        var mapCenter = "POINT (" + _map.getCenter().x + " " + _map.getCenter().y + ")"; // OGC WKT
        var zoomLevel = _map.getZoom();
        var whereClause = encodeURIComponent(_searchPrefs.CreatePermalinkWhereClause());
        var geometry = "";

        // For markers, just get the lng/lat
        if (_searchGeometryObject.GeometryType == "marker") {
            //var geometry = _searchGeometryObject.Geometry.y + "," + _searchGeometryObject.Geometry.x;
            geometry = "POINT (" + _searchGeometryObject.Geometry.x + " " + _searchGeometryObject.Geometry.y + ")"; // OGC WKT
        }
        // For envelope, loop through Geometry and add to Geometry param (in clockwise)
        else if (_searchGeometryObject.GeometryType == "envelope") {
            geometry = "POLYGON ((";
            for (var i = 0; i < _searchGeometryObject.Geometry.getVertexCount() - 1; i++) {
                geometry += _searchGeometryObject.Geometry.getVertex(i).x + " " + _searchGeometryObject.Geometry.getVertex(i).y + ",";
            }
            geometry += _searchGeometryObject.Geometry.getVertex(0).x + " " + _searchGeometryObject.Geometry.getVertex(0).y + "))";
        }
        // For polygon, loop through Geometry and add to Geometry param (in counter-clockwise)
        else if (_searchGeometryObject.GeometryType == "polygon") {
            geometry = "POLYGON ((";
            for (var i = _searchGeometryObject.Geometry.getVertexCount() - 1; i > 0; i--) {
                geometry += _searchGeometryObject.Geometry.getVertex(i).x + " " + _searchGeometryObject.Geometry.getVertex(i).y + ",";
            }
            geometry += _searchGeometryObject.Geometry.getVertex(0).x + " " + _searchGeometryObject.Geometry.getVertex(0).y + "))";
        }

        // Encode the Geometry
        geometry = encodeURIComponent(geometry);

        // Encode the centerPoit
        mapCenter = encodeURIComponent(mapCenter);
        
        // Display the URL
        $('uxPermaLink').value = "http://" + _serverName + "/Maps/Map.aspx?pv=2&geometryType=" + geometryType + "&geometryWKT=" + geometry + "&mapCenterWKT=" + mapCenter + "&zoomLevel=" + zoomLevel + "&whereClause=" + whereClause;
    }
    else {
        $('uxPermaLink').value = "Please execute a search on the Image Catalog.";
    }
}

// Strip whitespace from a string
function RemoveSpaces(string) {
    var tstring = "";
    string = '' + string;
    splitstring = string.split(" ");
    for (i = 0; i < splitstring.length; i++)
        tstring += splitstring[i];
    return tstring;
}

// function used to process external reference variables
function processExternalReference() {
    try {
        // execute on load function, from external reference
        xref_OnLoad();
    }
    catch (Exception)
    { }
}

// ----------------------- END ---------------------------