//(C) Copyright 2009 Active Web Solutions Ltd  
//      All rights reserved.
// This software is provided "as is" without warranty of any kind, express or implied, 
// including but not limited to warranties of merchantability and fitness for a particular
// purpose. Active Web Solutions Ltd does not support the Software, nor does it warrant
// that the Software will meet your requirements or that the operation of the Software will 
// be uninterrupted or error free or that any defects will be corrected.

/* GLOBAL VARIABLES
 **********************************************************************************************/
// Get Site Uri
var re = new RegExp("^http[s]?://(\[\\w\\d\\.]*)/");
var m = re.exec(document.URL);
var siteUrl = m[0].substr(0, m[0].length - 1);

// Absolute uris (site uri + relative uri)
var TILE_SERVER_ABSOLUTE_URI = siteUrl + TILE_SERVER_RELATIVE_URI;  
var WEBSERVICE_ABSOLUTE_URI = siteUrl + WEBSERVICE_RELATIVE_URI;
var METADATASERVICE_ABSOLUTE_URI = siteUrl + METADATASERVICE_RELATIVE_URI;

// Global variables
var map;
var DEFAULT_LAT = 12;
var DEFAULT_LONG = 0;
var DEFAULT_ZOOM = 2;
var Enum = new Enums();
var distanceObject = new MeasureDistance(-1, -1);
var cache = new Cache();
var qs = new QueryString();
var requestManager = new RequestManager();
var statusBar = new StatusBar();
var effectLock = false;
var GetGeoRssMapData_lock = false;
var mapData = new MapData();
var isNewRequest = true;
var availableStats = new AvailableStats(); // Must be global because of OnSelectNameChange method
var userSettings = new UserSettings();

var ISOs = new Array();
var ResultsPanelTimerId = null;

/* CUSTOM OBJECTS         
 **********************************************************************************************/

// Enumerations Objects
//!!! Must be synchronized with ItemType enum on the server
ItemTypeEnum = new function() {
    this.GeoRssInfo = -1;
    this.Crisis = 0;
    this.Conflict = 1;
    this.SuddenDisaster = 2;
    this.FoodSecurity = 3;
    this.Health = 4;
    this.Storm = 5;
    this.Earthquake = 6;
    this.Volcano = 7;
    this.Flood = 8;
    this.ContentItem = 9;        
    this.News = 10;
    this.AidAgency = 11;
    this.Blog = 12;
    this.Insight = 13;
    this.Picture = 14;
    this.Video = 15;        
    this.Map = 16;
    this.Statistic= 17;
    this.Unspecified = 18;
}

function Enums() {
    this.TileLayer = new function() {
        this.Wms = 0;
        this.Kml = 1;
    }
    this.Distance = new function() {
        this.Status = new function() {
            this.NotStarted = 0;
            this.Started = 1;
            this.Stopped = 2;            
        }
        this.Unit = new function() {
            this.Kilometers = 0;
            this.Miles = 1;            
        }
        this.UnitDisplayFormat = new function() {
            this.OneDecimalValue = 0;
            this.Detailed = 1;
        }
    }
    this.QsParams = new function() {
        // Tools
        this.MiniMap = "miniMap";
        this.miniMap = new function() {
            this.None = 0;
            this.Small = 1;
            this.Large = 2;
        }
        this.ScaleBar = "scaleBar";
        this.scaleBar = new function() {
            this.None = 0;
            this.Miles = 1;
            this.Kilometers = 2;
        }
        this.LatLonSensor = "llSensor";
        this.latLonSensor = new function() {
            this.None = 0;
            this.DMSUnit = 1;
            this.DecimalUnit = 2;
        }
        this.LLNextToPointer = "llNext";
        this.lLNextToPointer = new function() {
            this.TurnOff = 0;
            this.TurnOn = 1;
        }        
        this.DistanceMeasure = "distance";
        this.distanceMeasure = new function() {
            this.None = 0;
            this.Miles = 1;
            this.Kilometers = 2;
        }
        this.DistanceNextToPointer = "dmNext";
        this.distanceNextToPointer = new function() {
            this.TurnOff = 0;
            this.TurnOn = 1;
        }        

        // Server data
        this.Crisis = "crisis";
        this.Statistic = "statistic";
        this.ContentItem = "contentItem";
        this.Map = "map";

        // ContentItem
        this.News = "news";
        this.AidAgency = "aidAgency";
        this.Blog = "blog";
        this.Insight = "insight";
        this.Picture = "picture";
        this.Video = "video";

        // Crisis
        this.Conflicts = "conflict";
        this.Food = "food";
        this.Storms = "storm";
        this.Disasters = "disaster";
        this.Health = "health";
        this.EarthQuakes = "earthquake";
        this.Volcanos = "volcano";
        this.Floods = "flood";

        // Statistic
        this.Year = "year";
        this.StatMethod = "statMethod";

        // Applicable for all types
        this.Code = "code";
        this.LatestHours = "hours";
        this.FromDate = "fromDate"
        this.ToDate = "toDate"
        this.Top = "top"
        this.Source = "source";
        this.MapType = "mapType";
        this.SearchFor = "searchFor";

        // VEMap
        this.Zoom = "zoom";
        this.Latitude = "lat";
        this.Longitude = "long";
        this.MapStyle = "style";
    } 
    
    this.Request = new function() {
        this.Type = new function() {
            this.Server = 0;                        
            this.VeFind = 1;
            this.VeGeo = 2; 
            this.VeLatLong = 3;
            this.TileServer = 4;     
            this.ServerGeoRss = 5;    
            this.ServerStorm = 6;         
        }
        this.DataType = new function() {
            this.LatestNews = 0;
            this.Crisis = 1;
            this.Statistics = 2;
            this.GeoData = 3;
            this.LocationSearch = 4;   
            this.LatLongSearch = 5;              
        }        
        this.Status = new function() {
            this.Parsed = 0;
            this.Validated = 1;
            this.Sent = 2;
            this.Canceled = 3;
            this.Received = 5;    
        }              
    }   
}

function UserSettings() {
        this.cookie = new Cookie();
    }

    UserSettings.prototype.SetToolSettingsFromCookie = function() {

        // ScaleBar - Units
        var scaleBar = this.cookie.GetValue(Enum.QsParams.ScaleBar);
        if (scaleBar != null && scaleBar.length > 0) {
            //$("ScaleBarChBox").checked = true;
            (scaleBar == Enum.QsParams.ScaleBar.Miles) ? $("ScaleBarMiRBtn").checked = true : $("ScaleBarKmRBtn").checked = true;
        }
        
        // Minimap - Units
        var miniMap = this.cookie.GetValue(Enum.QsParams.MiniMap);
        if (miniMap == Enum.QsParams.miniMap.Small) {
            $("MiniMapSmallRBtn").checked = true;
        }
        else if (miniMap == Enum.QsParams.miniMap.Large) {
            $("MiniMapLargeRBtn").checked = true;
        }

        // Latitude/Longitude Sensor - Units
        var latLonSensor = this.cookie.GetValue(Enum.QsParams.LatLonSensor);
        if (latLonSensor == Enum.QsParams.latLonSensor.DMSUnit) {
            $("LatLongU1RBtn").checked = true;
        }
        else if (latLonSensor == Enum.QsParams.latLonSensor.DecimalUnit) {
            $("LatLongU2RBtn").checked = true;
        }
        
        // LLSensor - NextToPointer panel
        var llNext = this.cookie.GetValue(Enum.QsParams.LLNextToPointer);
        llNext == Enum.QsParams.lLNextToPointer.TurnOn ? $("LatLongPointerChBox").checked = true : $("LatLongPointerChBox").checked = false;

        // Distance
        var distance = this.cookie.GetValue(Enum.QsParams.DistanceMeasure);
        if (distance == Enum.QsParams.distanceMeasure.Miles) {
            $("DistanceMiRBtn").checked = true;
        }
        else if (distance == Enum.QsParams.distanceMeasure.Kilometers) {
            $("DistanceKmRBtn").checked = true;
        }
        
        // Distance - NextToPointer panel
        var dmNext = this.cookie.GetValue(Enum.QsParams.DistanceNextToPointer);
        dmNext == Enum.QsParams.distanceNextToPointer.TurnOn ? $("DistancePointerChBox").checked = true : $("DistancePointerChBox").checked = false;
    }
    
    UserSettings.prototype.ChangeCookieSettings = function(name, value)
    {
        var current_date = new Date;
        var cookie_year = current_date.getFullYear ( ) + 1; // cookie expires in one year
        var cookie_month = current_date.getMonth ( );
        var cookie_day = current_date.getDate ( );       
        
        this.cookie.Set(name, value, cookie_year, cookie_month, cookie_day);    
    }


// Cookie Class
function Cookie() {

}
    Cookie.prototype.GetValue = function(name)
    {
        var results = document.cookie.match ( '(^|;) ?' + name + '=([^;]*)(;|$)' );

        if ( results )
            return ( unescape ( results[2] ) );
        else
            return null;
    }
    
    Cookie.prototype.Delete = function(name)
    {
        var cookie_date = new Date ( );  // current date & time
        cookie_date.setTime ( cookie_date.getTime() - 1 );
        document.cookie = cookie_name += "=; expires=" + cookie_date.toGMTString();
    }
    
    Cookie.prototype.Set = function( name, value, exp_y, exp_m, exp_d, path, domain, secure )
    {
        var cookie_string = name + "=" + escape ( value );

        if ( exp_y )
        {
            var expires = new Date ( exp_y, exp_m, exp_d );
            cookie_string += "; expires=" + expires.toGMTString();
        }

        if ( path )
            cookie_string += "; path=" + escape ( path );

        if ( domain )
            cookie_string += "; domain=" + escape ( domain );

        if ( secure )
            cookie_string += "; secure";

        document.cookie = cookie_string;
    }
    
// Country Class
function Country(iso, name, items, vePolygons, link)
    {
        // Country Iso
        this.Iso = iso;
        // CountryName
        this.Name = name; 
        // Link to Country profile
        this.Link = link;
        // Array of VEShapes        
        this.VEPolygons = vePolygons;
        // Array of Items
        this.Items = items;    
    }
    
    // Returns true if a country contains more than one item type
    Country.prototype.IsThereMoreItemTypes = function(items)
    {
        if (items.length == 1) {
            return false;
        }
        else {
            // sort items by ItemType
            items.sortBy(
                function(value, index) {
                    return value.ItemType;            
                });
            // compare the first and last
            if (items.first().Type != items.last().Type) {
                return true;
            }    
            else {        
                return false;
            }    
        }
    }    

// PolygonCountryReference Class
function PolygonCountryReference(polygonID, iso)
    {
        this.PolygonID = polygonID;
        this.Iso = iso;
    }

// CountryData Class
function CountryData()
    {
        this.Countries = new Array();
        this.PolIsoReferences = new Array();
    }
    
    // Adds PolygonCountryReference
    CountryData.prototype.AddPolIsoReference = function(polygonID, iso)
    {
        var polIsoRef = new PolygonCountryReference(polygonID, iso);
        this.PolIsoReferences.push(polIsoRef);    
    }
    
    // Finds PolygonId for a country (iso)
    CountryData.prototype.GetPolygonIdForIso = function(iso, biggestPol)
    {    
        var polygonID = null;
        var polIsoReferences = this.PolIsoReferences.findAll( function(obj) { return contains(obj, "Iso", iso); });
        if (polIsoReferences != null && polIsoReferences.length > 0)
        {                    
            if (biggestPol) {
                var shape = null;
                var count = -1;
                for (var i = 0; i < polIsoReferences.length; i++)
                {
                    shape = map.GetShapeByID(polIsoReferences[i].PolygonID);
                    if (shape.GetPoints().length > count) {
                        count = shape.GetPoints().length;
                        polygonID = polIsoReferences[i].PolygonID;                    
                    }                    
                }
            }
            else {
                polygonID = polIsoReferences[0].PolygonID;            
            }                               
        }        
        return polygonID;

        function contains(obj, prop, value) {
            var propertyValue = (obj[prop]) ? obj[prop] : null;
            return value==propertyValue;
        }                  
    }    
    
    // Finds a country (iso) for a polygonID
    CountryData.prototype.GetIsoForPolygonId = function(polygonID)
    {  
        var iso = null;
        var polIsoReference = this.PolIsoReferences.findAll( function(obj) { return contains(obj, "PolygonID", polygonID); })[0];
        if (polIsoReference != null)
        {
            iso = polIsoReference.Iso;
        } 
        return iso;                 
                 
        function contains(obj, prop, value) {
            var propertyValue = (obj[prop]) ? obj[prop] : null;
            return value==propertyValue;
        }     
    }
    
    // Deletes PolygonCountryReference
    CountryData.prototype.DeleteAllPolygonReferencesToIso = function(deleteISOs)
    {  
        for (var i = 0; i < deleteISOs.length; i++)
        {
            this.PolIsoReferences = this.PolIsoReferences.reject( function(obj) { return contains(obj, "Iso", deleteISOs[i]); });
        }    
    
        function contains(obj, prop, value) {
            var propertyValue = (obj[prop]) ? obj[prop] : null;
            return value==propertyValue;
        }      
    }
    
    // Deletes All Country Data
    CountryData.prototype.DeleteAllCountries = function()
    {
        this.Countries = null;
    }
  
    // Deletes Country Data except Countries provided as an argument
    CountryData.prototype.DeleteCountries = function(deleteISOs)
    {                                            
        if (deleteISOs == null)
        {
            // Delete all cached ISOs
            deleteISOs = this.GetCachedISOs();
        }                  
        
        // Deletes Country objects in Countries array
        // Deletes VEShapes
        var layer = cache.MapLayerManager.GetPolygonLayer(map);
        for (var i = 0; i < deleteISOs.length; i++)
        {
            var country = this.GetCountry(deleteISOs[i]);
            for (var j = 0; j < country.VEPolygons.length; j++)
            {
                var shape = country.VEPolygons[j];
                layer.DeleteShape(shape);
            }
            var index = this.Countries.indexOf(country);
            this.Countries.splice(index, 1);        
        }
        // Deletes PolIsoReferences        
       this.DeleteAllPolygonReferencesToIso(deleteISOs);        
    }


    // Add Polygon to CachedPolygons array
    CountryData.prototype.AddCountry = function(country)
    {
        if (this.Countries == null) {
            this.Countries = new Array();                    
        }
        this.Countries.push(country);    
    }

    // Returns Polygon
    CountryData.prototype.GetCountry = function(iso) 
    {
        function contains(obj, prop, value) {
            var propertyValue = (obj[prop]) ? obj[prop] : null;
            return value==propertyValue;
        }          
        
        var result = null;
        if (this.Countries != null) {
            result = this.Countries.find(
                        function(obj) { return contains(obj, "Iso", iso); }
                    );     
        }            
        return result;    
    }

    // Returns a string Array of cached country ISOs
    CountryData.prototype.GetCachedISOs = function() 
    {
        if (this.Countries != null)
        {
            var countryISOs = new Array();            
            for (var i = 0; i < this.Countries.length; i++) {
                countryISOs.push(this.Countries[i].Iso);            
            }
            return countryISOs;        
        } 
        else {
            return null;
        }
    }
    
    CountryData.prototype.GetUniqueItemTypes = function()
    {
        itemTypes = new Array();
        for (var i = 0; i < this.Countries.length; i++)
        {
            for (var j = 0; j < this.Countries[i].Items.length; j++)
            {
                itemTypes.push(this.Countries[i].Items[j].Type);            
            }                    
        }
        itemTypes = itemTypes.uniq();
        return itemTypes;    
    }
    
    CountryData.prototype.IsMultiple = function()
    {
        for (var i = 0; i < this.Countries.length; i++)
        {
            var previosType = this.Countries[0].Items[0].Type;
            for (var j = 1; j < this.Countries[i].Items.length; j++)
            {
                if (this.Countries[i].Items.length != previosType) {
                    return true;
                }             
            }                    
        }
        return false;   
    }
    
    
    // Displays Polygons for Countries
    CountryData.prototype.DisplayPolygons = function(newlyCachedInBoxISOs, cachedInBoxISOs)
    {                 
        // Delete Countries which are out of the box
        if (cachedInBoxISOs != null)
        {        
            var layer = cache.MapLayerManager.GetPolygonLayer(map);
            var cachedISOs = this.GetCachedISOs();                
            var exceptISOs = newlyCachedInBoxISOs.concat(cachedInBoxISOs);            
            var deleteISOs = cachedISOs.reject(
                                function(iso) {
                                    return exceptISOs.indexOf(iso) != -1;                                                             
                                });                        
            this.DeleteCountries(deleteISOs);
        }
        
        var polygonLayer = cache.MapLayerManager.GetPolygonLayer(map);
        var vePolygons = new Array();       
        for (var i = 0; i < newlyCachedInBoxISOs.length; i++)
        {                    
            var country = this.GetCountry(newlyCachedInBoxISOs[i]);
            for (var j = 0; j < country.VEPolygons.length; j++)
            {                               
                var polygonShape = country.VEPolygons[j];
                polygonLayer.AddShape(polygonShape);
                this.AddPolIsoReference(polygonShape.GetID(), country.Iso);
            }                                                                  
        }
    }
    
    // Shows Info Box when you click on a polygon
    CountryData.prototype.ShowInfoBox = function(veShape, latLong)
    {    
        var polygonID = veShape.GetID();
        var title = "Data not available."
        var desc = "";
    
        var iso = this.GetIsoForPolygonId(polygonID);
        if (iso != null && iso.length > 0)
        {
            var country = cache.CountryData.GetCountry(iso);                                
            var title = "<div class='control'>" + 
                            "<div class='cHeader'>" +                     
                                "<a href='http://www.alertnet.org/db/cp/" + country.Name + ".htm' target='_blank'>" + country.Name + " (" + country.Iso + ")</a>" + 
                                "<div class='winClose' onclick='CloseInfoBox()'>" +
                                    "<img src='" + IMAGES_URL + "empty15x15.gif' alt='Close' title='Close' />" +                                    
                                "</div>" +
                            "</div>" + 
                        "</div>";            
            var desc = "<div id='InformationBoxDescription'>";
            var previosType = null;
            for (var j = 0; j < country.Items.length; j++)
            {
                var item = country.Items[j];                                
                                
                if (previosType == null || item.Type != previosType)
                {                
                    desc += "<div><h2>" + GetNameOfItemType(item.Type) + "</h2></div>";                                                
                }    
                // If title of an artickle is not provided than ignore a whole item (article)
                if (item.Title != null && item.Title.length > 0)
                {
                    // Article title
                    if (IsItCrisis(item.Type))
                    {
                        desc += "<div><h3 class='clickable crisis' onclick=\"SubmitCrisisCode('" + item.Code + "')\">" + item.Title + "</h3></div>";
                    }
                    else
                    { 
                        desc += "<div><h3>" + item.Title + "</h3></div>";
                    }    
                    if (item.Time != null)
                    {
                        if (item.Type == ItemTypeEnum.Statistic)
                        {
                            //desc += "<div><i>Year: </i>" + item.Time.format("yyyy") + "</div>";
                        }
                        else
                        {                            
                            desc += "<div>" + item.Time.toUTCString(); //format("dd/MMM/yyyy HH:mm:ss") + "</div>";                            
                        }    
                    }
                    // Article description                
                    if (item.Desc != null && item.Desc.length > 0)
                    {
                        desc += "<div class='itemDesc'>" + item.Desc + "</div>";                
                    }
                    // Article source
                    if (item.Source != null && item.Source.length > 0)
                    {
                        if (item.Type != ItemTypeEnum.Statistic)
                        {
                            desc += "<div class='itemSource'><span class='label'>Source: </span>" + item.Source + "</div>";                
                        }    
                    }                    
                    // Article link
                    if (item.Link != null && item.Link.length > 0)
                    {    
                        desc += "<div><a href='" + item.Link + "' target='_blank'>See details...</a></div>";
                    }
                    // Article kml (only for maps)
                    if (item.Kml != null && item.Kml.length > 0)
                    {
                        desc += "<div><a href='#' onclick=\"ShowKmlOnMap('" + item.Kml + "')\">Show on map...</a></div>";
                    }
                }                                                                    
                
                previosType = item.Type;
            }   
            desc += "</div>";
        }                
        veShape.SetTitle(title);
        veShape.SetDescription(desc);
        
        map.ShowInfoBox(veShape, latLong, null);    
        
        // Helper method
        function contains(obj, prop, value) 
        {
            var propertyValue = (obj[prop]) ? obj[prop] : null;
            return value.toLowerCase() == propertyValue.toLowerCase();
        }                  
    } 
    
    // Upadates Results Panel 
    CountryData.prototype.UpdateResultsPanel = function()
    {   
        // Clear Results Panel  
        $("MapResultsContentDiv").innerHTML = "";
        
        // Write Results
        var resText = "";
        var previosType = null;
        if (this.Countries != null)
        {
            this.Countries = this.Countries.sortBy(function(value, index)
                {
                    return value.Name;            
                });
            
            ISOs = this.GetCachedISOs();
            this._PutCountryResultIntoPanel(ISOs);                                                        
        }                     
    }
    // Clears Results Panel 
    CountryData.prototype.ClearResultsPanel = function()
    {   
        // Clear Results Panel  
        $("MapResultsContentDiv").innerHTML = "";                   
    }    
    
    // Upadates Results Panel 
    CountryData.prototype._PutCountryResultIntoPanel = function(ISOs)
    {     
        if (ISOs.length > 0)
        {
            var iso = ISOs.shift();
            var country = this.GetCountry(iso);            
            var polygonID = this.GetPolygonIdForIso(country.Iso, false);
                            
            if (polygonID != null)
            {
                //var resText = "<h3 class='clickable' onclick='ShowInfoBox(\"" + polygonID + "\")'>" + country.Name + "</h3>";
                var resText = "<h3>" + country.Name + "</h3>";
                previosType = null;
                
                for (j = 0; j < country.Items.length; j++)
                {
                    var item = country.Items[j];
                    if (previosType == null || item.Type != previosType)
                    {
                        resText += "<h4>" + GetNameOfItemType(item.Type) + "</h4>";                
                    }
                    
                    resText += "<p>" + item.Title + "</p>";
                    
                    previosType = item.Type;
                }                      
                // Update Results Panel
                // TODO: find out a polygonId was not returned for a ISO code
                $("MapResultsContentDiv").innerHTML += resText;    
            }
            
            ResultsPanelTimerId = setTimeout("cache.CountryData._PutCountryResultIntoPanel(ISOs)", 100);
        }            
    }
    
function MapLayerManager() 
    {
        this._PolygonLayer = null;        
        this._GeoLayer = null      
        this._GeoVolcanoLayer = null      
        this._GeoEarthquakeLayer = null      
        this._GeoStormLayer = null      
        this._GeoFloodLayer = null      
        this._TileLayers = new Array();
        this._StormLayer = null;
        this._VELayer = null;
        
        // Used for Kml processing - when TileLayer is displayed -> current map.GetMapView is saved
        this.PreviosMapView = null;
        this.PolygonId = null;
    } 
    
    MapLayerManager.prototype.GetItemType = function(layerIndex)
    {
        if (this._GeoVolcanoLayer != null && this._GeoVolcanoLayer._index == layerIndex) return ItemTypeEnum.Volcano;           
        if (this._GeoEarthquakeLayer != null && this._GeoEarthquakeLayer._index == layerIndex) return ItemTypeEnum.Earthquake;           
        if (this._GeoStormLayer != null && this._GeoStormLayer._index == layerIndex) return ItemTypeEnum.Storm;
        if (this._GeoFloodLayer != null && this._GeoFloodLayer._index == layerIndex) return ItemTypeEnum.Flood;
        return null;
    }
       
    // Returns Polygon Layer
    MapLayerManager.prototype.GetPolygonLayer = function()
    {
        if (this._PolygonLayer == null)
        {
            this._PolygonLayer = new VEShapeLayer();
            map.AddShapeLayer(this._PolygonLayer);
        }    
        return this._PolygonLayer;
    } 
    // Are there any shapes on polygon layer?
    MapLayerManager.prototype.DoesPolygonLayerHaveAnyShapes = function()
    {
        if (this._PolygonLayer != null)
        {
            var count = this._PolygonLayer.GetShapeCount();
            if (count != null && count > 0)
            {
                return true;
            }                    
        }
        return false;             
    }  
    
    // Hide Polygon Layer
    MapLayerManager.prototype.HidePolygonLayer = function()
    {
        if (this._PolygonLayer != null)
        {
            this._PolygonLayer.Hide();
        }            
    } 
    
    // Show Polygon Layer
    MapLayerManager.prototype.ShowPolygonLayer = function()
    {
        if (this._PolygonLayer != null)
        {
            this._PolygonLayer.Show();
        }            
    } 
          
    // Deletes Polygon Layer
    MapLayerManager.prototype.DeletePolygonLayer = function()
    {
        if (this._PolygonLayer != null)
        {
            //map.DeleteShapeLayer(this._PolygonLayer);
            this._PolygonLayer.DeleteAllShapes();
        }            
    }  
    // Returns Storm Layer
    MapLayerManager.prototype.GetStormLayer = function()
    {
        if (this._StormLayer == null)
        {
            this._StormLayer = new VEShapeLayer();
            map.AddShapeLayer(this._StormLayer);
        }    
        return this._StormLayer;
    } 
    // Are there any shapes on polygon layer?
    MapLayerManager.prototype.DoesStormLayerHaveAnyShapes = function()
    {
        if (this._StormLayer != null)
        {
            var count = this._StormLayer.GetShapeCount();
            if (count != null && count > 0)
            {
                return true;
            }                    
        }
        return false;             
    }        
    // Deletes Polygon Layer
    MapLayerManager.prototype.DeleteStormLayer = function()
    {
        if (this._StormLayer != null)
        {
            //map.DeleteShapeLayer(this._PolygonLayer);
            this._StormLayer.DeleteAllShapes();
        }            
    }     
      
    // Geo Layer
    MapLayerManager.prototype.GetGeoLayer = function()
    {                
        if (this._GeoLayer == null)
        {
            this._GeoLayer = new VEShapeLayer(); 
            map.AddShapeLayer(this._GeoLayer);       
        }
        return this._GeoLayer;
    }   
    MapLayerManager.prototype.DeleteGeoLayer = function()
    {                
        if (this._GeoLayer != null)
        {
            map.DeleteShapeLayer(this._GeoLayer);
            this._GeoLayer = null;
        }
    }       
    // Geo Volcano Layer
    MapLayerManager.prototype.GetGeoVolcanoLayer = function()
    {                
        if (this._GeoVolcanoLayer == null)
        {
            this._GeoVolcanoLayer = new VEShapeLayer();        
            this._GeoVolcanoLayer.SetTitle("volcanos");
            map.AddShapeLayer(this._GeoVolcanoLayer);
        }
        return this._GeoVolcanoLayer;
    }   
    MapLayerManager.prototype.DeleteGeoVolcanoLayer = function()
    {                
        if (this._GeoVolcanoLayer != null)
        {
            map.DeleteShapeLayer(this._GeoVolcanoLayer);
            this._GeoVolcanoLayer = null;
        }
    }       
    // Geo Earthquake Layer
    MapLayerManager.prototype.GetGeoEarthquakeLayer = function()
    {                
        if (this._GeoEarthquakeLayer == null)
        {
            this._GeoEarthquakeLayer = new VEShapeLayer();     
            this._GeoEarthquakeLayer.SetTitle("earthquakes");  
            map.AddShapeLayer(this._GeoEarthquakeLayer);
        }
        return this._GeoEarthquakeLayer;
    }   
    MapLayerManager.prototype.DeleteGeoEarthquakeLayer = function()
    {                
        if (this._GeoEarthquakeLayer != null)
        {
            map.DeleteShapeLayer(this._GeoEarthquakeLayer);
            this._GeoEarthquakeLayer = null;
        }
    }       
    // Geo Flood Layer
    MapLayerManager.prototype.GetGeoFloodLayer = function()
    {                
        if (this._GeoFloodLayer == null)
        {
            this._GeoFloodLayer = new VEShapeLayer();
            this._GeoFloodLayer.SetTitle("floods");
            map.AddShapeLayer(this._GeoFloodLayer);        
        }
        return this._GeoFloodLayer;
    }   
    MapLayerManager.prototype.DeleteGeoFloodLayer = function()
    {                
        if (this._GeoFloodLayer != null)
        {
            map.DeleteShapeLayer(this._GeoFloodLayer);
            this._GeoFloodLayer = null;
        }
    }       
    // Geo Storm Layer
    MapLayerManager.prototype.GetGeoStormLayer = function()
    {                
        if (this._GeoStormLayer == null)
        {
            this._GeoStormLayer = new VEShapeLayer();  
            this._GeoStormLayer.SetTitle("storms");    
            map.AddShapeLayer(this._GeoStormLayer);       
        }
        return this._GeoStormLayer;
    }   
    MapLayerManager.prototype.DeleteGeoStormLayer = function()
    {                
        if (this._GeoStormLayer != null)
        {
            map.DeleteShapeLayer(this._GeoStormLayer);
            this._GeoStormLayer = null;
        }
    }    
    
    // VE Layer
    MapLayerManager.prototype.GetVELayer = function()
    {                
        if (this._VELayer == null)
        {
            this._VELayer = new VEShapeLayer();  
            this._VELayer.SetTitle("VE");    
            map.AddShapeLayer(this._VELayer);       
        }
        return this._VELayer;
    }   
    MapLayerManager.prototype.DeleteVELayer = function()
    {                
        if (this._VELayer != null)
        {
            map.DeleteShapeLayer(this._VELayer);
            this._VELayer = null;
        }
    }                            
        
    // Deletes all GeoLayers
    MapLayerManager.prototype.DeleteAllGeoLayers = function()
    {
        this.DeleteGeoVolcanoLayer();
        this.DeleteGeoEarthquakeLayer();
        this.DeleteGeoFloodLayer();
        this.DeleteGeoStormLayer();
        this.DeleteGeoLayer();
        this.DeleteStormLayer();
        this.DeleteVELayer();
    }            
    // Adds a tile layer on a map and shows it. Args> id: "kml" or "wms"
    MapLayerManager.prototype.ShowTileLayer = function(url, type) {

        function GetBoundingBoxOfKmlImage_onSuccess(obj) {
            statusBar.HideLoading();
            // Did we get valid bounds?
            if (obj.MaxLatitude != null && obj.MinLongitude != null && obj.MinLatitude != null && obj.MaxLongitude != null) {
                var bounds = [new VELatLongRectangle(new VELatLong(obj.MaxLatitude, obj.MinLongitude), new VELatLong(obj.MinLatitude, obj.MaxLongitude))];

                // Create VE tile layer       
                var tileSourceSpec = new VETileSourceSpecification(id, TILE_SERVER_ABSOLUTE_URI + "?&quadkey=%4&kml=" + url);
                tileSourceSpec.NumServers = 1;
                tileSourceSpec.Bounds = bounds;
                tileSourceSpec.MinZoomLevel = 1;
                tileSourceSpec.MaxZoomLevel = 23;
                tileSourceSpec.Opacity = 0.85;
                tileSourceSpec.ZIndex = 500;
                map.AddTileLayer(tileSourceSpec, true);

                // Focus on an image (tile layer)
                map.SetMapView(bounds);

                if (map.GetZoomLevel() > 0) {
                    map.SetZoomLevel(map.GetZoomLevel() - 1)
                }
            }
        }
        function GetBoundingBoxOfKmlImage_onFailed(obj) {
            statusBar.HideLoading();
        }

        //statusBar.ShowLoading();
        this._DeleteTileLayer(id)

        if (type == Enum.TileLayer.Wms) {
            var id = "wms";

            // Save Layer
            this._TileLayers.push({ Id: id });

            var bounds = [new VELatLongRectangle(new VELatLong(90, -180), new VELatLong(-90, 180))];
            var tileSourceSpec = new VETileSourceSpecification(id, TILE_SERVER_ABSOLUTE_URI + "?&quadkey=%4&wms=" + url);
            tileSourceSpec.NumServers = 1;
            tileSourceSpec.Bounds = bounds;
            tileSourceSpec.MinZoomLevel = 1;
            tileSourceSpec.MaxZoomLevel = 23;
            tileSourceSpec.Opacity = 0.85;
            tileSourceSpec.ZIndex = 110;
            map.AddTileLayer(tileSourceSpec, true);
        }
        else if (type == Enum.TileLayer.Kml) {
            var id = "kml";

            // Save layer
            this._TileLayers.push({ Id: id });

            // Find out the bound of an image      
            Reuters.Alertnet.TileServer.Web.MetaDataService.set_path(METADATASERVICE_RELATIVE_URI);
            Reuters.Alertnet.TileServer.Web.MetaDataService.GetBoundingBoxOfKmlImage(url, GetBoundingBoxOfKmlImage_onSuccess, GetBoundingBoxOfKmlImage_onFailed, null);
        }
    }                
    // Deletes a specific tile layer
    MapLayerManager.prototype._DeleteTileLayer = function(id)
    {
        if (map.GetTileLayerByID(id) != null)
        {
            map.DeleteTileLayer(id);    
        }    
    }        
    // Deletes all tile layers
    MapLayerManager.prototype.DeleteAllTileLayers = function()
    {
        while (this._TileLayers.length > 0)
        {
            var tileLayer = this._TileLayers.pop(); 
            this._DeleteTileLayer(tileLayer.Id);
        }
    } 
        
    // Returns Geo Earthquake Layer
    /*MapLayerManager.prototype.GetGeoEarthquakeLayer = function(map, iconClusters) 
    {        
        if (geoEarthquakeLayer == null) 
        {
            geoEarthquakeLayer = new VEShapeLayer();
            if (iconClusters) 
            {
                var clusterOptions = new VEClusteringOptions();
                iconSpec = new VECustomIconSpecification();
                var iconCluster = "Content/Images/iconPushpinGreenCluster.gif"; 
                iconSpec.Image = iconCluster;
                clusterOptions.Icon = iconSpec;
                clusterOptions.Callback = null;     
                geoEarthquakeLayer.SetClusteringConfiguration(VEClusteringType.Grid, clusterOptions);
                // Default clustering - red pushpins
                //geoEarthquakeLayer.SetClusteringConfiguration(VEClusteringType.Grid);
            }  
            map.AddShapeLayer(geoEarthquakeLayer);                    
        }
        return geoEarthquakeLayer;
    } */                    
                            

// Cache Object
function Cache() 
    {  
    // Country Data
    this.CountryData = new CountryData();      
    // Map Layers
    this.MapLayerManager = new MapLayerManager();                             
    }


// QueryString Object
function QueryString() 
    {    
        this.Params = null;
        this.SiteUrl = null;
        this.DataUpdate = false;    
    }    

    QueryString.prototype.GetVELatLongMapCenter = function() 
    {  
        var lat = this.Params[Enum.QsParams.Latitude];
        var lon = this.Params[Enum.QsParams.Longitude];        
        if (lat != null && lon != null) {
            return new VELatLong(lat, lon);
        }    
        return null;            
    }

    QueryString.prototype.GetZoomLevel = function() 
    {  
        return this.Params[Enum.QsParams.Zoom];
    }

    QueryString.prototype.Initialize = function() 
    {  
        // Parse QueryString
        var query = location.href;
        this.Params = query.toQueryParams();
        
        // Get Site Url
        var index = query.indexOf("?");
        if (index > 0) {
            this.SiteUrl = query.substr(0, index);            
        }
        else {
            if (query.charAt(query.length - 1) == "#") {
                this.SiteUrl = query.substr(0, query.length - 1);
            }
            else
            {
                this.SiteUrl = query;
            }    
        }
    }
        
    QueryString.prototype.GetVELatLong = function()
    {
        var lat = this.Params[Enum.QsParams.Latitude];
        var lon = this.Params[Enum.QsParams.Longitude];        
        if (lat != null && lon != null)
        {
            return new VELatLong(lat, lon);                   
        }
    }
    
    QueryString.prototype.GetZommLevel = function()
    {
        return this.Params[Enum.QsParams.Zoom];
    }
                        
    QueryString.prototype.SetMapControls = function()
    {
        if (this.Params == null)
        {
            this._Initialize(location.href);        
        }    
        // VEMap
        var lat = this.Params[Enum.QsParams.Latitude];
        var lon = this.Params[Enum.QsParams.Longitude];        
        if (lat != null && lon != null)
        {
            var center = new VELatLong(lat, lon);
            map.SetCenter(center);        
        }
        var zoom = this.Params[Enum.QsParams.Zoom];
        if (zoom != null) {
            map.SetZoomLevel(zoom);
        }
        var style = this.Params[Enum.QsParams.MapStyle];
        if (style != null) {
            map.SetMapStyle(style);
        }

        // Tools
        var scaleBar = this.Params[Enum.QsParams.ScaleBar];
        if (scaleBar != null && scaleBar.length > 0) {
            $("ScaleBarChBox").checked = true;
            (scaleBar == Enum.QsParams.ScaleBar.Miles) ? $("ScaleBarMiRBtn").checked = true : $("ScaleBarKmRBtn").checked = true;
        }
        // Minimap   
        var miniMap = this.Params[Enum.QsParams.MiniMap];
        if (miniMap == Enum.QsParams.miniMap.Small) {
            $("MiniMapChBox").checked = true;
            $("MiniMapSmallRBtn").checked = true;
        }
        else if (miniMap == Enum.QsParams.miniMap.Large) {
            $("MiniMapChBox").checked = true;
            $("MiniMapLargeRBtn").checked = true;
        } 
        // Latitude/Longitude Sensor
        var latLonSensor = this.Params[Enum.QsParams.LatLonSensor];
        if (latLonSensor == Enum.QsParams.latLonSensor.DMSUnit) {
            $("LatLongChBox").checked = true;
            $("LatLongU1RBtn").checked = true;
        } 
        else if (latLonSensor == Enum.QsParams.latLonSensor.DecimalUnit) {
            $("LatLongChBox").checked = true;
            $("LatLongU2RBtn").checked = true;
        }
        // Distance
        var distance = this.Params[Enum.QsParams.DistanceMeasure];
        if (distance == Enum.QsParams.distanceMeasure.Miles) {
            $("MeasureDistanceChBox").checked = true;
            $("DistanceMiRBtn").checked = true;
        } 
        else if (distance == Enum.QsParams.distanceMeasure.Kilometers) {
            $("MeasureDistanceChBox").checked = true;
            $("DistanceKmRBtn").checked = true;
        }   
             
        // Server Data
        var data = new Object();
        
        // Server data
        if (this.Params[Enum.QsParams.Crisis]) data.Crisis = true;
        if (this.Params[Enum.QsParams.Statistic]) data.Statistic = true;
        if (this.Params[Enum.QsParams.ContentItem]) data.ContentItem = true;
        if (this.Params[Enum.QsParams.Map]) data.Map = true;
        
        // ContentItem
        if (this.Params[Enum.QsParams.News]) data.News = true;
        if (this.Params[Enum.QsParams.AidAgency]) data.AidAgency = true;     
        if (this.Params[Enum.QsParams.Blog]) data.Blog = true;
        if (this.Params[Enum.QsParams.Insight]) data.Insight = true;
        if (this.Params[Enum.QsParams.Picture]) data.Picture = true;
        if (this.Params[Enum.QsParams.Video]) data.Video = true; 

        // Crisis
        if (this.Params[Enum.QsParams.Conflicts]) data.Conflicts = true;
        if (this.Params[Enum.QsParams.Food]) data.Food = true;
        if (this.Params[Enum.QsParams.Storms]) data.Storms = true;
        if (this.Params[Enum.QsParams.Disasters]) data.Disasters = true;
        if (this.Params[Enum.QsParams.Health]) data.Health = true;
        if (this.Params[Enum.QsParams.EarthQuakes]) data.EarthQuakes = true;
        if (this.Params[Enum.QsParams.Volcanos]) data.Volcanos = true;
        if (this.Params[Enum.QsParams.Floods]) data.Floods = true;
        
        // Statistic
        if (this.Params[Enum.QsParams.Year] != null && this.Params[Enum.QsParams.Year].length > 0) {
            data.Year = this.Params[Enum.QsParams.Year];
        }    
        if (this.Params[Enum.QsParams.StatMethod] != null && this.Params[Enum.QsParams.StatMethod].length > 0) {
            data.StatMethod = this.Params[Enum.QsParams.StatMethod];
        }    

        // Applicable for all types
        if (this.Params[Enum.QsParams.Code] != null && this.Params[Enum.QsParams.Code].length > 0) {
            data.Code = this.Params[Enum.QsParams.Code];
        }    
        if (this.Params[Enum.QsParams.LatestHours] != null && this.Params[Enum.QsParams.LatestHours].length > 0) { 
            data.LatestHours = this.Params[Enum.QsParams.LatestHours];
        }    
        if (this.Params[Enum.QsParams.FromDate] != null && this.Params[Enum.QsParams.FromDate].length > 0) { 
            data.FromDate = this.Params[Enum.QsParams.FromDate];
        }    
        if (this.Params[Enum.QsParams.ToDate] != null && this.Params[Enum.QsParams.ToDate] > 0) {
            data.ToDate = this.Params[Enum.QsParams.ToDate];
        }
        if (this.Params[Enum.QsParams.Top] != null && this.Params[Enum.QsParams.Top].length > 0) {
            data.Top  = this.Params[Enum.QsParams.Top];
        }    
        if (this.Params[Enum.QsParams.Source] != null && this.Params[Enum.QsParams.Source].length > 0) { 
            data.Source = this.Params[Enum.QsParams.Source];
        }
        if (this.Params[Enum.QsParams.SearchFor] != null && this.Params[Enum.QsParams.SearchFor].length > 0) { 
            data.SearchFor = this.Params[Enum.QsParams.SearchFor];
        }        
        
        requestManager.AddServerRequest(data)                  
        requestManager.AddServerGeoRssRequest(data);
        requestManager.AddServerStormRequest(data);
        requestManager.SendAllRequests();           
    }
        
    // Returns URL represent a current settings of Map and Data Control    
    QueryString.prototype.Bookmark = function() 
    {
        // Reset this.Params
        this.Params = new Object();
        
        // VEMap
        var latLong = map.GetCenter();        
        this.Params[Enum.QsParams.Latitude] = latLong.Latitude;
        this.Params[Enum.QsParams.Longitude] = latLong.Longitude;        
        this.Params[Enum.QsParams.Zoom] = map.GetZoomLevel();  
        this.Params[Enum.QsParams.MapStyle] = map.GetMapStyle();  

        // Tools            
        if ($("ScaleBarChBox").checked) {
            if ($("ScaleBarMiRBtn").checked) { 
                this.Params[Enum.QsParams.ScaleBar] = Enum.QsParams.scaleBar.Miles; 
            } 
            else {
                this.Params[Enum.QsParams.ScaleBar] = Enum.QsParams.scaleBar.Kilometers;
            }     
        }                    
        if ($("MiniMapChBox").checked) {
            if ($("MiniMapSmallRBtn").checked) {
                this.Params[Enum.QsParams.MiniMap] = Enum.QsParams.miniMap.Small;    
            }
            else {
                this.Params[Enum.QsParams.MiniMap] = Enum.QsParams.miniMap.Large;
            }
        }        
        if ($("LatLongChBox").checked) {
            if ($("LatLongU1RBtn").checked) {
                this.Params[Enum.QsParams.LatLonSensor] = Enum.QsParams.latLonSensor.DMSUnit;
            }
            else {
                this.Params[Enum.QsParams.LatLonSensor] = Enum.QsParams.latLonSensor.DecimalUnit;            
            }
        }         
        if ($("MeasureDistanceChBox").checked) {
            if ($("DistanceMiRBtn").checked) {
                this.Params[Enum.QsParams.DistanceMeasure] = Enum.QsParams.distanceMeasure.Miles;
            }
            else {
                this.Params[Enum.QsParams.DistanceMeasure] = Enum.QsParams.distanceMeasure.Kilometers;
            }
        }           
    
        // Is any data displayed on the map? (was any server request made?)
        var request = null;
        var reqId = requestManager.GetLatestIdOfRequestByType(Enum.Request.Type.Server);
        if (reqId != null) {
            request = requestManager.GetRequestById(reqId);
        }
        if (request != null && request.Data != null && request.Status == Enum.Request.Status.Received)
        { 
            // Server data
            if (request.Data.Crisis) this.Params[Enum.QsParams.Crisis] = true;
            if (request.Data.Statistic)  this.Params[Enum.QsParams.Statistic] = true;
            if (request.Data.ContentItem) this.Params[Enum.QsParams.ContentItem] = true;
            if (request.Data.Map) this.Params[Enum.QsParams.Map] = true;
            
            // ContentItem
            if (request.Data.News) this.Params[Enum.QsParams.News] = true;
            if (request.Data.AidAgency) this.Params[Enum.QsParams.AidAgency] = true;     
            if (request.Data.Blog) this.Params[Enum.QsParams.Blog] = true;
            if (request.Data.Insight) this.Params[Enum.QsParams.Insight] = true;
            if (request.Data.Picture) this.Params[Enum.QsParams.Picture] = true;
            if (request.Data.Video) this.Params[Enum.QsParams.Video] = true; 

            // Crisis
            if (request.Data.Conflicts) this.Params[Enum.QsParams.Conflicts] = true;
            if (request.Data.Food) this.Params[Enum.QsParams.Food] = true;
            if (request.Data.Storms) this.Params[Enum.QsParams.Storms] = true;
            if (request.Data.Disasters) this.Params[Enum.QsParams.Disasters] = true;
            if (request.Data.Health) this.Params[Enum.QsParams.Health] = true;
            
            // Statistic
            if (request.Data.Year != null && request.Data.Year.length > 0) this.Params[Enum.QsParams.Year] = request.Data.Year;
            if (request.Data.StatMethod != null && request.Data.StatMethod.length > 0) this.Params[Enum.QsParams.StatMethod] = request.Data.StatMethod;

            // Applicable for all types
            if (request.Data.Code != null && request.Data.Code.length > 0) this.Params[Enum.QsParams.Code] = request.Data.Code;
            if (request.Data.LatestHours != null && request.Data.LatestHours.length > 0) this.Params[Enum.QsParams.LatestHours] = request.Data.LatestHours;
            if (request.Data.FromDate != null && request.Data.FromDate.length > 0) this.Params[Enum.QsParams.FromDate] = request.Data.FromDate;
            if (request.Data.ToDate != null && request.Data.ToDate.length > 0) this.Params[Enum.QsParams.ToDate] = request.Data.ToDate;
            if (request.Data.Top != null && request.Data.Top.length > 0) this.Params[Enum.QsParams.Top] = request.Data.Top;
            if (request.Data.Source != null && request.Data.Source.length > 0) this.Params[Enum.QsParams.Source] = request.Data.Source;
            if (request.Data.SearchFor != null && request.Data.SearchFor.length > 0) this.Params[Enum.QsParams.SearchFor] = request.Data.SearchFor;
        }
        
        // Is any data displayed on the map? (was any server GeoRSS request made?)
        var request = null;
        var reqId = requestManager.GetLatestIdOfRequestByType(Enum.Request.Type.ServerGeoRss);
        if (reqId != null) {
            request = requestManager.GetRequestById(reqId);
        }
        if (request != null && request.Data != null && request.Status == Enum.Request.Status.Received)
        {         
            if (request.Data.EarthQuakes) this.Params[Enum.QsParams.EarthQuakes] = true;
            if (request.Data.Volcanos) this.Params[Enum.QsParams.Volcanos] = true;
            if (request.Data.Floods) this.Params[Enum.QsParams.Floods] = true;        
        }

        // Is any data displayed on the map? (was any server Storm request made?)
        var request = null;
        var reqId = requestManager.GetLatestIdOfRequestByType(Enum.Request.Type.ServerStorm);
        if (reqId != null) {
            request = requestManager.GetRequestById(reqId);
        }
        if (request != null && request.Data != null && request.Status == Enum.Request.Status.Received)
        {         
            this.Params[Enum.QsParams.Storms] = true;   
        }
        
        var url = this.SiteUrl + "?" + $H(this.Params).toQueryString();
        return url;
    }        

// Request Class
// Improvements: attach onSuccessFunction to Request instead to RequestManager
function Request(type, data, dataType, isValid, refresh)
    {    
        this.Id = null; // request Id is assigned at the time of sending a request
        this.Type = type; // Server, Geo, Search
        this.DataType = dataType;
        this.IsValid = isValid; 
        this.Status = Enum.Request.Status.Parsed; // Parsed, Validated, Sent, Received
        this.Data = data; 
        this.RefreshMap = refresh;
    }

// Request Manager Class
// Note: There is no need to attach methods to prototype property - there is going to be only one instance of this class
function RequestManager()
{    
    this.LatestId = 0;
    this.LatestRequestType = null;
    this.Lock = false;    
    this._Requests = new Array();

    // Adds new request from input data
    // Arg: data - is a data object gained from FormData.GetRequestedData method
    this.AddNewRequests = function(data, refresh)
    {
        for (var i = 0; i < data.length; i++)
        {
            this._AddNewRequest(data[i].DataRequest, data[i].DataType, data[i].RequestType, refresh);                
        }    
    }
    
    this._AddNewRequest = function(dataRequest, dataType, requestType, refresh)
    {
        if (!this.Lock)
        {
            if (dataRequest != null) {
                var newRequest = new Request(requestType, dataRequest, dataType, true, refresh);
                this._Requests.push(newRequest);
            }
        }
    }
    
    /* Use on load of a map -> dataRequest is created from query parameters */
    this.AddServerRequest = function(dataRequest) {
        var newRequest = new Request(Enum.Request.Type.Server, dataRequest, null, true, true);
        var isValid = this._ValidateServerRequest(newRequest);
        if (isValid) {
            // Save data request
            this._Requests.push(newRequest);
        }
    }

    this.AddServerGeoRssRequest = function(dataRequest) {
        var newRequest = new Request(Enum.Request.Type.ServerGeoRss, dataRequest, null, true, true);
        var isValid = this._ValidateServerGeoRssRequest(newRequest);
        if (isValid) {
            // Save data request           
            this._Requests.push(newRequest);
        }    
    }

    this.AddServerStormRequest = function(dataRequest) {
        var newRequest = new Request(Enum.Request.Type.ServerStorm, dataRequest, null, true, true);
        if (dataRequest.Storms) {
            // Save data request         
            this._Requests.push(newRequest);
        }    
    }
    
    this._ValidateServerRequest = function(request)
    {
        var data = request.Data;
        if (data.Crisis || data.Statistic || data.ContentItem || data.Map)
        {
            return true;
        }
        
        return false;    
    }

    this._ValidateServerGeoRssRequest = function(request)
    {
        var data = request.Data;
        if (data.Volcanos || data.EarthQuakes || data.Floods)
        {
            return true;
        }
                
        return false;    
    }

    
    this.CreateAndSendCrisisRequestWithCode = function(code)
    {
        if (code != null && code.length > 0)
        {
            data = new Reuters.Alertnet.WebServices.Models.DataRequest();    
            data.Crisis = true;
            data.Code = code;        
            var request = new Request(Enum.Request.Type.Server, data, Enum.Request.DataType.Crisis, true);            
            request.RefreshMap = true;
            this._Requests.push(request);
            this._SendRequest(request);
        }    
    }
    
    this.SendAllRequests = function()
    {
        for (var i = 0; i < this._Requests.length; i++) {        
            this._SendRequest(this._Requests[i]);                            
        }    
    }

    this.SendRequestByType = function(requestType, refreshMap) {
        for (var i = 0; i < this._Requests.length; i++) {
            if (this._Requests[i].Type == requestType) {                
                this._Requests[i].RefreshMap = refreshMap;
                this._SendRequest(this._Requests[i]);
                break;
            }
        }
    }
        
    this.DeleteRequests = function()
    {
        this._Requests.clear();
    }
    
    this.GetLatestIdOfRequestByType = function(requestType)
    {
        var latestId = null;
        if (this._Requests != null && this._Requests.length > 0)
        {
            this._Requests.each(function(r) { if (r.Type == requestType && r.Id > latestId) latestId = r.Id; });
        }    
        return latestId;
    }
    
    this.GetIdOfLatestOnEndZoomRequest = function()
    {
        var latestId = null;
        this._Requests.each(function(r) { if (r.Type == Enum.Request.Type.Server && r.Id > latestId && r.Refresh) latestId = r.Id; });                
        return latestId;
    }       
    
    this.GetRequestById = function(id)
    {
        var request = null;
        this._Requests.each( function(r){ if (r.Id == id) request = r; });        
        return request;
    }
    
    this.AreAllRequestsDone = function()
    {
        var result = true;
        this._Requests.each( function(r){ if (r.Status != Enum.Request.Status.Received) result = false; });
        return result;
    }

    this._SendRequest = function(request) {
        request.Id = ++this.LatestId;        
        if (request.Type == Enum.Request.Type.Server) {
            this._SendServerRequest(request);
        }
        else if (request.Type == Enum.Request.Type.ServerGeoRss) {
            this._SendServerGeoRssRequest(request);
        }
        else if (request.Type == Enum.Request.Type.VeGeo) {
            this._SendVeGeoRequest(request);
        }
        else if (request.Type == Enum.Request.Type.VeFind) {
            this._SendVeFindRequest(request);
        }
        else if (request.Type == Enum.Request.Type.VeLatLong) {
            this._SendVeLatLongRequest(request);
        }
        else if (request.Type == Enum.Request.Type.TileServer) {
            this._SendTileLayerRequest(request);
        }
        else if (request.Type == Enum.Request.Type.ServerStorm) {
            this._SendStormRequest(request);
        }
    }

    this._SendServerRequest = function(request) {
        // Update Status Bar
        statusBar.ShowLoading();

        // Update Request By Bounding Box and Cache Data
        var mapView = map.GetMapView();
        var topleft = mapView.TopLeftLatLong;
        var bottomright = mapView.BottomRightLatLong;
        request.Data.North = topleft.Latitude;
        request.Data.West = topleft.Longitude;
        request.Data.South = bottomright.Latitude;
        request.Data.East = bottomright.Longitude;
        request.Data.ZoomLevel = map.GetZoomLevel();
        if (request.RefreshMap) {
            request.Data.CachedISOs = null;
        }
        else {
            request.Data.CachedISOs = cache.CountryData.GetCachedISOs();
        }
        request.Data.RequestId = request.Id;
        // ToDo: Delete when not needed
        // Map Style
        var style = map.GetMapStyle();
        if (style == VEMapStyle.Aerial) request.Data.MapStyle = 0;
        if (style == VEMapStyle.Road) request.Data.MapStyle = 1;
        if (style == VEMapStyle.Hybrid) request.Data.MapStyle = 2;

        // Call Webservice Method (AJAX call)
        requestSubmitedTime = new Date().getTime();
        Reuters.Alertnet.WebServices.MapDataService.set_path(WEBSERVICE_RELATIVE_URI);
        Reuters.Alertnet.WebServices.MapDataService.GetMapData(request.Data, GetDataFromServer_onSuccess, GetDataFromServer_onFailed, null);
        this.Status = Enum.Request.Status.Sent;
        return true;
    }  
    
    this._SendServerGeoRssRequest = function(request)  
    {
        // Update Status Bar
        statusBar.ShowLoading();
                       
        request.Data.RequestId = request.Id;
        
        // Call Webservice Method (AJAX call)
        Reuters.Alertnet.WebServices.MapDataService.set_path(WEBSERVICE_RELATIVE_URI);
        Reuters.Alertnet.WebServices.MapDataService.GetGeoRssMapData(request.Data, GetGeoRssMapData_onSuccess, GetGeoRssMapData_onFailed, null);                        
        this.Status = Enum.Request.Status.Sent;
        return true;   
    }
    
    this._SendStormRequest = function(request)
    {
        // Update Status Bar
        statusBar.ShowLoading();
                       
        request.Data.RequestId = request.Id;
        
        // Call Webservice Method (AJAX call)
        Reuters.Alertnet.WebServices.MapDataService.set_path(WEBSERVICE_RELATIVE_URI);
        Reuters.Alertnet.WebServices.MapDataService.GetStorms(request.Id, GetStorms_onSuccess, GetStorms_onFailed, null);                        
        this.Status = Enum.Request.Status.Sent;
        return true;  
    }
        
    this._SendVeGeoRequest = function(request)
    {        
        // Update Status Bar
        statusBar.ShowLoading();
        
        var iconPath = null;
        var clusterIconPath = null;
        var isBestView = true;
        var layer = null;
        
        // Set up an icon
        switch (request.DataType)
        {
            case ItemTypeEnum.Storm:
            {
                layer = cache.MapLayerManager.GetGeoStormLayer();
                iconPath = IMAGES_URL + "iconPushpinGreen.gif";
                iconClusterPath = null;                
                break;
            }
            case ItemTypeEnum.Flood:
            {
                layer = cache.MapLayerManager.GetGeoFloodLayer();
                iconPath = IMAGES_URL + "iconPushpinBlue.gif";
                iconClusterPath = null;            
                break;
            }        
            case ItemTypeEnum.Earthquake:
            {
                layer = cache.MapLayerManager.GetGeoEarthquakeLayer();
                iconPath = IMAGES_URL + "iconPushpinRed.gif";
                iconClusterPath = null;            
                break;
            }                
            case ItemTypeEnum.Volcano:
            {
                layer = cache.MapLayerManager.GetGeoVolcanoLayer();                
                iconPath = IMAGES_URL + "iconPushpinYellow.gif";
                iconClusterPath = null;          
                break;
            }
            default:
            {
                layer = cache.MapLayerManager.GetGeoLayer();
            }
        }
        
        // Sends a request                        
        if (request.IsValid) 
        {  
            var currentZoomLevel = map.GetZoomLevel();             
            var shapeSpec = new VEShapeSourceSpecification(VEDataType.ImportXML, request.Data.Url, layer);
            map.ImportShapeLayerData(shapeSpec, geoOnSuccess, isBestView);                                                       
        }
        
        // Receives a response
        function geoOnSuccess(layer)
        {             
            if (iconPath != null) {
                var numShapes = layer.GetShapeCount();
                for(var i=0; i < numShapes; ++i)
                {
                    var s = layer.GetShapeByIndex(i);
                    s.SetCustomIcon(iconPath);
                }
            }
            if (clusterIconPath != null) {
                var clusterOptions = new VEClusteringOptions();
                iconSpec = new VECustomIconSpecification();
                iconSpec.Image = clusterIconPath;
                clusterOptions.Icon = iconSpec;
                clusterOptions.Callback = null;
                layer.SetClusteringConfiguration(VEClusteringType.Grid, clusterOptions);
            }
            else {
                layer.SetClusteringConfiguration(VEClusteringType.Grid);
            }
            // Best Fit View
            if (isBestView) {
                var rectBestFit = layer.GetBoundingRectangle();                   
                if (layer.GetShapeCount() > 0)
                {
                    map.SetMapView(rectBestFit);
                    if (map.GetZoomLevel() > currentZoomLevel)
                    {
                        map.SetZoomLevel(currentZoomLevel);
                    }
                }
            }    
            requestManager.GetRequestById(request.Id).Status = Enum.Request.Status.Received;
            if (requestManager.AreAllRequestsDone())
            {
                statusBar.HideLoading();
            }   
            if (layer.GetShapeCount() == 0)
            {
                var lTitle = layer.GetTitle();
                if (lTitle.length > 0) 
                {
                    lTitle = " for " + lTitle;                    
                }
                statusBar.ShowStatusMessage("No data available" + lTitle + ".", 3000);
            }
            else
            {
                var itemType = cache.MapLayerManager.GetItemType(layer._index)
                if (itemType != null)
                {
                    ShowLegends([ itemType ] , true, true);
                }                                        
            }
        }
    }

    this._SendVeFindRequest = function(request, iconPath, clusterIconPath, isBestView) {
        $('VEFindDiv').hide();
        $('VEFindResultsDiv').innerHTML = "";
        if (request.IsValid) map.Find("",
                                      request.Data.Location,
                                      null,
                                      cache.MapLayerManager.GetVELayer(),
                                      null,
                                      null,
                                      null,
                                      null,
                                      false,
                                      null,
                                      VEFind_Callback);


        function VEFind_Callback(a, b, c, d, e) {
            if (c != null && c.length > 1) {
                ActivateMenuItem_OnClick($("SearchLi"));
                var results = "";
                for (i = 0; i < c.length; i++) {
                    if (i == 0 || c[i].Name != c[i - 1].Name) {
                        results += "<a href=\"javascript:FindOnMap('" + c[i].Name + "')\">" + c[i].Name + "</a><br>";
                    }
                }
                $('VEFindDiv').show();
                $('VEFindResultsDiv').innerHTML = results;
            }
        }

        function disambigDone(n) {
            if (document.getElementById("callbackText")) {
                UpdateHTML("callbackText", "");
                if (placesArray && n >= 0) {
                    try {
                        map.Find(find.what, placesArray[n].Name, null, findLayer, find.start, find.num, find.show, find.create, find.disam, find.best, find.doCallback);
                    }
                    catch (e) {
                        UpdateHTML("callbackText", "<tt style='color:Red;'>Error: " + e.message + "</tt>");
                    }
                }
                else {
                    HideAlert();
                    if (placesArray && n >= 0) DoFind(null, placesArray[n].Name, null, null, null, null, false, null, null);
                }
            }
        }

    }

    this._SendVeLatLongRequest = function(request, iconPath, clusterIconPath, isBestView)
    {
        if (request.IsValid) 
        {
            ShowPointOnMap(request.Data.Lat, request.Data.Lon);
        }    
    }
        
    this._SendTileLayerRequest = function(request)
    {        
        cache.MapLayerManager.ShowTileLayer(request.Data.Url, Enum.TileLayer.Wms);
    }                        
}


// FormData Class
function FormData()
    {
    }
    
    // Returns dataRequest object
    FormData.prototype.GetRequestedData = function()
    {
        var data = null;
        
        var dataType = this._GetTypeOfSubmittedData();
        if (dataType != null)
        {
            var isValid = this.Validate(dataType);
            if (isValid)
            {
                data = this._CreateServerRequestDataObject(dataType);                                
            }                
        } 
        
        return data;    
    }
    
    // Returns the type of submitted data
    FormData.prototype._GetTypeOfSubmittedData = function()
    {
        var dataType = null;
        
        try
        {
            if ($("LatestNewsDiv").getElementsByClassName("activeHeader").length > 0)
            {
                dataType = Enum.Request.DataType.LatestNews;
            }                    
            else if ($("CrisisDiv").getElementsByClassName("activeHeader").length > 0)
            {
                dataType = Enum.Request.DataType.Crisis;
            }
            else if ($("StatisticsDiv").getElementsByClassName("activeHeader").length > 0)
            {
                dataType = Enum.Request.DataType.Statistics;
            }                    
            else if ($("GeoDataDiv").getElementsByClassName("activeHeader").length > 0)
            {
                dataType = Enum.Request.DataType.GeoData;
            }                            
            else if ($("SearchLocationDiv").getElementsByClassName("activeHeader").length > 0)
            {
                dataType = Enum.Request.DataType.LocationSearch;
            }                    
            else if ($("SearchLatLongDiv").getElementsByClassName("activeHeader").length > 0)
            {
                dataType = Enum.Request.DataType.LatLongSearch;
            }                                                    
        }
        catch (ex)
        {
            // works in IE
            if (Element.getElementsByClassName($("LatestNewsDiv"), "activeHeader").length > 0)
            {
                dataType = Enum.Request.DataType.LatestNews;
            }                                
            else if (Element.getElementsByClassName($("CrisisDiv"), "activeHeader").length > 0)
            {
                dataType = Enum.Request.DataType.Crisis;
            }
            else if (Element.getElementsByClassName($("StatisticsDiv"), "activeHeader").length > 0)
            {
                dataType = Enum.Request.DataType.Statistics;
            }                    
            else if (Element.getElementsByClassName($("GeoDataDiv"), "activeHeader").length > 0)
            {
                dataType = Enum.Request.DataType.GeoData;
            }               
            else if (Element.getElementsByClassName($("SearchLocationDiv"), "activeHeader").length > 0)
            {
                dataType = Enum.Request.DataType.LocationSearch;
            }                    
            else if (Element.getElementsByClassName($("SearchLatLongDiv"), "activeHeader").length > 0)
            {
                dataType = Enum.Request.DataType.LatLongSearch;
            }                                                          
        }

        return dataType;               
    }
    
    
    // Returns dataRequest object created from parsed form data
    FormData.prototype._CreateServerRequestDataObject = function(dataType) {
        var data = new Array();

        // Crisis
        if (dataType == Enum.Request.DataType.Crisis) {
            // Server
            var dataRequest = new Reuters.Alertnet.WebServices.Models.DataRequest();

            dataRequest.Crisis = true;
            if ($("ConflictsChBox").checked) dataRequest.Conflicts = true;
            if ($("SuddenDisasterChBox").checked) dataRequest.Disasters = true;
            if ($("FoodSecurityChBox").checked) dataRequest.Food = true;
            if ($("HealthChBox").checked) dataRequest.Health = true;

            if (dataRequest.Conflicts || dataRequest.Disasters || dataRequest.Food || dataRequest.Health) {
                data.push({ RequestType: Enum.Request.Type.Server, DataType: dataType, DataRequest: dataRequest });
            }

            // GeoRSS, KML
            dataRequest = new Reuters.Alertnet.WebServices.Models.DataRequest();
            if ($("FloodsChBox").checked) {
                dataRequest.Floods = true;
            }
            if ($("EarthquakesChBox").checked) {
                dataRequest.EarthQuakes = true;
            }
            if ($("VolcanosChBox").checked) {
                dataRequest.Volcanos = true;
            }

            if (dataRequest.Floods || dataRequest.EarthQuakes || dataRequest.Volcanos) {
                data.push({ RequestType: Enum.Request.Type.ServerGeoRss, DataType: dataType, DataRequest: dataRequest });
            }

            // Storms    
            if ($("StormsChBox").checked) {
                data.push({ RequestType: Enum.Request.Type.ServerStorm, DataType: dataType, DataRequest: { Storm: true} });
            }
        }
        // GeoData
        else if (dataType == Enum.Request.DataType.GeoData) {
            // Did user write his/her own address of GeoRSS?
            if ($("UrlOfRSSFeedRBtn").checked) {
                var url = $("UrlGeoRSS").value.replace(/^\s+|\s+$/g, '');
                data.push({ RequestType: Enum.Request.Type.VeGeo, DataType: dataType, DataRequest: { Url: url, ItemType: null} });
            }
            // Did user selected GeoRSS from a dropdownlist?
            else if ($("SelectRSSFeedRBtn").checked) {
                var url = $("GeoRSSDDList").value.replace(/^\s+|\s+$/g, '');
                data.push({ RequestType: Enum.Request.Type.VeGeo, DataType: dataType, DataRequest: { Url: url, ItemType: null} });
            }
            // Did user write his/her own address of GeoRSS?
            else if ($("UrlOfWmsFeedRBtn").checked) {
                var url = $("UrlWMS").value.replace(/^\s+|\s+$/g, '');
                data.push({ RequestType: Enum.Request.Type.TileServer, DataType: dataType, DataRequest: { Url: url, ItemType: null} });
            }
        }
        // Statistics                     
        else if (dataType == Enum.Request.DataType.Statistics) {
            var dataRequest = new Reuters.Alertnet.WebServices.Models.DataRequest();

            dataRequest.Statistic = true;
            var statsCode = $("AvailableStatNameSelect").value;
            var statsYear = $("AvailableStatYearSelect").value;
            dataRequest.Statistic = true;
            dataRequest.Year = statsYear;
            dataRequest.Code = statsCode;
            // Statistic evaluating algorithm
            if ($("StatMethodLinearRBtn").checked) dataRequest.StatMethod = $("StatMethodLinearRBtn").value;
            if ($("StatMethodLogRBtn").checked) dataRequest.StatMethod = $("StatMethodLogRBtn").value;
            if ($("StatMethodKMeansRBtn").checked) dataRequest.StatMethod = $("StatMethodKMeansRBtn").value;

            data.push({ RequestType: Enum.Request.Type.Server, DataType: dataType, DataRequest: dataRequest });
        }
        // Latest News
        else if (dataType == Enum.Request.DataType.LatestNews) {
            var dataRequest = new Reuters.Alertnet.WebServices.Models.DataRequest();

            // Categories
            if ($("NewsChBox").checked) dataRequest.News = true;
            if ($("InsightChBox").checked) dataRequest.Insight = true;
            if ($("BlogChBox").checked) dataRequest.Blog = true;
            if ($("AidAgencyChBox").checked) dataRequest.AidAgency = true;
            if ($("PictureChBox").checked) dataRequest.Picture = true;
            if ($("MapChBox").checked) dataRequest.Map = true;

            if (dataRequest.News || dataRequest.Insight || dataRequest.Blog || dataRequest.AidAgency || dataRequest.Picture) {
                dataRequest.ContentItem = true;
            }

            // Time period
            if ($("TimePeriodChBox").checked) {
                dataRequest.LatestHours = $("LatestNewsSelect").value;
            }

            // Date
            if ($("DateChBox").checked) {
                var from = $("SearchDateFromValue").value;
                var to = $("SearchDateToValue").value;
                dataRequest.FromDate = from;
                dataRequest.ToDate = to;
            }

            // Source
            if ($("SourceChBox").checked) {
                if ($("SourceNameSelect").visible()) {
                    dataRequest.Source = $("SourceNameSelect").value;
                }
                else if ($("AidAgencySourceNameSelect").visible()) {
                    dataRequest.AidAgencySource = $("AidAgencySourceNameSelect").value;
                }
                else if ($("MapSourceNameSelect").visible()) {
                    dataRequest.Source = $("MapSourceNameSelect").value;
                }
            }

            // Search term
            if ($("SearchWhat").value != null && $("SearchWhat").value.length > 0) {
                dataRequest.SearchFor = $("SearchWhat").value;
            }

            data.push({ RequestType: Enum.Request.Type.Server, DataType: dataType, DataRequest: dataRequest });
        }
        // Search -> Location
        else if (dataType == Enum.Request.DataType.LocationSearch) {
            var loc = $("SearchWhere").value;
            data.push({ RequestType: Enum.Request.Type.VeFind, DataType: dataType, DataRequest: { Location: loc} });
        }
        // Search -> LatLong
        else if (dataType == Enum.Request.DataType.LatLongSearch) {
            var lat = $("SearchLat").value;
            var lon = $("SearchLong").value;
            data.push({ RequestType: Enum.Request.Type.VeLatLong, DataType: dataType, DataRequest: { Lat: lat, Lon: lon} });
        }

        return data;
    }
    
    // Validated form data                                  
    FormData.prototype.Validate = function(dataType)
    {
        var isValid = true;
                
        if (dataType == Enum.Request.DataType.Crisis)
        {
            if (!$("ConflictsChBox").checked && !$("SuddenDisasterChBox").checked && !$("FoodSecurityChBox").checked && 
                !$("HealthChBox").checked && 
                !$("StormsChBox").checked && !$("FloodsChBox").checked && !$("EarthquakesChBox").checked && 
                !$("VolcanosChBox").checked)
            {
                alert("No crisis types are selected.");
                isValid = false;
            }    
        }        
        else if (dataType == Enum.Request.DataType.LatestNews)
        {
            if (!$("NewsChBox").checked && !$("InsightChBox").checked && !$("BlogChBox").checked && !$("AidAgencyChBox").checked &&
                !$("PictureChBox").checked && !$("MapChBox").checked)
            {
                isValid = false;
                alert("Please tick off any of the checkboxes.");                            
            }                                
        
            if ($("SearchWhat").value.replace(/^\s+|\s+$/g, '').length == 0 && !$("DateChBox").checked && 
                !$("SourceChBox").checked && !$("TimePeriodChBox").checked)
            {
                alert("To search, please specify the required dates, time period, source, or search text.");
                isValid = false;
            }
                
            if ($("DateChBox").checked)
            {                    
                var defaultDate = "dd/mm/yyyy";                    
                var fromDate = $("SearchDateFromValue").value;
                if (!this._ValidateDate(fromDate, "From date", true, defaultDate))
                {
                    isValid = false;
                }
                
                var toDate = $("SearchDateToValue").value;
                if (!this._ValidateDate(toDate, "To date", true, defaultDate))
                {
                    isValid = false;
                }
            }  
                      
            if ($("SourceChBox").checked)
            {  
                var sourceValue = null;
                if ($("SourceNameSelect").visible())
                {
                    sourceValue = $("SourceNameSelect").value;               
                }
                else if ($("AidAgencySourceNameSelect").visible())
                {
                    sourceValue = $("AidAgencySourceNameSelect").value;
                }
                else if ($("MapSourceNameSelect").visible())
                {
                    sourceValue = $("MapSourceNameSelect").value;
                }                
                if (sourceValue != null && sourceValue == "-1")
                {
                    alert("Please select a source.");
                    isValid = false;
                }
            }                        
        } 
        else if (dataType == Enum.Request.DataType.LatLongSearch)
        {
            var lat = $("SearchLat").value;
            if (!this._ValidateDecimalLatitude(lat))
            {
                isValid = false;
            }
            
            var lon = $("SearchLong").value;
            if (!this._ValidateDecimalLongitude(lon))
            {
                isValid = false;
            }
        }
        else if (dataType == Enum.Request.DataType.GeoData)
        {
            if ($("UrlOfRSSFeedRBtn").checked)
            {
                $("UrlGeoRSS").value = $("UrlGeoRSS").value.replace(/^\s+|\s+$/g, '');
                if ($("UrlGeoRSS").value == null || $("UrlGeoRSS").value.length == 0)
                {
                    isValid = false;
                    alert("Please enter a valid URL.");
                }
            }
            else if ($("UrlOfWmsFeedRBtn").checked) {
                if ($("UrlWMS").value == null || $("UrlWMS").value.length == 0) {
                    isValid = false;
                    alert("Please enter a valid URL.");
                }
            }            
            else if ($("SelectRSSFeedRBtn").checked)
            {
                if ($("GeoRSSDDList").value == "-1")
                {
                    isValid = false;
                    alert("Please select a feed.");
                }
            
            }
        }
        else if (dataType == Enum.Request.DataType.Statistics)
        {
            if ($("AvailableStatNameSelect").value == "-1")
            {
                isValid = false;
                alert("Please select which statistics to display.");
            }
        }         
        else if (dataType == Enum.Request.DataType.LocationSearch)
        {
            $("SearchWhere").value = $("SearchWhere").value.replace(/^\s+|\s+$/g, '');
            var location = $("SearchWhere").value;
            if (location == null || location.length == 0)
            {
                isValid = false;
                alert("Please enter a valid location (e.g. country, territory or town).");         
            }
        }                    
        return isValid;
    }
    
    // Validates Date format        
    FormData.prototype._ValidateDate = function(value, name, isRequired, defaultValue)
    {               
        var isValid = false;
        if ( value == null || value == defaultValue || value.length == 0)
        {
            alert(name + " is required.");
        }            
        else
        {
            var regEx = new RegExp("^\\s*([1-9]|0[1-9]|[12][0-9]|3[01])[- /.]([1-9]|0[1-9]|1[012])[- /.](19|20)\\d\\d\\s*$");
            if (!regEx.test(value))
            {
                alert(name + " is not valid. (Please use the format: dd/mm/yyyy).");
            }
            else
            {
                isValid = true;                
            }
        } 
        return isValid;  
    }
    // Validates Longitude format
    FormData.prototype._ValidateDecimalLongitude = function(value)
    {
        var isValid = false;
        var regEx = new RegExp("^\\s*[-]?(180{1}|1{1}[0-7]{1}[0-9]{1}|[0-9]{1}[0-9]{1}|[0-9]{1})([.][0-9]*)?\\s*$");               
        if (!regEx.test(value))
        {
            alert("Longitude is not valid. (Please enter a value in decimal format from -180 to 180).");
        }
        else
        {
            isValid = true;
        }     
        return isValid;
    }
    // Validates Latitude format
    FormData.prototype._ValidateDecimalLatitude = function(value)
    {
        var isValid = false;
        var regEx = new RegExp("^\\s*[-]?(90{1}|[0-8]{1}[0-9]{1}|[0-9]{1})([.][0-9]*)?\\s*$");
        if (!regEx.test(value))
        {
            alert("Latitude is not valid. (Please enter a value in decimal format from -90 to 90).");
        }     
        else
        {
            isValid = true;            
        }
        return isValid;
    }              


    // Map Data
    function MapData()
    {
        // Array of Reuters.Alertnet.WebServices.Models.Storm();
        this.Storms = null;             
    }    

    // Storms class
    function Storm() {
        var _A = 0.9;
        this._colors = [ new VEColor(0, 204, 255, _A),
                       new VEColor(0, 255, 0, _A),
                       new VEColor(255, 255, 0, _A),
                       new VEColor(255, 204, 0, _A),
                       new VEColor(255, 102, 0, _A),
                       new VEColor(255, 0, 0, _A),
                       new VEColor(204, 0, 204, _A)
                     ];  
    }

    Storm.prototype.ShowOnMap = function() {
        var storms = mapData.Storms;

        if (storms == null) {
            return;
        }

        // If there are any shapes -> delete them
        if (cache.MapLayerManager.DoesStormLayerHaveAnyShapes()) {
            cache.MapLayerManager.DeleteGeoStormLayer();
        }

        var layer = cache.MapLayerManager.GetStormLayer();
        var stormIndex = null;
        for (var i = 0; i < storms.length; i++) {

            // Add projections polylines
            if (storms[i].Projections.length > 2) {
                for (var j = 1; j < storms[i].Projections.length; j++) {
                    var prevProj = storms[i].Projections[j - 1];
                    var projection = storms[i].Projections[j];
                    var latlongs = [new VELatLong(prevProj.Lat, prevProj.Lon), new VELatLong(projection.Lat, projection.Lon)];
                    /*if (j == storms[i].Projections.length - 1) {
                    var arrowLine = new ArrowLine();
                    latlongs = arrowLine.GeneratePolylinePointsWithArrow(latlongs);
                    }*/
                    var polyline = new VEShape(VEShapeType.Polyline, latlongs);
                    stormIndex = this._GetStormIndex(prevProj.Peak);
                    polyline.SetLineColor(this._colors[stormIndex]);
                    polyline.HideIcon();                    
                    layer.AddShape(polyline);                    
                }
            }

            // Add an info pushpin
            var lastProj = storms[i].Projections[storms[i].Projections.length - 1];
            var infoPushpin = new VEShape(VEShapeType.Pushpin, new VELatLong(lastProj.Lat, lastProj.Lon));
            var iconPath = IMAGES_URL + "iconStorm" + stormIndex + ".png";
            var icon = "<div><img src='" + iconPath + "'></div>";
            infoPushpin.SetCustomIcon(icon);
            infoPushpin.SetTitle(this._SetTitle(storms[i]));
            infoPushpin.SetDescription(this._SetDescription(storms[i]));
            layer.AddShape(infoPushpin);
        }
    }

    Storm.prototype._GetStormIndex = function(strPeak) {
        var index = null;        
        var peak = parseInt(strPeak);
        if (peak < 63) index = 0;
        else if (peak < 119) index = 1;
        else if (peak < 154) index = 2;
        else if (peak < 178) index = 3;
        else if (peak < 211) index = 4;
        else if (peak < 250) index = 5;
        else if (peak >= 250) index = 6;
        return index;
    }

    Storm.prototype._SetTitle = function(storm)
    {
        var title = "<div class='control'>" + 
                        "<div class='cHeader'>" +
                            "<a href='http://alertnet.org" + storm.Link + "' target='_blank'>" + storm.Title + "</a>" + 
                            "<div class='winClose' onclick='CloseInfoBox()'>" +
                                "<img src='" + IMAGES_URL + "empty15x15.gif' alt='Close' title='Close' />" +                                    
                            "</div>" +
                        "</div>" + 
                    "</div>";
        return title;              
    }

    Storm.prototype._SetDescription = function(storm) {
        var desc = "<div>" + storm.Date.format("dd/MMM/yyyy hh:mm:ss") + "</div>" +
                        "<div class='itemDesc'>" + storm.Desc + "</div>" +
                        "<div><img src='http://alertnet.org" + storm.ImgLink + "'/></div>" +
                        "<div class='itemSource'><span class='label'>Source: </span>" + storm.Source + "</div>";

        // Link
        if (storm.Link != null && storm.Link.length > 0) {
            desc += "<div><a href='http://alertnet.org" + storm.Link + "' target='_blank'>See details...</a></div>";
        }

        // Kml
        if (storm.Kml != null && storm.Kml.length > 0) {
            desc += "<div><a href='#' onclick=\"ShowKmlOnMap('" + item.Kml + "')\">Show on map...</a></div>";
        }
        
        return "<div id='InformationBoxDescription'>" + desc + "</div>";
    }
    
          
    
    // Arrow line Class
    function ArrowLine()
    {
    }

    ArrowLine.prototype.GeneratePolylinePointsWithArrow = function(points)  
    {  
        //last point in polyline array  
        var anchorPoint = points[points.length-1];  
          
        //bearing from last point to second last point in pointline array  
        var bearing = this._CalculateBearing(anchorPoint,points[points.length-2]);  
          
        //length of arrow head lines in km
        var arrowLength = 1 / map.GetZoomLevel() * 500;  
          
        //angle of arrow lines relative to polyline in degrees  
        var arrowAngle = 20;  
          
        //calculate coordinates of arrow tips  
        var arrowPoint1 = this._CalculateCoord(anchorPoint, bearing-arrowAngle, arrowLength);  
        var arrowPoint2 = this._CalculateCoord(anchorPoint, bearing+arrowAngle, arrowLength);  
          
        //go from last point in polyline to one arrow tip, then back to the   
        //last point then to the second arrow tip.  
        points.push(arrowPoint1);  
        points.push(anchorPoint);  
        points.push(arrowPoint2);  
          
        return points;  
    }  
      
    ArrowLine.prototype._DegtoRad = function(x)  
    {  
        return x*Math.PI/180;  
    }  
  
    ArrowLine.prototype._RadtoDeg = function(x)  
    {  
        return x*180/Math.PI;  
    }  
  
    ArrowLine.prototype._CalculateCoord = function(origin, brng, arcLength)  
    {  
        var earthRadius = 6371;
        var lat1 = this._DegtoRad(origin.Latitude);  
        var lon1 = this._DegtoRad(origin.Longitude);  
        var centralAngle = arcLength /earthRadius;  
  
        var lat2 = Math.asin( Math.sin(lat1)*Math.cos(centralAngle) + Math.cos(lat1)*Math.sin(centralAngle)*Math.cos(this._DegtoRad(brng)));  
        var lon2 = lon1+Math.atan2(Math.sin(this._DegtoRad(brng))*Math.sin(centralAngle)*Math.cos(lat1),Math.cos(centralAngle)-Math.sin(lat1)*Math.sin(lat2));  
                      
        return new VELatLong(this._RadtoDeg(lat2),this._RadtoDeg(lon2));  
    }  
  
    ArrowLine.prototype._CalculateBearing = function(A,B)  
    {  
        var lat1 = this._DegtoRad(A.Latitude);  
        var lon1 = A.Longitude;  
        var lat2 = this._DegtoRad(B.Latitude);  
        var lon2 = B.Longitude;  
                  
        var dLon = this._DegtoRad(lon2-lon1);  
                  
        var y = Math.sin(dLon) * Math.cos(lat2);  
        var x = Math.cos(lat1)*Math.sin(lat2) - Math.sin(lat1)*Math.cos(lat2)*Math.cos(dLon);  
  
        var brng = (this._RadtoDeg(Math.atan2(y, x))+360)%360;  
                  
        return brng;  
    }  



// Distance Class
function MeasureDistance(layerIndex, moveIndicatorId) 
{
            
    // Distance Layer Index
    var layerIndex = layerIndex;
    // Shape which signals the current distance
    var moveIndicatorId = moveIndicatorId;
    // Total Distance
    this.TotalDistance = 0;
    // Distance between two latest Points
    this.LatestDistance = 0;
    // Array of point's IDs (pushpin's IDs)
    this.Points = new Array();
    // Status Enum - 0: measuring not started yet, 1: measuring, 2: measuring stopped
    this.Status = Enum.Distance.Status.NotStarted;
        
    // Returns Distance Layer
    this.getDistanceLayer = function() {
        if (layerIndex == -1) {
            map.AddShapeLayer(new VEShapeLayer());    
            layerIndex = map.GetShapeLayerCount() - 1;            
        }  
        return map.GetShapeLayerByIndex(layerIndex); 
    };
            
    // Returns Shape Indicating Current Distance
    this.getMoveIndicator = function() {
        if (moveIndicatorId != -1) {
            return this.getDistanceLayer().GetShapeByID(moveIndicatorId);            
        }
        else {
            return null;        
        }
    };
    
    // Changes the Location of Shape indicating the Current Distance
    this.displayMoveIndicator = function(latlong) {        
        if (this.Points.length > 0) {                     
            if (moveIndicatorId == -1) {
                latlong1 = this.getDistanceLayer().GetShapeByID(this.Points[this.Points.length - 1]).GetPoints()[0];
                moveIndicator = new VEShape(VEShapeType.Polyline, new Array(latlong1, latlong));
                moveIndicator.HideIcon();
                moveIndicator.SetTitle("MoveIndicator");
                this.getDistanceLayer().AddShape(moveIndicator);
                moveIndicatorId = moveIndicator.GetID();
            }
            else {
                this.getMoveIndicator().SetPoints(new Array(latlong1, latlong));    
            }
        }
    };
    
    // Returns distance between two lat/long Points - Haversine formula
    this.countDistance = function(latlong1, latlong2) {
      var lat1 = latlong1.Latitude;
      var lon1 = latlong1.Longitude;
      var lat2 = latlong2.Latitude;
      var lon2 = latlong2.Longitude;
      var earthRadius = 6371; //appxoximate radius
          
      var factor = Math.PI/180;
      var dLat = (lat2-lat1)*factor;
      var dLon = (lon2-lon1)*factor; 
      var a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(lat1*factor) 
        * Math.cos(lat2*factor) * Math.sin(dLon/2) * Math.sin(dLon/2); 
      var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
      var d = earthRadius * c;
      return d;
    };
    
    // Returns Distance Between the Latest Point and the Coordinates passed to the function
    this.GetDistanceBetweenLatestPointAndPoint = function(latlong) {
        if (this.Points.length > 0) {
            latlong1 = this.getDistanceLayer().GetShapeByID(this.Points[this.Points.length - 1]).GetPoints()[0];
            return this.countDistance(latlong1, latlong);
        } 
        else {
            return null;
        }    
    }
    
    // Draws Line Between Two Latest Points
    this.drawLineBetweenTwoLatestPoints = function(latlong1, latlong2, veColor) {        
        var polyLine = new VEShape(VEShapeType.Polyline, new Array(latlong1, latlong2));        
        polyLine.HideIcon();
        if (veColor != null) {
            polyLine.SetLineColor(veColor);
        }
        this.getDistanceLayer().AddShape(polyLine);
    };  
    
    // Adds Point (Pushpin shape) to Distance Layer, Updates Distances and Displayes Connection Line     
    this.addPoint = function(latlong) {
        // Create Pushpin and Place it on DistanceLayer
        var point = new VEShape(VEShapeType.Pushpin, latlong);
        this.getDistanceLayer().AddShape(point);
        this.Points.push(point.GetID());           
        var iconPath = IMAGES_URL + "iconPushpinRed.gif";
        var icon = "<img class='iconPushpin' src='" + iconPath + "'><span class='pinText'>" + this.Points.length + "</span>";
        point.SetCustomIcon(icon);
        
        if (this.Points.length > 1) {
            // Update this.LatestDistance and this.TotalDistance
            latlong1 = this.getDistanceLayer().GetShapeByID(this.Points[this.Points.length - 1]).GetPoints()[0];
            latlong2 = this.getDistanceLayer().GetShapeByID(this.Points[this.Points.length - 2]).GetPoints()[0];
            this.LatestDistance = this.countDistance(latlong2, latlong1);
            this.TotalDistance += this.LatestDistance;        
            // Draw PolyLine
            this.drawLineBetweenTwoLatestPoints(latlong2, latlong1, null);
        }
        // Set Status - Measuring Started
        this.Status = Enum.Distance.Status.Started;
    };    
    
    // Returns LatestDistance formated into a string
    this.ConvertDistanceToString = function(valKm, unitEnum, formatEnum) {
        if (unitEnum == Enum.Distance.Unit.Kilometers) {        
            if (formatEnum == Enum.Distance.UnitDisplayFormat.OneDecimalvalKmue)
                return Math.floor(valKm) + "." + Math.floor((valKm - Math.floor(valKm)) * 10) +  "Km ";
            else
                return Math.floor(valKm) + "Km " + Math.floor((valKm - Math.floor(valKm)) * 1000) + "m";            
        }
        else {
            var valMi = valKm / 1.609;
            if (formatEnum == Enum.Distance.UnitDisplayFormat.OneDecimalvalKmue)
                return Math.floor(valMi) + "." + Math.floor((valMi - Math.floor(valMi)) * 10) +  "Mi ";
            else
                return Math.floor(valMi) + "Mi " + Math.floor((valMi - Math.floor(valMi)) * 1760) + "Yr";            
        }
    };
    
    // Reset 
    this.Reset = function() {
        map.DeleteShapeLayer(this.getDistanceLayer());
        moveIndicatorId = -1; 
        layerIndex = -1; 
        this.Status = Enum.Distance.Status.NotStarted;
        this.LatestDistance = 0;
        this.TotalDistance = 0;
        this.Points = new Array();
    };
    
    // Stop Measuring Distance
    this.StopMeasuring = function() {
        this.Status = Enum.Distance.Status.Stopped;
        this.getDistanceLayer().DeleteShape(this.getMoveIndicator());
    };   
}   

function AvailableStats()
    {
        // It is an array of Reuters.Alertnet.WebServices.Models.AvailableStatistic objects
        this.Data = null;
        this.IsInitialized = false;
    }
    
    // Populates Statistic Name and Year DropDownLists
    AvailableStats.prototype.InitializeDropDownLists = function()
    {
        if (!this.IsInitialized)
        {
            if (this.Data == null) {
                this._RequestAvailableStats()        
            }
            else {
                this._PopulateStatisticNameDropDownList();
                this._PopulateStatisticYearDropDownList(this.Data[0].Code);
                this.IsInitialized = true;
            }
        }    
    }
    
    // OnAvailableNameStatisticChange -> repopulate years dropdownlist for the selected statistic
    AvailableStats.prototype.OnAvailableStatisticNameChanged = function()
    {
            var code = $("AvailableStatNameSelect").value;                          
            this._PopulateStatisticYearDropDownList(code);        
    }
    
    // Makes a requests to a webservice for data   
    AvailableStats.prototype._RequestAvailableStats = function()
    {
        if (this.Data == null)
        {
            var mustBeThere = null;
            Reuters.Alertnet.WebServices.MapDataService.set_path(WEBSERVICE_RELATIVE_URI);
            Reuters.Alertnet.WebServices.MapDataService.GetAvailableStatistics(mustBeThere, this._OnSuccess, this._OnFailed, this);
        }    
    }
    
    // OnSuccess    
    AvailableStats.prototype._OnSuccess = function(arg, thisObject)
    {
        if (arg != null && arg.length > 0)
        {
            thisObject.Data = arg;     
            thisObject.InitializeDropDownLists();
        }                    
    }
    
    // OnFailed   
    AvailableStats.prototype._OnFailed = function(arg)
    {    
        alert("Warning: Failed to retrieve available statistics.");
    }        
    
    // Pupulates Statistic Name DropDownList    
    AvailableStats.prototype._PopulateStatisticNameDropDownList = function()
    {       
        if (this.Data != null)
        {     
            $("AvailableStatNameSelect").innerHTML = "";  
            
            // Place '-- please select --' at the first position
            var defaultOption = document.createElement("option");
            defaultOption.setAttribute('value', '-1');    
            defaultOption.innerHTML = "-- Please select --";
            $("AvailableStatNameSelect").appendChild(defaultOption);
                         
            this.Data.each(function(availableStat)
                {
                    var name = availableStat.Name;           
                    var code = availableStat.Code;
                    var newEl = document.createElement("option");
                    newEl.setAttribute('value', code);    
                    newEl.innerHTML = name;                                                        
                    $("AvailableStatNameSelect").appendChild(newEl);
                });         
        }
    }
    
    // Pupulates Statistic Year DropDownList    
    AvailableStats.prototype._PopulateStatisticYearDropDownList = function(code)
    {       
        function contains(obj, prop, value) {
            var propertyValue = (obj[prop]) ? obj[prop] : null;
            return value==propertyValue;
        }                       
        
        // Returns an AvailableStat object for the code
        var availableStat = this.Data.findAll(
                function(obj) { return contains(obj, "Code", code); }
            )[0];    
            
        // Populates the dropdownlist    
        if (availableStat != null)
        {     
            $("AvailableStatYearSelect").innerHTML = "";
            
            // Place '-- please select --' at the first position
//            var defaultOption = document.createElement("option");
//            defaultOption.setAttribute('value', '-1');    
//            defaultOption.innerHTML = "-- Please select --";
//            $("AvailableStatYearSelect").appendChild(defaultOption);            
                        
            availableStat.Years.each(function(year)
                {
                    var name = availableStat.Name;           
                    var code = availableStat.Code;
                    var newEl = document.createElement("option");
                    newEl.setAttribute('value', year);    
                    newEl.innerHTML = year;                                                        
                    $("AvailableStatYearSelect").appendChild(newEl);
                }); 
        }
    } 
   
function AvailableSources()
    {
        // It is an array of Reuters.Alertnet.WebServices.Models.AvailableSource objects
        this.Data = null;
        this.IsInitialized = false;
    }
    
    // Populates Source Name and Year DropDownLists
    AvailableSources.prototype.InitializeDropDownList = function()
    {
        if (!this.IsInitialized)
        {
            if (this.Data == null) {
                this._RequestAvailableSources()        
            }
            else {
                this._PopulateSourceNameDropDownList();
                this.IsInitialized = true;
            }
        }    
    }   
    
    // Makes a requests to a webservice for data   
    AvailableSources.prototype._RequestAvailableSources = function()
    {
        if (this.Data == null)
        {
            var mustBeThere = null;
            Reuters.Alertnet.WebServices.MapDataService.set_path(WEBSERVICE_RELATIVE_URI);
            Reuters.Alertnet.WebServices.MapDataService.GetAvailableSources(mustBeThere, this._OnSuccess, this._OnFailed, this);
        }    
    }
    
    // OnSuccess    
    AvailableSources.prototype._OnSuccess = function(arg, thisObject)
    {
        if (arg != null && arg.length > 0)
        {
            thisObject.Data = arg;     
            thisObject.InitializeDropDownList();
        }                    
    }
    
    // OnFailed   
    AvailableSources.prototype._OnFailed = function(arg)
    {                    
    }        
    
    // Pupulates Source Name DropDownList    
    AvailableSources.prototype._PopulateSourceNameDropDownList = function()
    {       
        if (this.Data != null)
        {     
            $("SourceNameSelect").innerHTML = "";  
            
            // Place '-- please select --' at the first position
            var defaultOption = document.createElement("option");
            defaultOption.setAttribute('value', '-1');    
            defaultOption.innerHTML = "-- Please select --";
            $("SourceNameSelect").appendChild(defaultOption);
                         
            this.Data.each(function(availableSource)
                {
                    var name = availableSource.Name;           
                    var code = availableSource.Code;
                    var newEl = document.createElement("option");
                    newEl.setAttribute('value', code);    
                    newEl.innerHTML = name;                                                        
                    $("SourceNameSelect").appendChild(newEl);
                });         
        }
    }
    
function MapSources()
    {
        // It is an array of Reuters.Alertnet.WebServices.Models.AvailableSource objects
        this.Data = null;
        this.IsInitialized = false;
    }
    
    // Populates Source Name and Year DropDownLists
    MapSources.prototype.InitializeDropDownList = function()
    {
        if (!this.IsInitialized)
        {
            if (this.Data == null) {
                this._RequestMapSources()        
            }
            else {
                this._PopulateSourceNameDropDownList();
                this.IsInitialized = true;
            }
        }    
    }   
    
    // Makes a requests to a webservice for data   
    MapSources.prototype._RequestMapSources = function()
    {
        if (this.Data == null)
        {
            var mustBeThere = null;
            Reuters.Alertnet.WebServices.MapDataService.set_path(WEBSERVICE_RELATIVE_URI);
            Reuters.Alertnet.WebServices.MapDataService.GetMapSources(mustBeThere, this._OnSuccess, this._OnFailed, this);
        }    
    }
    
    // OnSuccess    
    MapSources.prototype._OnSuccess = function(arg, thisObject)
    {
        if (arg != null && arg.length > 0)
        {
            thisObject.Data = arg;     
            thisObject.InitializeDropDownList();
        }                    
    }
    
    // OnFailed   
    MapSources.prototype._OnFailed = function(arg)
    {                    
    }        
    
    // Pupulates Source Name DropDownList    
    MapSources.prototype._PopulateSourceNameDropDownList = function()
    {       
        if (this.Data != null)
        {     
            $("MapSourceNameSelect").innerHTML = "";  
            
            // Place '-- please select --' at the first position
            var defaultOption = document.createElement("option");
            defaultOption.setAttribute('value', '-1');    
            defaultOption.innerHTML = "-- Please select --";
            $("MapSourceNameSelect").appendChild(defaultOption);
                         
            this.Data.each(function(availableSource)
                {
                    var name = availableSource.Name;           
                    var code = availableSource.Code;
                    var newEl = document.createElement("option");
                    newEl.setAttribute('value', code);    
                    newEl.innerHTML = name;                                                        
                    $("MapSourceNameSelect").appendChild(newEl);
                });         
        }
    }    
    
function AidAgencySources()
    {
        // It is an array of Reuters.Alertnet.WebServices.Models.AidAgencySource objects
        this.Data = null;
        this.IsInitialized = false;
    }
    
    // Populates Source Name and Year DropDownLists
    AidAgencySources.prototype.InitializeDropDownList = function()
    {
        if (!this.IsInitialized)
        {
            if (this.Data == null) {
                this._RequestAidAgencySources()        
            }
            else {
                this._PopulateSourceNameDropDownList();
                this.IsInitialized = true;
            }
        }    
    }   
    
    // Makes a requests to a webservice for data   
    AidAgencySources.prototype._RequestAidAgencySources = function()
    {
        if (this.Data == null)
        {
            var mustBeThere = null;
            Reuters.Alertnet.WebServices.MapDataService.set_path(WEBSERVICE_RELATIVE_URI);
            Reuters.Alertnet.WebServices.MapDataService.GetAidAgencySources(mustBeThere, this._OnSuccess, this._OnFailed, this);
        }    
    }
    
    // OnSuccess    
    AidAgencySources.prototype._OnSuccess = function(arg, thisObject)
    {
        if (arg != null && arg.length > 0)
        {
            thisObject.Data = arg;     
            thisObject.InitializeDropDownList();
        }                    
    }
    
    // OnFailed   
    AidAgencySources.prototype._OnFailed = function(arg)
    {                    
    }        
    
    // Pupulates Source Name DropDownList    
    AidAgencySources.prototype._PopulateSourceNameDropDownList = function()
    {       
        if (this.Data != null)
        {     
            $("AidAgencySourceNameSelect").innerHTML = "";  
            
            // Place '-- please select --' at the first position
            var defaultOption = document.createElement("option");
            defaultOption.setAttribute('value', '-1');    
            defaultOption.innerHTML = "-- Please select --";
            $("AidAgencySourceNameSelect").appendChild(defaultOption);
                         
            this.Data.each(function(availableSource)
                {
                    var name = availableSource.Name;           
                    var code = availableSource.Code;
                    var newEl = document.createElement("option");
                    newEl.setAttribute('value', code);    
                    newEl.innerHTML = name;                                                        
                    $("AidAgencySourceNameSelect").appendChild(newEl);
                });         
        }
    }

    function GeoDataDropDownListItem() {
        // It is an array of Reuters.Alertnet.WebServices.Models.AvailableSource objects
        this.Data = null;
        this.IsInitialized = false;
    }

    // Populates Source Name and Year DropDownLists
    GeoDataDropDownListItem.prototype.InitializeDropDownList = function() {
        if (!this.IsInitialized) {
            if (this.Data == null) {
                this._RequestGeoDataDropDownListItems()
            }
            else {
                this._PopulateGeoDataDropDownList();
                this.IsInitialized = true;
            }
        }
    }

    // Makes a requests to a webservice for data
    GeoDataDropDownListItem.prototype._RequestGeoDataDropDownListItems = function() {
        if (this.Data == null) {
            var mustBeThere = null;
            Reuters.Alertnet.WebServices.MapDataService.set_path(WEBSERVICE_RELATIVE_URI);
            Reuters.Alertnet.WebServices.MapDataService.GetGeoDataDropDownListItems(mustBeThere, this._OnSuccess, this._OnFailed, this);
        }
    }

    // OnSuccess
    GeoDataDropDownListItem.prototype._OnSuccess = function(arg, thisObject) {
        if (arg != null && arg.length > 0) {
            thisObject.Data = arg;
            thisObject.InitializeDropDownList();
        }
    }

    // OnFailed
    GeoDataDropDownListItem.prototype._OnFailed = function(arg) {
    }

    // Pupulates Source Name DropDownList
    GeoDataDropDownListItem.prototype._PopulateGeoDataDropDownList = function() {
        if (this.Data != null) {
            $("GeoRSSDDList").innerHTML = "";

            // Place '-- please select --' at the first position
            var defaultOption = document.createElement("option");
            defaultOption.setAttribute('value', '-1');
            defaultOption.innerHTML = "-- Please select --";
            $("GeoRSSDDList").appendChild(defaultOption);

            this.Data.each(function(geoDataItem) {
                var name = geoDataItem.Name;
                var value = geoDataItem.Value;
                var newEl = document.createElement("option");
                newEl.setAttribute('value', value);
                newEl.innerHTML = name;
                $("GeoRSSDDList").appendChild(newEl);
            });
        }
    }

function Help() {
        this.isInitialized = false;
    }

    // Populates Help div
    Help.prototype.Initialize = function() {
        if (!this.IsInitialized) {
            this._RequestHelpData()
        }
    }

    // Makes a requests to a webservice for data
    Help.prototype._RequestHelpData = function() {
        var mustBeThere = null;
        Reuters.Alertnet.WebServices.MapDataService.set_path(WEBSERVICE_RELATIVE_URI);
        Reuters.Alertnet.WebServices.MapDataService.GetHelp(mustBeThere, this._OnSuccess, this._OnFailed, this);
    }

    // OnSuccess
    Help.prototype._OnSuccess = function(arg, thisObject) {
        if (arg != null && arg.length > 0) {
            this.isInitialized = true;
            $("HelpContentDiv").innerHTML = arg[0];
            $("HelpNavigatorDiv").innerHTML = arg[1];
        }
    }

    // OnFailed   
    AidAgencySources.prototype._OnFailed = function(arg) {
    }     
    
    
    
         
function StatusBar()
    {
        this._IsLoading = false;
        this._IsStatusMsg = false;
        this._IsTooltip = false;
        this._IsLegend = false;   
        this._TimeStatusMsg = null;             
        this._TimeTooltip = null;
    }
    // Loading
    StatusBar.prototype.ShowLoading = function()
    {
        this._IsLoading = true;
        this._Show();      
    }    
    StatusBar.prototype.HideLoading = function(force)
    {
        if (requestManager.AreAllRequestsDone() || force)
        {
            this._IsLoading = false;
            $("LoadingDiv").hide();
            this._Show();
        }          
    }
    // Legend
    StatusBar.prototype.ShowLegend = function()
    {
        this._IsLegend = true;
        this._Show();
    }    
    StatusBar.prototype.HideLegend = function()
    {
        this._IsLegend = false;
        $("LegendDiv").hide();  
        this._Show();    
    }            
    // Status Msg
    StatusBar.prototype.ShowStatusMessage = function(msg, timeInMs)
    { 
        this._IsStatusMsg = true;
        this._TimeStatusMsg = timeInMs;
        if ($("StatusDiv").innerHTML.length > 0)
        {
            $("StatusDiv").innerHTML += " " + msg;
        }
        else
        {
            $("StatusDiv").innerHTML = msg;
        }    
        this._Show();        
    }    
    StatusBar.prototype.HideStatusMessage = function()
    {
        this._IsStatusMsg = false;
        $("StatusDiv").innerHTML = "";
        $("StatusDiv").hide(); 
        this._TimeStatusMsg = null; 
        this._Show();   
    }
    // Tooltip 
    StatusBar.prototype.ShowTooltip = function(msg, timeInMs)
    {    
        this._IsTooltip = true;   
        this._TimeTooltip = timeInMs;        
        $("TooltipDiv").innerHTML = msg;
        this._Show();                
    }                    
    StatusBar.prototype.HideTooltip = function()
    {
        this._IsTooltip = false;
        this._TimeTooltip = null;
        $("TooltipDiv").hide();  
        this._Show();
    }
    StatusBar.prototype.ClearAllMsgs = function()
    {
        this.HideLoading();
        this.HideStatusMessage();
        this.HideTooltip();
        this.HideLegend();        
    }
    StatusBar.prototype._Show = function()
    {
        if (this._IsLoading)
        {
            $("LoadingDiv").show();
            $("StatusDiv").hide();
            $("TooltipDiv").hide();
            $("LegendDiv").hide();
        }
        else if (this._IsStatusMsg)
        {
            $("StatusDiv").show();                                    
            $("LegendDiv").hide();
            $("TooltipDiv").hide();
            if (this._TimeStatusMsg != null)
            {
                setTimeout("statusBar.HideStatusMessage()", this._TimeStatusMsg);
            }             
        }
        else if (this._IsTooltip)
        {
            $("TooltipDiv").show();                                   
            $("LegendDiv").hide();
            if (this._TimeTooltip != null)
            {
                setTimeout("statusBar.HideTooltip()", this._TimeTooltip);
            }            
        }
        else if (this._IsLegend)
        {
            $("LegendDiv").show();
        }    
    }  
    

    

/* MAP FUNCTIONS         
 **********************************************************************************************/
 
// Loads the main object (Bing Map Object)        
function LoadMap() 
{                
    // Adjust a height of MainDiv to its right value (IE6, FooterDiv has top -27 => makes MainDiv 27px heigher)
    // Must be placed before VEMap is laoded !!!
    $("MapContainerDiv").style.height = $("MapContainerDiv").offsetHeight - $("FooterDiv").offsetHeight + "px";

    // set a size of a MapDiv before loading a map
    var width = $("MapContainerDiv").offsetWidth;
    var height = $("MapContainerDiv").offsetHeight;
    $("MapDiv").style.width = width + "px";
    $("MapDiv").style.height = height + "px";
        
    map = new VEMap("MapDiv");    
    
    qs.Initialize();
    var center = qs.GetVELatLongMapCenter();
    var zoom = qs.GetZoomLevel();
    
    if (center == null) {
        center = new VELatLong(DEFAULT_LAT, DEFAULT_LONG);
    }    
    if (zoom == null) {
        zoom = DEFAULT_ZOOM;
    }

    // load map
    map.LoadMap(center, zoom, 'h', false);
            
    $("LogoDiv").style.display = "block";
        
    OnLoad();                       
}   

// OnLoad 
function OnLoad() {    
    // MapDiv_OnResize();
    // shapes are drawn correctly - country polygons follow exactly the borders
    map.EnableShapeDisplayThreshold(false);         
    
    // Attach Event Events to Handlers
    map.AttachEvent("onmouseover", MouseEventHandler);
    map.AttachEvent("onmouseout", MouseEventHandler);    
    map.AttachEvent("onclick", MouseEventHandler);
    map.AttachEvent("ondoubleclick", MouseEventHandler);
    map.AttachEvent("onmousemove", MouseEventHandler);
    map.AttachEvent("onendpan", MouseEventHandler);
    map.AttachEvent("onendzoom", MouseEventHandler);

    // reset user controls (checkboxes, selects, text fields..)
    ResetMapBtn_OnClick()
    // if query string contains data info => make data request
    qs.SetMapControls();
    // Setting control's values
    userSettings.SetToolSettingsFromCookie();

    // Default view to show latest news for the past 24 hours
    // If there was no requests made => make a default request    
    if (requestManager.LatestId == 0) {
        ActivateControl({ 'Header': 'NewsH', 'Container': 'NewsC' });
        $("NewsChBox").checked = true;
        ShowSourceChBox();
        $("TimePeriodChBox").checked = true;
        TimePeriodChBox_Click();
        $("LatestNewsSelect").selectedIndex = "3";
    
        isNewRequest = true;
        var data = new Object();
        data.ContentItem = true;
        data.News = true;
        data.LatestHours = 24;
        requestManager.AddServerRequest(data)
        requestManager.SendAllRequests();
    }
        
    // Initialize Map Controls
    ScaleBarChBox_OnClick();
    MiniMapChBox_OnClick();
    LatLongChBox_OnClick();
    MeasureDistanceChBox_OnClick();
    ResultsChBox_OnClick();
    DateChBox_Click();
    TimePeriodChBox_Click();
    ShowSourceChBox();
    SourceChBox_OnClick();        
    
    // Is Map Update Required?
    if (qs.DataUpdate) {
        UpdateMapBtn_OnClick( { IsRefresh: true, IsNew: true } );
    } 
    
    // Populate Available Statistics, Available Sources and Available Aid Agency Sources from webservices
    availableStats.InitializeDropDownLists();
    
    var availableSources = new AvailableSources();
    availableSources.InitializeDropDownList();   
    
    var mapSources = new MapSources();
    mapSources.InitializeDropDownList();   
    
    var aidAgencySources = new AidAgencySources();    
    aidAgencySources.InitializeDropDownList();

    var geoDataItem = new GeoDataDropDownListItem();
    geoDataItem.InitializeDropDownList();

    var help = new Help();
    help.Initialize();
    
}

// Mouse Handlers
function MouseEventHandler(e)
{     
    if (e.eventName == "ondoubleclick") {
        if ($("MeasureDistanceChBox").checked) {
                MeasureDistanceStopOrClear(e);            
        }    
        // Do not process any other event handlers => return true                
        return true;
    }                          
    if (e.eventName == "onclick") {                        
        if ($("MeasureDistanceChBox").checked) {
            if (e.leftMouseButton) {
                MeasureDistanceStartOrPlaceMark(e);
            } 
            if (e.rightMouseButton) {
                MeasureDistanceStopOrClear(e);
            }                                
        }
        else {
            // Show PopUp with info about a shape
            if(e.elementID != null) {
                var shape = map.GetShapeByID(e.elementID);
                if (shape != null) {
                    if (shape.GetType() == VEShapeType.Pushpin || shape.GetType() == VEShapeType.Polyline) {
                        return false;
                    }
                    var latLong = map.PixelToLatLong(new VEPixel(e.mapX, e.mapY));
                    cache.CountryData.ShowInfoBox(shape, latLong);
                }
            }    
        }                
    }                     
    if (e.eventName == "onmouseover") { 
        // Change Cursor - Mouseover a Shape
        if(e.elementID != null) {
            $(e.elementID).style.cursor = "pointer";
        }            
    }        
    if (e.eventName == "onmouseout") {
    }    
    if (e.eventName == "onmousemove") {
        // Display Lat / Long sensor
        if ($("LatLongChBox").checked) {            
            ShowLatLong(e);
        }
        // Display Circle while measuring distance           
        if ($("MeasureDistanceChBox").checked) {
            MeasureDistanceOnMove(e);                                   
        }        
    }
    if (e.eventName == "onendpan") {
        UpdateMapBtn_OnClick( { IsRefresh: false, IsNew: false } );
    } 
    if (e.eventName == "onendzoom") {
        UpdateMapBtn_OnClick( { IsRefresh: true, IsNew: false } );
    } 
}

/* General Methods
**********************************************************************************************/

/* Map Handlers
**********************************************************************************************/


/*** Help Div 
/************************************/
// Expands a navigator menu (shows subitems)
function ExpandHelpNavigatorItem(id, expandIt) {
    // Should a navigator item be expanded?
    if (expandIt == null) {
        if ($("HelpNavigator" + id).hasClassName("expanded")) {
            expandIt = false;
        }
        else {
            expandIt = true;
        }
    }

    // Indicate that the div is expanded by adding expanded css class
    // Change an image in front of the navigator item (+, -)
    if (expandIt) {
        $("HelpNavigator" + id).addClassName("expanded");
        if ($("HelpNavImg" + id) != null) {
            $("HelpNavImg" + id).src = "Content/Images/helpmenuminus.png";
        }
    }
    else {
        $("HelpNavigator" + id).removeClassName("expanded");
        if ($("HelpNavImg" + id) != null) {
            $("HelpNavImg" + id).src = "Content/Images/helpmenuplus.png";
        }        
    }
    
    // Show the child navigator divs
    $("HelpNavigator" + id).childElements().each(function(chElement) {
    if (chElement.nodeName.toLowerCase() == "div" && chElement.id.length - 13 == id.toString().length + 1) { // length of HelpNavigator is 13
            if (expandIt) {
                chElement.style.display = "block";
            }
            else {
                chElement.style.display = "none";
            }
        }
    });
}

// Shows the appropriate help content depending on the selection (from navigator menu or from a link inside a content)
function ShowHelpContent(id) {
    if ($("HelpNavigatorDiv").descendants().length > 0) {

        // Is Help panel visible?
        if (!$("HelpMapDiv").visible()) {
            $("HelpMapDiv").show();
        }

        // clear highlights from navigator items
        $("HelpNavigatorDiv").descendants().each(function(chElement) {
            if (chElement.nodeName.toLowerCase() == "span" && chElement.hasClassName("activeText")) {
                chElement.removeClassName("activeText");
            }
        });

        // highlight a selected item's text
        $("NavText" + id).addClassName("activeText");

        // hide all content divs
        $("HelpContentDiv").childElements().each(function(chElement) {
            if (chElement.nodeName.toLowerCase() == "div" && chElement.id.substr(0, 11) == "HelpContent") {
                chElement.style.display = "none";
            }
        });
        // show content div with id
        $("HelpContent" + id).style.display = "block";

        // make sore a navigator item is visible
        strId = id.toString();
        for (var i = 1; i <= strId.length; i++) {
            ExpandHelpNavigatorItem(strId.substr(0, i), true);
        }
    }
    else {
        alert("Help is not available");
    }
}


// When a browser window is resized -> resize the map
function MapDiv_OnResize() 
{
//var div = $("MapDiv");
//var width = $("MapContainerDiv").offsetWidth;
//var height = $("MapContainerDiv").offsetHeight;
//map.Resize(width, height);
////$("MapResultsContentDiv").style.height = div.clientHeight-60;
//    
//// If a minimap is displayed and a page is resize than the minimap needs to be repositioned
//MiniMapChBox_OnClick("DisableCookie");
}

/* Tools
************/

function LatLongU1RBtn_Click() {
    userSettings.ChangeCookieSettings(Enum.QsParams.LatLonSensor, Enum.QsParams.latLonSensor.DMSUnit);
    LatLongChBox_OnClick();
}

function LatLongU2RBtn_Click() {
    userSettings.ChangeCookieSettings(Enum.QsParams.LatLonSensor, Enum.QsParams.latLonSensor.DecimalUnit);
    LatLongChBox_OnClick();
}

function LatLongPointerChBox_Click(chBox) {
    if (chBox.checked) {
        userSettings.ChangeCookieSettings(Enum.QsParams.LLNextToPointer, Enum.QsParams.lLNextToPointer.TurnOn);
    } else {
        userSettings.ChangeCookieSettings(Enum.QsParams.LLNextToPointer, Enum.QsParams.lLNextToPointer.TurnOff);
    }
    LatLongChBox_OnClick();
}

// Shows and Hides Lat / Long Sensor (UI method)
function LatLongChBox_OnClick(allow)
{
    if (allow != null)
    {
        $("LatLongChBox").checked = allow;
    }

    if ($("LatLongChBox").checked) 
    {
        $("LatLongDiv").show();
        ShowLatLongSensorPanel(true);        
    }        
    else 
    {
        ShowLatLongSensorPanel(false);
    }    
}                          
// Updates (displayes) coordinates of a current cursor position
function ShowLatLong(e)
{
    var x = e.mapX;
    var y = e.mapY;
    pixel = new VEPixel(x, y);
    latLong = map.PixelToLatLong(pixel);                 
    if ($("LatLongU1RBtn").checked) {
        $("LongLabel").innerHTML = ConvertCoordinate(latLong.Longitude, (latLong.Longitude < 0) ? " W" : " E");
        $("LatLabel").innerHTML = ConvertCoordinate(latLong.Latitude, (latLong.Latitude < 0) ? " S" : " N");        
    } 
    else {
        var strLat = new String(latLong.Longitude);
        var strLong = new String(latLong.Latitude);
        $("LongLabel").innerHTML = strLat.substr(0, 12);
        $("LatLabel").innerHTML = strLong.substr(0, 12);           
    } 
    $("LatPointerValue").innerHTML = $("LatLabel").innerHTML;
    $("LonPointerValue").innerHTML = $("LongLabel").innerHTML;
    $("NextToPointerDiv").style.left = x+10 + "px";
    $("NextToPointerDiv").style.top = y+10 + "px";
    //$("MapDiv").style.cursor = "default";
       
}

// Shows / Hides measure latlong sensor tool (includes next to pointer div)
function ShowLatLongSensorPanel(show)
{
    if (show)
    {
        $("LatLongDiv").show();
        // Next To Pointer Div?
        if ($("LatLongPointerChBox").checked)
        {  
            $("NextToPointerDiv").show();
            $("NextToPointerLatLongDiv").show();
            // DistanceNextToPointer?          
            if ($("MeasureDistanceChBox").checked && $("DistancePointerChBox").checked) {
            
                $("NextToPointerDiv").className = "both";
                $("NextToPointerLatLongDiv").style.top = "0px";     
            }
            else {                  
                $("NextToPointerDiv").className = "latlong";             
                $("NextToPointerLatLongDiv").style.top = "14px";
            } 
        }
        else
        {
            // Hide Next To pointer           
            $("NextToPointerLatLongDiv").hide();
            // DistanceNextToPointer?          
            if ($("MeasureDistanceChBox").checked && $("DistancePointerChBox").checked) {
                // Display just DistanceNextToPointer
                $("NextToPointerDiv").className = "distance";    
            }
            else {  
                // Hide whole Next To Pointer div
                $("NextToPointerDiv").hide();             
            }        
        }         
    }
    else
    {
        // Hide Measure Distance Tool
        $("LatLongDiv").hide();
        // Next To Pointer Div?
        if ($("LatLongPointerChBox").checked)
        {   
            // Hide Next To pointer           
            $("NextToPointerLatLongDiv").hide();
            // DistanceNextToPointer?          
            if ($("MeasureDistanceChBox").checked && $("DistancePointerChBox").checked) {
                // Display just DistanceNextToPointer
                $("NextToPointerDiv").className = "distance";    
            }
            else {  
                // Hide whole Next To Pointer div
                $("NextToPointerDiv").hide();             
            } 
        }       
    }
}

// Measure distance unit - set cookie
function DistanceKmRBtn_Click() {
    userSettings.ChangeCookieSettings(Enum.QsParams.DistanceMeasure, Enum.QsParams.distanceMeasure.Kilometers);
}
// Measure distance unit - set cookie
function DistanceMiRBtn_Click() {
    userSettings.ChangeCookieSettings(Enum.QsParams.DistanceMeasure, Enum.QsParams.distanceMeasure.Miles);
}

// Measure distance - NextToPointer panel
function DistancePointerChBox_Click(chBox) {
    if (chBox.checked) {
        userSettings.ChangeCookieSettings(Enum.QsParams.DistanceNextToPointer, Enum.QsParams.distanceNextToPointer.TurnOn);
    }
    else {
        userSettings.ChangeCookieSettings(Enum.QsParams.DistanceNextToPointer, Enum.QsParams.distanceNextToPointer.TurnOff);
    }
    MeasureDistanceChBox_OnClick();
}


// Hides / shows Measure Distance Next To Pointer Div
function ShowMeasureDistanceNextToPointerDiv(show)
{
    var previousValue = null;
    if (show != null)
    {
        previousValue = $("DistancePointerChBox").checked;
        $("DistancePointerChBox").checked = show;
    }

    if ($("MeasureDistanceChBox").checked)
    {
        if ($("DistancePointerChBox").checked)
        {
            $("NextToPointerDiv").show();
            $("NextToPointerDistanceDiv").show();
            // LatLongNextToPointer?          
            if ($("LatLongChBox").checked && $("LatLongPointerChBox").checked) {
                $("NextToPointerDiv").className = "both";    
            }
            else {  
                $("NextToPointerDiv").className = "distance";             
            } 
        }
        else
        {
            // Hide Next To pointer and Clear total distance value
            $("NextToPointerDistanceDiv").hide();
            $("DistancePointerValue").innerHTML == "";
            // LatLongNextToPointer?          
            if ($("LatLongChBox").checked && $("LatLongPointerChBox").checked) {
                // Display just LatLongNextToPointer
                $("NextToPointerDiv").className = "latlong";    
            }
            else {  
                // Hide whole Next To Pointer div
                $("NextToPointerDiv").hide();             
            } 
        }
    }
    else
    {
        // Hide Next To pointer and Clear total distance value
        $("NextToPointerDistanceDiv").hide();
        $("DistancePointerValue").innerHTML == "";
        // LatLongNextToPointer?          
        if ($("LatLongChBox").checked && $("LatLongPointerChBox").checked) {
            // Display just LatLongNextToPointer
            $("NextToPointerDiv").className = "latlong";    
        }
        else {  
            // Hide whole Next To Pointer div
            $("NextToPointerDiv").hide();             
        }     
    }
    
    if (previousValue != null)
    {
        $("DistancePointerChBox").checked = previousValue;
    }
}        


// Shows / Hides measure distance tool (includes next to pointer div)
function ShowMeasureDistancePanel(show)
{
    if (show)
    {
        $("MeasureDistanceDiv").show();
        // Next To Pointer Div
        ShowMeasureDistanceNextToPointerDiv();
    }
    else
    {
        // Hide Measure Distance Tool
        $("MeasureDistanceDiv").hide();
        // Next To Pointer Div
        ShowMeasureDistanceNextToPointerDiv();      
    }
}

// Displayes / Hides Measure Distance Tool
function MeasureDistanceChBox_OnClick(allow)
{
    if (allow != null)
    {
        $("MeasureDistanceChBox").checked = allow;
    }
    // Display / Hide MeasureDistanceDiv on Map
    if ($("MeasureDistanceChBox").checked) {
        statusBar.ShowTooltip("Please click on the <b>left button</b> to start measuring and to place a mark on the map. Click on the <b>right button</b> to stop measuring. Click on the <b>right button</b> again to clear results.");
        ShowMeasureDistancePanel(true);
    } else {
        statusBar.HideTooltip();
        ShowMeasureDistancePanel(false);               
        distanceObject.Reset();             
    }    
}

// When Mesure Distance is Active - OnRight Click Handler - Place Pushpin
function MeasureDistanceStartOrPlaceMark(e) 
{
    // Show Next To Pointer Div
    ShowMeasureDistanceNextToPointerDiv();        
    // Display Point on the Map    
    if (distanceObject.Status != Enum.Distance.Status.Stopped) {                         
        latLong = map.PixelToLatLong(new VEPixel(e.mapX, e.mapY));
        distanceObject.addPoint(latLong);
        if ($("DistanceKmRBtn").checked) {
            $("TotalDistanceDiv").innerHTML = distanceObject.ConvertDistanceToString(distanceObject.TotalDistance, Enum.Distance.Unit.Kilometers, Enum.Distance.UnitDisplayFormat.OneDecimalValue);
            $("LatestDistanceDiv").innerHTML = "";
        }
        else {
            $("TotalDistanceDiv").innerHTML = distanceObject.ConvertDistanceToString(distanceObject.TotalDistance, Enum.Distance.Unit.Miles, Enum.Distance.UnitDisplayFormat.OneDecimalValue);
            $("LatestDistanceDiv").innerHTML = "";                                
        }    
    }
}
// When Mesure Distance is Active - OnDoubleLeft Click Handler - Stop Measuring
function MeasureDistanceStopOrClear(e) 
{
    if (distanceObject.Status == Enum.Distance.Status.Started) {
        distanceObject.StopMeasuring();
        if ($("DistanceKmRBtn").checked) {
            $("TotalDistanceDiv").innerHTML = distanceObject.ConvertDistanceToString(distanceObject.TotalDistance, Enum.Distance.Unit.Kilometers, Enum.Distance.UnitDisplayFormat.OneDecimalValue);
            $("LatestDistanceDiv").innerHTML = "";
        }
        else {
            $("TotalDistanceDiv").innerHTML = distanceObject.ConvertDistanceToString(distanceObject.TotalDistance, Enum.Distance.Unit.Miles, Enum.Distance.UnitDisplayFormat.OneDecimalValue);
            $("LatestDistanceDiv").innerHTML = "";                    
        }    
        // Update NextToPointer with the right value (it is always higher bout the latest distance)
        $("DistancePointerValue").innerHTML = $("TotalDistanceDiv").innerHTML;
    }
    // Reset -> Ready For New Measurement
    else if (distanceObject.Status == Enum.Distance.Status.Stopped) {
        distanceObject.Reset();
        $("TotalDistanceDiv").innerHTML = "";
        $("LatestDistanceDiv").innerHTML = "";
        $("DistancePointerValue").innerHTML = "";
        ShowMeasureDistanceNextToPointerDiv(false);
    }  
}
// Shows line when in mesuring distance is active - OnMove Handler
function MeasureDistanceOnMove(e)
{
    // Status == 1 - Measuring
    if (distanceObject.Status == Enum.Distance.Status.Started) {
        var cursorlatLong = map.PixelToLatLong(new VEPixel(e.mapX, e.mapY));
        var distance = distanceObject.GetDistanceBetweenLatestPointAndPoint(cursorlatLong);
        if (distance != null) {        
            distanceObject.displayMoveIndicator(cursorlatLong);  
            if ($("DistanceKmRBtn").checked) {
                $("TotalDistanceDiv").innerHTML = distanceObject.ConvertDistanceToString(distanceObject.TotalDistance + distance, Enum.Distance.Unit.Kilometers, Enum.Distance.UnitDisplayFormat.OneDecimalValue);
                $("LatestDistanceDiv").innerHTML = distanceObject.ConvertDistanceToString(distance, Enum.Distance.Unit.Kilometers, Enum.Distance.UnitDisplayFormat.OneDecimalValue);
            }
            else {
                $("TotalDistanceDiv").innerHTML = distanceObject.ConvertDistanceToString(distanceObject.TotalDistance + distance, Enum.Distance.Unit.Miles, Enum.Distance.UnitDisplayFormat.OneDecimalValue);
                $("LatestDistanceDiv").innerHTML = distanceObject.ConvertDistanceToString(distance, Enum.Distance.Unit.Miles, Enum.Distance.UnitDisplayFormat.OneDecimalValue);                    
            } 
            $("DistancePointerValue").innerHTML = $("TotalDistanceDiv").innerHTML;
            $("NextToPointerDiv").style.left = e.mapX+10 + "px";
            $("NextToPointerDiv").style.top = e.mapY+10 + "px";               
        }    
    }      
}
// Shows and Hides ScaleBar
function ScaleBarChBox_OnClick(sender, e)
{
    if ($("ScaleBarChBox").checked) {
        //$("ScaleBarUnitDiv").show();
        map.ShowScalebar();
        // Sets unit depending on radio
        ScaleBarRadio_OnClick();
    }                                                    
    else {            
        //$("ScaleBarUnitDiv").hide();
        map.HideScalebar()                  
    }
}
// Sets Units of Scale Bar
function ScaleBarRadio_OnClick(sender, e)
{
    if ($("ScaleBarKmRBtn").checked) {
        userSettings.ChangeCookieSettings(Enum.QsParams.ScaleBar, Enum.QsParams.scaleBar.Kilometers);
        map.SetScaleBarDistanceUnit(VEDistanceUnit.Kilometers);
    }
    else {
        userSettings.ChangeCookieSettings(Enum.QsParams.ScaleBar, Enum.QsParams.scaleBar.Miles);
        map.SetScaleBarDistanceUnit(VEDistanceUnit.Miles);        
    }    
}
// Shows / Hides Mini Map
function MiniMapChBox_OnClick(el)
{
    var disableCookie = false;
    
    // When a mini map icon is clicked
    if (el != null)
    {
        if (el.id == "MiniMapShowImg") {
            $("MiniMapChBox").checked = true;
        }
        else if (el.id == "MiniMapHideImg") {
            $("MiniMapChBox").checked = false;
        }
        else if (el == "DisableCookie") {
            disableCookie = true;
        }
    }
    
    // Set unit cookie
    if ($("MiniMapSmallRBtn").checked) {
        if (!disableCookie) userSettings.ChangeCookieSettings(Enum.QsParams.MiniMap, Enum.QsParams.miniMap.Small);
    }
    else {
        if (!disableCookie) userSettings.ChangeCookieSettings(Enum.QsParams.MiniMap, Enum.QsParams.miniMap.Large);
    }
    
    // Show MiniMap
    if ($("MiniMapChBox").checked) {
        // Make sore that the map is in 2D mode
        if (map.GetMapMode() == VEMapMode.Mode3D) {
           map.SetMapMode(VEMapMode.Mode2D);
        }
        // Shows MiniMap and Resizes it depending on the checked radio        
        var miniMapSize = null;
        if ($("MiniMapSmallRBtn").checked) {            
            miniMapSize = VEMiniMapSize.Small;            
            var x = 0;
            var y = $("MapDiv").offsetHeight - 152;
            //var x = $("MapDiv").offsetWidth - 152;
            //var y = $("MapDiv").offsetHeight - 152;        
        }
        else {
            miniMapSize = VEMiniMapSize.Large;
            var x = 0;
            var y = $("MapDiv").offsetHeight - 194;
        }        
        map.ShowMiniMap(x, y, miniMapSize); 
        $("MiniMapShowImg").hide();
        $("MiniMapHideImg").show();
    }                            
    else {
        // Hide Map
        map.HideMiniMap();   
        $("MiniMapShowImg").show();
        $("MiniMapHideImg").hide();             
    }    
}

/* Results Box 
*****************/
// Shows / Hides MapResultsBox
function ResultsChBox_OnClick(allow) 
{
    if (allow != null)
    {
        $("ResultsChBox").checked = allow;
    }
    if ($("ResultsChBox").checked) {
        $("MapResultsDiv").show();
        cache.CountryData.UpdateResultsPanel();    
    } 
    else {
        $("MapResultsDiv").hide();
        $("MapResultsMinDiv").hide();
    }
}

// Minimizes Results Panel
function ResultsPanelAction(command) 
{
    if (command == "minimize")
    {
        $("MapResultsDiv").hide();
        $("MapResultsMinDiv").show();
    }
    else if (command == "maximize")
    {
        $("MapResultsDiv").show();
        $("MapResultsMinDiv").hide();    
    }
}

function MakeMapBgDarker(obj)
{    
    var el = $(obj.Id);
    if (obj.SetDarker) {
        if (!el.hasClassName("onMapBgDarker")) {
            el.addClassName("onMapBgDarker");
        }
    }    
    else {        
        if (el.hasClassName("onMapBgDarker")) {
            el.removeClassName("onMapBgDarker");
        }
    }    
}

function ShowInfoBox(polygonID)
{
    var shape = map.GetShapeByID(polygonID);
    cache.CountryData.ShowInfoBox(shape, null);
    
    /*var shape = map.GetShapeByID(polygonID);
    var zoom = map.GetZoomLevel();
    map.SetMapView(shape.GetPoints());
    map.SetZoomLevel(zoom);
    map.ShowInfoBox(shape);*/       
}

/* Map Menu
**************/
// Handles user-menu interaction
// When a menu item is clicked, an activateTab css is applied to it (element Li) and also representing panel is displayed)
// Requirements: Menu Li elements names ends with Li
//              (div element) has the same name but ending with Div
// Example: CrisisLi (menu item) -> CrisisDiv (panel)               
function ActivateMenuItem_OnClick(el)
{          
    panelId = el.id.substr(0, el.id.length-2) + "Div";
    $(panelId).show();
    
    // Horizontal menu - when an active menu item is clicked than inactivate it and close its panel
    if (el.className == "activeTab") {
        if (el.id == "SettingsLi") CloseControl("SettingsDiv", el.id);
        if (el.id == "ToolsLi") CloseControl("ToolsDiv", el.id);
        if (el.id == "SearchLi") CloseControl("SearchDiv", el.id);
        return 0;
    }
    
    // If click on menu item, make it active and display its panel  
    menuLiElements = el.parentElement.getElementsByTagName("Li");
    $A(menuLiElements).each( 
        function(e) 
        { 
            if (e.id.length > 0 && e.id != "MinimizeLi") e.className = "inactiveTab"; 
        });            
    el.className = "activeTab";
    
    panelId = el.id.substr(0, el.id.length-2) + "Div";
    panelElement = $(panelId);
    panelElements = panelElement.parentElement.childNodes;
    $A(panelElements).each( 
        function(e) 
        { 
            // ToDo: figure out why I can not use e.hide()
            //if (e.nodeName == "DIV") e.hide();
            if (e.nodeName == "DIV") e.style.display = "none";
        });
    var r = panelElement.visible();
    panelElement.show();
}  

function HighliteMenuItem(obj)
{    
    var el = $(obj.Id);
    var highlite = obj.Highlite;
    if (highlite) {        
        if (obj.Id == "MinimizeDiv" || obj.Id == "MaximizeDiv")
        {
	        el.style.display = "block";
        }
        else
        {
            el.style.border = "1px solid #8DC2EE";
	        el.style.padding = "5px 5px 4px 5px";        
	    }
    }                   
    else {                
        if (obj.Id == "MinimizeDiv" || obj.Id == "MaximizeDiv")
        {	        
	        el.hide();             
        }
        else
        {
            el.style.border = "none";
	        el.style.padding = "6px 6px 4px 6px";	        
	    }	   
    }    
}

function MinimizeMenu()
{
    $("MenuMaximizeFg").hide();
    $("MenuMinimizeFg").show();
    $("HorizontalMenuDiv").addClassName("minimize");
}

function MaximizeMenu()
{
    $("MenuMaximizeFg").show();
    $("MenuMinimizeFg").hide();
    $("HorizontalMenuDiv").removeClassName("minimize");
}


/* Accordian control */
function ActivateControl(obj)
{
    // If tools => create permalink
    if (obj.Header == "PermalinkH")
    {
        GeneratePageLink('true');
    }
    // Accordian control - operation
    var TIME_DOWN = 0.6; //[s]
    var TIME_UP = 0.3; //[s]

    /* effectLock - make headers onclick inactive till an effect finishes otherwise there were issues with a high of a div which was changed */
    if (!effectLock)
    {    
        var hEl = $(obj.Header);
        var cEl = $(obj.Container);
                                
        // Was is clicked on an active header?                        
        if (hEl.hasClassName("activeHeader"))
        {          
            // Yes - slide it up and make a header inactive        
            effectLock = true;
            var effect = new Effect.SlideUp(cEl, { duration: TIME_UP, afterFinish: function() { hEl.removeClassName("activeHeader"); effectLock = false; } });        
        }
        else
        {        
            // Is there any active header?           
            var actH = null;
            var actC = null;
            
            var mainContainer = hEl.parentNode.parentNode;            
            var subHeaders;
            try
            {
                 subHeaders = Element.getElementsByClassName(mainContainer, "cHeader");
            }
            catch (e)
            {
                 subHeaders = mainContainer.getElementsByClassName("cHeader");
            }
            
            $A(subHeaders).each(function(el) 
                {
                    if (Element.hasClassName(el, "activeHeader"))
                    {
                        actH = el;
                        try
                        {
                            actC = Element.getElementsByClassName(actH.parentNode, "container")[0];
                        }
                        catch (e)
                        {
                            actC = actH.parentNode.getElementsByClassName("container")[0];
                        }                                                
                    }                
                });
                       
            // has been an active element found?
            if (actH != null && actC != null)
            {
                // Yes, than slide it up and make it inactive
                effectLock = true;
                actH.removeClassName("activeHeader");
                var effect = new Effect.SlideUp(actC, 
                    { 
                        duration: TIME_UP, 
                        afterFinish: function() 
                            { 
                                effectLock = true;
                                hEl.addClassName("activeHeader");
                                var effect = new Effect.SlideDown(cEl, { duration: TIME_DOWN, afterFinish: function() { effectLock = false; } });
                            } 
                    });                               
            }            
            else
            {
                effectLock = true;
                hEl.addClassName("activeHeader");
                var effect = new Effect.SlideDown(cEl, { duration: TIME_DOWN, afterFinish: function() { effectLock = false; } });        
            }
        }
    }    
} 

/* Search Panel
*****************/
//  Shows/Hides from/to text boxes for date
function DateChBox_Click()
{
    if ($("DateChBox").checked) {
        $("SearchDateFromValue").value = "dd/mm/yyyy";
        $("SearchDateFromValue").value = "dd/mm/yyyy";
        $("SearchDateValueDiv").show();

        // tick off Time period check box
        $("TimePeriodChBox").checked = false;
        TimePeriodChBox_Click();        
    }
    else {
        $("SearchDateValueDiv").hide();
    }
}

//  Shows/Hides 'select options' for time period
function TimePeriodChBox_Click() {    
    if ($("TimePeriodChBox").checked) {
        $("SearchTimePeriodValueDiv").show();
        
        // tick off Date check box
        $("DateChBox").checked = false;
        DateChBox_Click();        
    }
    else {
        $("SearchTimePeriodValueDiv").hide();
    }
}

// Displays / Hides source check box
// if aid agency only is checked or if maps only is checked or if other options are checked excluding maps and aid agency
function ShowSourceChBox()
{
    if (($("NewsChBox").checked || $("InsightChBox").checked || $("BlogChBox").checked || $("PictureChBox").checked)
        && !$("MapChBox").checked && !$("AidAgencyChBox").checked) {
        $("SourceDiv").show(); // displays div with a source check box        
        $("SourceNameSelect").show();
        $("MapSourceNameSelect").hide();
        $("AidAgencySourceNameSelect").hide();
        SourceChBox_OnClick();
    }
    else if (!$("NewsChBox").checked && !$("InsightChBox").checked && !$("BlogChBox").checked && !$("PictureChBox").checked
        && $("MapChBox").checked && !$("AidAgencyChBox").checked) {
        $("SourceDiv").show(); // displays div with a source check box                
        $("SourceNameSelect").hide();
        $("MapSourceNameSelect").show();
        $("AidAgencySourceNameSelect").hide();
        SourceChBox_OnClick();
    }
    else if (!$("NewsChBox").checked && !$("InsightChBox").checked && !$("BlogChBox").checked && !$("PictureChBox").checked
        && !$("MapChBox").checked && $("AidAgencyChBox").checked) {
        $("SourceDiv").show(); // displays div with a source check box                
        $("SourceNameSelect").hide();
        $("MapSourceNameSelect").hide();
        $("AidAgencySourceNameSelect").show();
        SourceChBox_OnClick();
    }
    else {
        $("SourceDiv").hide(); // hides div with a source check box 
    }
}
function SourceChBox_OnClick()
{
    if ($("SourceChBox").checked)
    {
        $("SourceSelectDiv").show();                
    }
    else {
        $("SourceSelectDiv").hide();        
    }
}

function ClearDateValue(el)
{
    if (el.value == "dd/mm/yyyy") el.value = "";
}

/* GeoData Panel */
function GeoRSSChangeSelection(value)
{
    if (value == "urlText") {
        $("UrlOfRSSFeedRBtn").checked = "checked";
    }
    else if (value == "urlWms") {
        $("UrlOfWmsFeedRBtn").checked = "checked";
    }    
    else if (value == "select") {
        $("SelectRSSFeedRBtn").checked = "checked";
    }
} 

function GeneralSearch_ShowContentItemOptions()
{ 
    
    if ($("SearchContentItemRBtn").checked) {
        $('SearchContentItemOptionsDiv').show(); 
    }
    else {
        $('SearchContentItemOptionsDiv').hide(); 
    }    
} 
 
/* Available Statistics */ 
function AvailableStatNameSelect_OnChange()
{
    availableStats.OnAvailableStatisticNameChanged();
}
 
  
/* Submiting Data
********************************************************************************************************/

// Updates all Map Information
// arguments: isNew - if true than data from a form is parsed and new request is made
//                    if false than no form data is parsed, just the current request is resent
function UpdateMapBtn_OnClick(obj) 
{            
    var isRefresh = obj.IsRefresh;
    var isNew = obj.IsNew;

    if (isRefresh) 
    {        
        if (isNew)
        {
            // ToDo: replace functionality - displaying duplicities in legends
            isNewRequest = true;
        
            // UpdateBtn_OnClick
            // Crate new request with regard to the entered data          
            var formData = new FormData();
            var data = formData.GetRequestedData();        
            if (data != null && data.length > 0)
            {
                // Create a new request
                requestManager.DeleteRequests();
                requestManager.AddNewRequests(data, isRefresh);
                
                // Delete all layers and country data before a request is sent
                //map.DeleteAllShapes();
                cache.MapLayerManager.DeleteAllTileLayers();
                cache.MapLayerManager.DeleteAllGeoLayers();
                cache.MapLayerManager.DeletePolygonLayer();
                cache.MapLayerManager.DeleteGeoStormLayer();
                cache.CountryData.DeleteAllCountries();
                ClearLegend();
                cache.CountryData.ClearResultsPanel();
                
                // Send a request
                requestManager.SendAllRequests();

                // Close menu panel
                CloseControl("SettingsDiv", "SettingsLi");
                CloseControl("ToolsDiv", "ToolsLi");
                CloseControl("SearchDiv", "SearchLi");                
            } 
        }         
        else
        {
            isNewRequest = false;
            // OnEndZoom - just for Server Request
            if ($("SettingsMapUpdate").checked)
            {
                requestManager.SendRequestByType(Enum.Request.Type.Server, isRefresh);
            }
        }        
    }    
    else 
    {                  
        isNewRequest = false;
        // OnEndPan - just for Server Request
        if ($("SettingsMapUpdate").checked)
        {
            // Did I get the response back from the last onendzoom request?
            var reqId = requestManager.GetIdOfLatestOnEndZoomRequest();            
            if (reqId != null)
            {
                var request = requestManager.GetRequestById(reqId);
                if (request.Status != Enum.Request.Status.Received)
                {
                    //yes        
                    requestManager.SendRequestByType(Enum.Request.Type.Server, false);                                              
                    return;
                }                        
            }                        
            //no
            requestManager.SendRequestByType(Enum.Request.Type.Server, true);                              
        }    
    }        
}

// Deletes all VE layers and set all controls to their default values      
function ResetMapBtn_OnClick(sender, e) 
{    
    // In case of displaying KML -> PolygonLayer is hidden
    cache.MapLayerManager.ShowPolygonLayer();
    
    // Delete Layers
    cache.MapLayerManager.DeleteAllTileLayers();
    cache.MapLayerManager.DeleteAllGeoLayers();
    cache.MapLayerManager.DeletePolygonLayer();
    cache.MapLayerManager.DeleteGeoStormLayer();
    cache.CountryData.DeleteAllCountries();    
    
    // Delete Requests
    requestManager.DeleteRequests();
    
    // Clear Legend & Status bar & Results panel
    ClearLegend();  
    statusBar.ClearAllMsgs();
    cache.CountryData.ClearResultsPanel();
    
    // Recenter map
    map.SetCenter(new VELatLong(DEFAULT_LAT, DEFAULT_LONG));
    map.SetZoomLevel(DEFAULT_ZOOM);
    
    // Hide VE Find results div
    $("VEFindDiv").hide();

    // Clear Search panel
    
    // Hide Source Divs
    $("SourceDiv").hide();
    $("SourceSelectDiv").hide();
    $("SearchDateValueDiv").hide();
    $("SearchTimePeriodValueDiv").hide();    
        
    // Clear all checkboxes
    var tags = null;    
    tags = ($("SearchDiv").getElementsByTagName("input"));
    ResetInputTags(tags);
    
    tags = ($("SearchDiv").getElementsByTagName("select"));
    ResetInputTags(tags);

    // Time period select - default is 24
    $("LatestNewsSelect").value = 24;
                
    function ResetInputTags(tags)
    {        
        for (var i = 0; i < tags.length; i++)
        {
            var tag = tags[i];
            if ((tag.nodeName.toLowerCase() == "input") && tag.type.toLowerCase() == "checkbox")
            {
                tag.checked = false;
            }       
            if (tag.nodeName.toLowerCase() == "input" && tag.type.toLowerCase() == "text")
            {
                tag.value = "";
            }               
            if (tag.nodeName.toLowerCase() == "select")
            {
                var opts = tag.childNodes;
                if (opts != null && opts.length > 0)
                {             
                    var j = 0;
                    while (j < opts.length)
                    {
                        if (opts[j].nodeName.toLowerCase() == "option")
                        {
                            tag.value = opts[j].value;
                            break;                            
                        }
                        j++;    
                    }    
                }
            }                       
        }
    }   
}               

// ToDo: Make it a part of RequestManager class
// Requests data for crisis with a specific code - called when a user clicks on a title of crisis in an info box
function SubmitCrisisCode(code)
{
    if (code)
    {        
        ResetMapBtn_OnClick();
        requestManager.CreateAndSendCrisisRequestWithCode(code);
    }
}
// Displays a pushpin on a map for the provided coordinates 
function ShowPointOnMap(lat, lon)
{                  
    // trim values
    lat = lat.replace(/^\s+|\s+$/g, '');
    lon = lon.replace(/^\s+|\s+$/g, '');                  
    
    // Find address of the point (lat/long)    
    map.FindLocations(new VELatLong(lat, lon), GetAddressResults);
        
    function GetAddressResults(locations)
    {
        var address = null;
        if(locations != null)
        {
             address = locations[0].Name;           
        }
        
        // Show on map
        var title = "<div class='control'>" + 
                        "<div class='cHeader'>" +                     
                            "<a href='#' target='_blank'>" + "Latitude / Longitude Search Result" + "</a>" + 
                            "<div class='winClose' onclick='CloseInfoBox()'>" +
                                "<img src='" + IMAGES_URL + "empty15x15.gif' alt='Close' title='Close' />" +                                    
                            "</div>" +
                        "</div>" + 
                    "</div>";
                                  
        var desc = "<div id='InformationBoxDescription'>" +
                        "<div class='itemDesc'>" +
                            "Latitude: " + lat + 
                            "<br />" + 
                            "Longitude: " + lon;
                            if (address != null)
                            {                    
                                desc += "<h3>Address</h3>" + address;
                            }
               desc += "</div>" +                         
                   "</div>";    
                       
        var point = new VELatLong(lat, lon);
        var pushpin = new VEShape(VEShapeType.Pushpin, point);
        pushpin.SetTitle(title); 
        pushpin.SetDescription(desc);
        cache.MapLayerManager.GetVELayer().AddShape(pushpin);
        map.SetCenter(point);         
        
    }        
}

/* GENERAL METHODS 
 **********************************************************************************************/
 
/* KML */ 
// Show
function ShowKmlOnMap(url)
{
    $("SettingsMapUpdate").checked = false;
    cache.MapLayerManager.HidePolygonLayer();
    var MapUpdateChBoxPreviosState = $("SettingsMapUpdate").checked;    
    cache.MapLayerManager.PreviosMapView = map.GetMapView();    
    statusBar.ShowTooltip("<a href='#' onclick='ReturnBackToMaps(" + MapUpdateChBoxPreviosState + ")'>Go back</a>");    
    cache.MapLayerManager.ShowTileLayer(url, Enum.TileLayer.Kml);
} 
// Hide
function ReturnBackToMaps(MapUpdateChBoxPreviosState)
{
    $("SettingsMapUpdate").checked = MapUpdateChBoxPreviosState;
    map.SetMapView(cache.MapLayerManager.PreviosMapView);
    cache.MapLayerManager.ShowPolygonLayer();    
    statusBar.HideTooltip();
    cache.MapLayerManager.DeleteAllTileLayers();    
} 
 
 
        
/* AJAX         
 **********************************************************************************************/
 
// Exports Page to an image
function ConvertMapStyle() {
    var style = map.GetMapStyle();
    if (style == VEMapStyle.Aerial) return 0;
    if (style == VEMapStyle.Road) return 1;
    if (style == VEMapStyle.Hybrid) return 2;  
    return 0;
} 

function ExportPage()
{    
    var exportFormat = parseInt($("ExportPageSelect").value, 10);
    if (exportFormat != -1)
    {
        var reqId = requestManager.GetLatestIdOfRequestByType(Enum.Request.Type.Server);
        var dataRequest;
        if (reqId != null)
        {
            dataRequest = requestManager.GetRequestById(reqId).Data;
            
            //Export Format
            dataRequest.ExportFormat = exportFormat;

            Reuters.Alertnet.WebServices.MapDataService.set_path(WEBSERVICE_RELATIVE_URI);
            Reuters.Alertnet.WebServices.MapDataService.GetExportUrl(dataRequest, GetExportUrl_onSuccess, GetExportUrl_onFailed, null);
            statusBar.ShowStatusMessage("Exporting map...", 5000);            
        }
        else {
            alert("No exportable data is shown on the map.");
            return;
        }               
    }
    else
    {
        alert("Please select an export format.");
    }
}


function GetExportUrl_onSuccess(arg) {

	/*$("exportedMapIframe").innerHTML = "<iframe src ='" + WEBSERVICE_ABSOLUTE_URI + arg + "'>" +
		"<script type='text/javascript'>alert('Your browser does not support iframes. The saved image will open in a new window.'); window.open('"+ arg +"');" +
		"</iframe>";*/
    var exportUrl = WEBSERVICE_ABSOLUTE_URI + arg;
    var exportWindow = window.open(exportUrl, "exportWindow","location=1,status=1,scrollbars=0,width=100,height=100");
    exportWindow.moveTo(0, 0);
    exportWindow.location = exportUrl;
    
	statusBar.HideLoading();
}

function GetExportUrl_onFailed(arg) {
	var message = (arg == null) ? "" : arg;
	alert("Failed to export the map. \n" + message);
	statusBar.HideLoading();
}   
   
// GetGeoRssMapData onSuccess
function GetGeoRssMapData_onSuccess(dataResponse)
{        
    function contains(obj, prop, value) {
        var propertyValue = (obj[prop]) ? obj[prop] : null;
        return value==propertyValue;
    }         
    
    try
    {
        var request = requestManager.GetRequestById(dataResponse.RequestId);              
        request.Status = Enum.Request.Status.Received;
        
        // Is there an exception on the server or no data available?
        if (dataResponse.Items == null) 
        {
            statusBar.ShowStatusMessage("No data available.", 3000); 
            statusBar.HideLoading(); 
            return;
        }
        
        var item = null;
        var layer = null;
        var icon = null;
        var iconPath = null;
        
        // Get GeoRssInfoItem
        var infoItems = dataResponse.Items.findAll(
                function(obj) { return contains(obj, "Type", ItemTypeEnum.GeoRssInfo); }
            );        
            
        for (var j = 0; j < infoItems.length; j++)
        {                
            var infoItem = infoItems[j];
            
            // Get just items fot the specific type (stored in infoItem.Code)
            var items = dataResponse.Items.findAll(
                function(obj) { return contains(obj, "Type", infoItem.Code); }
            );        
            
            // Are there any items?
            if (items.length > 0)
            {
                // Get the type of items in a response (infoItem.Code -> used to store a type of items)                
                switch (parseInt(infoItem.Code))
                {
                    case ItemTypeEnum.Flood:
                    {
                        layer = cache.MapLayerManager.GetGeoFloodLayer();
                        iconPath = IMAGES_URL + "iconPushpinBlue.gif";
                        iconClusterPath = null;            
                        break;
                    }        
                    case ItemTypeEnum.Earthquake:
                    {
                        layer = cache.MapLayerManager.GetGeoEarthquakeLayer();
                        iconPath = IMAGES_URL + "iconPushpinRed.gif";
                        iconClusterPath = null;            
                        break;
                    }                
                    case ItemTypeEnum.Volcano:
                    {
                        layer = cache.MapLayerManager.GetGeoVolcanoLayer();                
                        iconPath = IMAGES_URL + "iconPushpinYellow.gif";
                        iconClusterPath = IMAGES_URL + "iconPushpinYellowCluster.gif";          
                        break;
                    }
                    default:
                    {
                        layer = cache.MapLayerManager.GetGeoLayer();
                    }
                }           
                
                // Display items on a map
                for (var i = 0; i < items.length; i++)
                {            
                    var item = items[i];                     
                 
                    if (item.Title != null && item.Points != null && item.Points.length > 0)
                    {
                        var latlong = new VELatLong(item.Points[0].H, item.Points[0].W);                
                        var shape = new VEShape(VEShapeType.Pushpin, latlong);            
                        
                        var title = "<div class='control'>" + 
                                        "<div class='cHeader'>" +                     
                                            infoItem.Title + 
                                            "<div class='winClose' onclick='CloseInfoBox()'>" +
                                                "<img src='" + IMAGES_URL + "empty15x15.gif' alt='Close' title='Close' />" +                                    
                                            "</div>" +
                                        "</div>" + 
                                    "</div>";            
                        var desc = "<div id='InformationBoxDescription'>" +
                                        "<div><h3>" + item.Title + "</h3></div>";
                                        if (item.Time != null)
                                        {
                                            desc += "<div>" + item.Time.toUTCString() + "</div>";
                                        }
                               desc +=  "<div class='itemDesc'>" + item.Desc + "</div>";
                                        if (infoItem.Title != null)
                                        {
                                            desc += "<div class='itemSource'><span class='label'>Source: </span>" + infoItem.Title + "</div>";
                                        }
                                desc += "<div><a href='" + item.Link + "' target='_blank'>See details...</a></div>" +
                                   "</div>";        
                        
                        shape.SetTitle(title);
                        shape.SetDescription(desc);        
                        icon = "<img src='" + iconPath + "'><span class='pinText'>" + "" + "</span>";
                        shape.SetCustomIcon(icon);
                        layer.AddShape(shape);            
                    }
                }
                ShowLegends([ parseInt(infoItem.Code) ] , true, true);
            }    
            else
            {
                // Note: infoItem.Code -> contains a type of items requested
                statusBar.ShowStatusMessage("No data available for " + GetNameOfItemType(infoItem.Code) + ".", 3000);  
            }            
        }       
        statusBar.HideLoading();                
    }
    catch (ex)
    {
        alert(ex.message);
        statusBar.HideLoading(true);
    }
    finally
    {
        GetGeoRssMapData_lock = false;
    }
    
}          

// GetGeoRssMapData onFail
function GetGeoRssMapData_onFailed(dataResponse)
{
    statusBar.HideLoading(true);
}   
   
// GetStorms onsuccess
function GetStorms_onSuccess(response)
{
    requestManager.GetRequestById(response.RequestId).Status = Enum.Request.Status.Received;
    if (response.Storms == null)
    {
        statusBar.HideLoading();
        statusBar.ShowStatusMessage("No data available for storms.", 3000);
        return;
    }        
    
    mapData.Storms = response.Storms;
    var storm = new Storm();
    storm.ShowOnMap();     
    statusBar.HideLoading(); 
    ShowLegends([ItemTypeEnum.Storm], null, true); 
}

// GetStorms onFail
function GetStorms_onFailed(response)
{
    statusBar.HideLoading(true);
}   
   
// GetDataFromServer onSuccess
function GetDataFromServer_onSuccess(dataResponse) 
{            
    //try
    {                       
        startTime = new Date().getTime();
    
        var id = requestManager.GetLatestIdOfRequestByType(Enum.Request.Type.Server);
        if (dataResponse.RequestId == id)
        {             
            requestManager.Lock = true;
            var request = requestManager.GetRequestById(id);            
            request.Status = Enum.Request.Status.Received; 
            clearTimeout(ResultsPanelTimerId);           
            
            // Is there any valid data?    
            if (dataResponse.Items == null || dataResponse.CountryPolygons == null)        
            {
                statusBar.HideLoading();                
                if (request.RefreshMap && isNewRequest)
                {
                    // If a new request is made (refresh is true) and no data is returned than display a message                                        
                    statusBar.ShowStatusMessage("No data currently available.", 3000);                    
                }
                requestManager.Lock = false;
                return;    
            }                    
            
            // Is there a message?
            if (dataResponse.Message != null && dataResponse.Message.length > 0)
            {  
                // ToDo: message = debug message.
                //var msg = dataResponse.Message + " <a href='" + WEBSERVICE_RELATIVE_URI + "/ShowLogFile'>Show log file</a>"
                //statusBar.ShowStatusMessage(msg, 4000);                 
            }                                                                                                                      
               
            // RefreshMap?
            if (request.RefreshMap)
            {            
                cache.CountryData.DeleteAllCountries();
                cache.CountryData.DeleteAllCountries();           
            }                                                   
                
            function contains(obj, prop, value) {
                var propertyValue = (obj[prop]) ? obj[prop] : null;
                return value==propertyValue;
            }                       
            
            cacheTime = new Date().getTime();
            // Process Country Related Data
            for (var i = 0; i < dataResponse.NotCachedItemsInBoxISOs.length; i++)
            {   
                // Cache Those Country Data that is not in cache
                var notCachedIso = dataResponse.NotCachedItemsInBoxISOs[i];     
                if (cache.CountryData.GetCountry(notCachedIso) == null)
                {
                    // Country Polygon
                    var countryPolygon = dataResponse.CountryPolygons.findAll(
                            function(obj) { return contains(obj, "Iso", notCachedIso); }
                        )[0];
                    // Get Items Belonging To Country
                    var items = dataResponse.Items.findAll(
                            function(obj) { return contains(obj, "Iso", notCachedIso); }
                        );
                    // Convert country polygons (CountryPolygon.Polygons) to an array of VEShape objects (vePolygons)
                    var vePolygons = ConvertCountryPolygonToVEPolygon(countryPolygon);
                                        
                    var newCountry = new Country(notCachedIso, countryPolygon.Name, items, vePolygons, countryPolygon.Link);               
                    cache.CountryData.AddCountry(newCountry);
                }
                // Throw away that Country Data that is out of box boundaries...
                /*
                
                */
            }
            // onZoomEnd -> refresh, shapes are deleted just before new ones are drawn.
            if (request.RefreshMap)
            {
                // Is it onZoomEnd
                if (cache.MapLayerManager.DoesPolygonLayerHaveAnyShapes())
                {
                    cache.MapLayerManager.GetPolygonLayer().DeleteAllShapes();
                }    
            }    
                        
            // Display Country Data                        
            displayTime = new Date().getTime();
            cache.CountryData.DisplayPolygons(dataResponse.NotCachedItemsInBoxISOs, dataResponse.CachedItemsInBoxISOs);
            
            // Update Results Panel
            updateTime = new Date().getTime();            
            if ($("ResultsChBox").checked)
            {
                cache.CountryData.UpdateResultsPanel();
            }
            
            // Status Bar
            statusTime = new Date().getTime();
            
            statusBar.HideLoading();
            if (dataResponse.Message != null)
            {
                // ToDo: message = debug message.
                //statusBar.ShowStatusMessage(dataResponse.Message);
            }               
            
            // Update Legend            
            ShowLegends(null, null, true);                         
            
            endTime = new Date().getTime();
            
            var diagnosticText = "Time>>>" + 
                                 " Total>" + (endTime - requestSubmitedTime) / 1000 + 
                                 ", Server>" + (startTime - requestSubmitedTime) / 1000 + 
                                 ", Client>" + (endTime - startTime) / 1000 + 
                                 ", CreatingVEShapes>" + (displayTime - cacheTime) / 1000 + 
                                 ", AddingShapesToLayer>" + (updateTime - displayTime) / 1000 + 
                                 ", UpdatingResultsPanel>" + (statusTime - updateTime) / 1000 + 
                                 ", RenderingResults>" + (statusTime - updateTime) / 1000;
            //alert(diagnosticText);
            
            requestManager.Lock = false;
        }
    }
    //catch(ex) 
    {
        /*requestManager.Lock = false;
        var jsEx = { Name: ex.name, Description: ex.description, Message: ex.message, Location: "" };*/        
        //alert(ex.message);
    }
}
        
// GetDataFromServer onFailure
function GetDataFromServer_onFailed(error, context, methodName) {
    if (error.get_timedOut()) {
        alert("The attempt to retrieve data has timed out. Please attempt your request again.");
    }    
    statusBar.HideLoading();
}  
         
/* HELPER METHODS
 **********************************************************************************************/

// Converts a country polygon object to a VEShape object
// Input: CountryPolygon object
// Output: Array of VE Polygons which can be displayed on a map
function ConvertCountryPolygonToVEPolygon(countryPolygon) 
{
    // array of VE polygons for a country
    var vePolygons = new Array();
    
    // Go through all polygons that belong to a country
    for (var i = 0; i < countryPolygon.Polygons.length; i++)
    {        
        // Points of a polygon
        var points = countryPolygon.Polygons[i].Points;
        
        // Convert Points to VELatLong objects
        var veLatLongArray = new Array();
        for (var j = 0; j < points.length; j++)
        {
            veLatLongArray[j] = new VELatLong(points[j].H, points[j].W);
        }            
                
        // Create VE polygon
        var polygonShape = new VEShape(VEShapeType.Polygon, veLatLongArray);
        
        // Assign Color
        if (countryPolygon.Color == null) alert(countryPolygon.Iso);
        polygonShape.SetFillColor(new VEColor(countryPolygon.Color.R, countryPolygon.Color.G, countryPolygon.Color.B, countryPolygon.Color.A));
        polygonShape.SetLineColor(new VEColor(246, 245, 155, 0.4));
        var lineWidth = Math.floor(map.GetZoomLevel() / 3);
        if (lineWidth == 0) lineWidth = 1;        
        polygonShape.SetLineWidth(lineWidth);
        polygonShape.HideIcon();                
        
        // Add a polygon to an array
        vePolygons.push(polygonShape);        
    }
    return vePolygons;
} 
  
// Returns name of an Item Type
function GetNameOfItemType(itemType)
{
    if (itemType == ItemTypeEnum.Conflict) typeName = "Conflicts";
    if (itemType == ItemTypeEnum.SuddenDisaster) typeName = "Sudden Disasters";
    if (itemType == ItemTypeEnum.FoodSecurity) typeName = "Food Security";
    if (itemType == ItemTypeEnum.Health) typeName = "Health";
    if (itemType == ItemTypeEnum.Storm) typeName = "Storms";
    if (itemType == ItemTypeEnum.Earthquake) typeName = "Earthquakes";
    if (itemType == ItemTypeEnum.Volcano) typeName = "Volcanos";
    if (itemType == ItemTypeEnum.Flood) typeName = "Floods";
    if (itemType == ItemTypeEnum.Statistic) typeName = "Statistics";
    if (itemType == ItemTypeEnum.News) typeName = "News";
    if (itemType == ItemTypeEnum.AidAgency) typeName = "Aid Agencies";
    if (itemType == ItemTypeEnum.Blog) typeName = "Blogs";
    if (itemType == ItemTypeEnum.Insight) typeName = "Insights";
    if (itemType == ItemTypeEnum.Picture) typeName = "Pictures";
    if (itemType == ItemTypeEnum.Video) typeName = "Videos";
    if (itemType == ItemTypeEnum.Map) typeName = "Maps";
    if (itemType == ItemTypeEnum.Statistic) typeName = "Statistic";
    if (itemType == ItemTypeEnum.Unspecified) typeName = "Others";    
    return typeName;
}

function GetLegendImageNameForItemType(itemType)
{
    if (itemType == ItemTypeEnum.Conflict) typeName = "conflict";
    if (itemType == ItemTypeEnum.SuddenDisaster) typeName = "suddenDisaster";
    if (itemType == ItemTypeEnum.FoodSecurity) typeName = "foodSecurity";
    if (itemType == ItemTypeEnum.Health) typeName = "health";
    if (itemType == ItemTypeEnum.Storm) typeName = "storm";
    if (itemType == ItemTypeEnum.Earthquake) typeName = "earthquake";
    if (itemType == ItemTypeEnum.Volcano) typeName = "volcano";
    if (itemType == ItemTypeEnum.Flood) typeName = "flood";
    if (itemType == ItemTypeEnum.Statistic) typeName = "statistics";
    if (itemType == ItemTypeEnum.News) typeName = "news";
    if (itemType == ItemTypeEnum.AidAgency) typeName = "aidAgency";
    if (itemType == ItemTypeEnum.Blog) typeName = "blog";
    if (itemType == ItemTypeEnum.Insight) typeName = "insight";
    if (itemType == ItemTypeEnum.Picture) typeName = "picture";
    if (itemType == ItemTypeEnum.Video) typeName = "video";
    if (itemType == ItemTypeEnum.Map) typeName = "map";
    if (itemType == ItemTypeEnum.Unspecified) typeName = "unspecified";    
    return typeName;
}

// Returns name of an Item Type
function GetLegendImagePath(itemType, endpart)
{
    if (itemType == ItemTypeEnum.Conflict) typeName = "conflict";
    if (itemType == ItemTypeEnum.SuddenDisaster) typeName = "suddenDisaster";
    if (itemType == ItemTypeEnum.FoodSecurity) typeName = "foodSecurity";
    if (itemType == ItemTypeEnum.Health) typeName = "health";
    if (itemType == ItemTypeEnum.Storm) { typeName = "storm"; return IMAGES_URL + "iconStorm32x32.png" }
    if (itemType == ItemTypeEnum.Earthquake) { typeName = "earthquake"; return IMAGES_URL + "iconPushpinRed.gif" }
    if (itemType == ItemTypeEnum.Volcano) { typeName = "volcano"; return IMAGES_URL + "iconPushpinYellow.gif" }
    if (itemType == ItemTypeEnum.Flood) { typeName = "flood"; return IMAGES_URL + "iconPushpinBlue.gif" }
    if (itemType == ItemTypeEnum.Statistic) typeName = "statistic";
    if (itemType == ItemTypeEnum.News) typeName = "news";
    if (itemType == ItemTypeEnum.AidAgency) typeName = "aidAgency";
    if (itemType == ItemTypeEnum.Blog) typeName = "blog";
    if (itemType == ItemTypeEnum.Insight) typeName = "insight";
    if (itemType == ItemTypeEnum.Picture) typeName = "picture";
    if (itemType == ItemTypeEnum.Video) typeName = "video";
    if (itemType == ItemTypeEnum.Map) typeName = "map";
    if (itemType == ItemTypeEnum.Unspecified) typeName = "unspecified";    
    return IMAGES_URL + "Legend/leg_" + typeName + endpart;
}

function ClearLegend()
{
    //$("LegendDiv").innerHTML = "";
    var legendBar = new LegendBar();
    legendBar.ClearAll();
    statusBar.HideLegend();      
}

// Used in Search / Location - results
function FindOnMap(location)
{
      map.Find(null, 
              location,
              null,
              cache.MapLayerManager.GetVELayer(),
              null,
              null,
              null,
              null,
              false,
              null,
              null);                    
}     

function LegendBar()
    {    
    }

    LegendBar.prototype.Show = function(itemTypes, append, isMultiple)
    {
        for(var i = 0; i < itemTypes.length; i++)
        {            
            if (itemTypes[i] == ItemTypeEnum.Statistic)
            {
                var max = 0;                
                for (var i = 0; i < cache.CountryData.Countries.length; i++)
                {
                    var value;
                    try
                    {
                        value = parseInt(cache.CountryData.Countries[i].Items[0].Source);
                        if (value > max)
                        {
                            max = cache.CountryData.Countries[i].Items[0].Source;
                        }
                    }
                    catch (ex)
                    {
                        max = "N/A";
                        i = itemTypes.length + 1;
                    }

                }                                                      
                var title = cache.CountryData.Countries[0].Items[0].Title;
                var desc =  cache.CountryData.Countries[0].Items[0].Desc;
                this._GenerateStatisticLegend(title, desc, 0, max);
            }                
            else
            {                
                this._GenerateLegend(itemTypes[i]);                
                if (isMultiple)
                {
                    this._GenerateMultipleLegend();
                }                
            }                       
        }
    }
    
    LegendBar.prototype.ClearAll = function()
    {        
        $A($("LegendDiv").childNodes).each(function(node)
            {
                if (node != null && node.id != null && node.tagName.toLowerCase() == "div") // && node.endsWith("LegDiv"))
                {
                    node.innerHTML = "";
                    node.style.display = "none";
                }            
            });
        
    }
    
    LegendBar.prototype._GenerateStatisticLegend = function(title, desc, min, max)
    {
        if ($("StatisticsLegDiv").innerHTML == "")
        {
            $("StatisticsLegDiv").innerHTML +=   "<div class='imagePart'>" +
                                                "<div class='value min'>" + min + "</div>" +  
                                                "<div class='value max'>" + max + "</div>" +  
                                                "<div class='clear'></div>" +                                               
                                                "<div class='legImage'>" +
                                                    "<img src='" + WEBSERVICE_ABSOLUTE_URI.substr(0, WEBSERVICE_ABSOLUTE_URI.length - 19) + "legend.ashx?img=statistics'/>" +
                                                "</div>" +
                                            "</div>" +
                                            "<div class='titlePart'>" +     
                                                title + " (" + desc + ")" +
                                            "</div>";
        }                                
        $("StatisticsLegDiv").show();                                   
    }
    
    LegendBar.prototype._GenerateLegend = function(itemType)
    {
        var legendName = GetLegendImageNameForItemType(itemType);
        var legendDivName = legendName.substr(0, 1).toUpperCase() + legendName.substr(1, legendName.length) + "LegDiv";
        
        if ($(legendDivName).innerHTML == "")
        {
            $(legendDivName).innerHTML += "<div class='basicLegend legend'>" +
                                            "<div class='imagePart basic'>" +                                              
                                                "<img src='" + this._GetLegendImagePath(itemType) + "'/>" +
                                            "</div>" +
                                            "<div class='titlePart'>" +     
                                                GetNameOfItemType(itemType) +
                                            "</div>" +   
                                       "</div>";
        }                                   
        $(legendDivName).show();                              
    }   
    
    LegendBar.prototype._GenerateMultipleLegend = function()
    {
        if ($("MultipleLegDiv").innerHTML == "")
        {
            $("MultipleLegDiv").innerHTML += "<div class='basicLegend legend'>" +
                                                "<div class='imagePart basic'>" +                                              
                                                    "<img src='" + WEBSERVICE_ABSOLUTE_URI.substr(0, WEBSERVICE_ABSOLUTE_URI.length - 19) + "legend.ashx?img=multiple'/>" +
                                                "</div>" +
                                                "<div class='titlePart'>" +     
                                                    "Multiple" +
                                                "</div>" +   
                                             "</div>";
        }                                 
        $("MultipleLegDiv").show(); 
    } 
    
    LegendBar.prototype._GetLegendImagePath = function(itemType)
    {
        var src = null;
        
        if (itemType == ItemTypeEnum.Earthquake)
        {
            src = IMAGES_URL + "iconPushpinRed.gif";
        }
        else if (itemType == ItemTypeEnum.Flood)
        {
            src = IMAGES_URL + "iconPushpinBlue.gif";
        }
        else if (itemType == ItemTypeEnum.Storm)
        {
            src = IMAGES_URL + "stormLegend.png";
        }
        else if (itemType == ItemTypeEnum.Volcano)
        {
            src = IMAGES_URL + "iconPushpinYellow.gif";
        }
        else
        {
            src = WEBSERVICE_ABSOLUTE_URI.substr(0, WEBSERVICE_ABSOLUTE_URI.length - 19) + "legend.ashx?img=" + GetLegendImageNameForItemType(itemTypes);        
        }   
        
        return src; 
    }
 

// Adds items to legend
function ShowLegends(itemTypes, hideMultiple, appendLegend, itemTitle)
{   
    //ClearLegend();
    
    // show legend div
    statusBar.ShowLegend();

    // Populate Legend    
    if (itemTypes == null)
    {
        itemTypes = cache.CountryData.GetUniqueItemTypes();
    }    

    var isMultiple = false;
    if (itemTypes.length > 1)
    {
        isMultiple = true;
    }  
    
    var legendBar = new LegendBar();
    legendBar.Show(itemTypes, appendLegend, isMultiple);             
}


function IsItCrisis(itemType)
{
    if (itemType == ItemTypeEnum.Conflict || 
        itemType == ItemTypeEnum.SuddenDisaster || 
        itemType == ItemTypeEnum.FoodSecurity || 
        itemType == ItemTypeEnum.Health || 
        itemType == ItemTypeEnum.Storm || 
        itemType == ItemTypeEnum.Earthquake || 
        itemType == ItemTypeEnum.Volcano || 
        itemType == ItemTypeEnum.Flood)
    {
        return true;    
    }
    
    return false;
}     

/*** Bookmarking
***********************************************************/
function BookmarkPage()
{
    var title = "Alertnet";
    var url = qs.Bookmark();
    if ((navigator.appName == "Microsoft Internet Explorer") && (parseInt(navigator.appVersion) >= 4)) {
        window.external.AddFavorite(url,title);
    } else if (navigator.appName == "Netscape") {
        window.sidebar.addPanel(title,url,"");
    } else {
        alert("Please click 'Copy permalink' and use your browser's tools to add this URL as a bookmark.");
    }
}

// Mails a link of a pate to an email account
function MailPageLink()
{
    var url = qs.Bookmark();
    var mailto_link = "mailto:?subject=Reuters AlertNet map&body=" + escape(url);
    var win = window.open(mailto_link, "emailWindow");
    if (win && win.open &&!win.closed) win.close();
}

// Displayes a link to a page
function GeneratePageLink(show)
{
    if (show) {
        var url = qs.Bookmark();
        $("PageLinkDiv").show();
        $("PageLinkText").value = url;
    }
    else {
        $("PageLinkDiv").hide();
    }
}

// Copy a permalink to a clipboard
function CopyPermalinkToClipboard() {
    var url = qs.Bookmark();
    if (window.clipboardData) {
        window.clipboardData.setData("Text", url);
        alert("Permalink was copied to a clipboard. Please use Ctrl-V to paste it.");
    }
    else {
        alert("Functionallity not supported for your browser, please copy a permalink from a text area below.");
    }
}

// Converts decimals to Degrees, Minutes, Seconds
function ConvertCoordinate(dec, direction) {
    dec = Math.abs(dec);
    var deg = Math.floor(dec);
    var m = (dec - deg) * 60;
    var min = Math.floor(m);
    var sec = Math.floor((m - min) * 60);        
    return deg + "° " + min + "' " + sec + "'' " + direction;
}   

// Hides an element with and id
function CloseControl(id, horizontalMenuLi)
{
    element = $(id);
    if (element != null) {
        element.hide();
    }
    
    // Horizontal menu -> when a panel is close than make its menu item inactive
    if (horizontalMenuLi != null) {
        $(horizontalMenuLi).className = "inactiveTab";
    }    
}

function CloseInfoBox()
{
    map.HideInfoBox();
}

/*** UNUSED
****************************************************************/
// Draws Circle
function drawCircle(origin,radius)
{  
  var earthRadius = 6371;
      
  //latitude in radians
  var lat = (origin.Latitude*Math.PI)/180; 
        
  //longitude in radians
  var lon = (origin.Longitude*Math.PI)/180; 
  //angular distance covered on earth's surface
  var d = parseFloat(radius)/earthRadius;  
  var Points = new Array();
  for (i = 0; i <= 360; i++) 
  { 
    var point = new VELatLong(0,0)            
    var bearing = i * Math.PI / 180; //rad
    point.Latitude = Math.asin(Math.sin(lat)*Math.cos(d) + 
      Math.cos(lat)*Math.sin(d)*Math.cos(bearing));
    point.Longitude = ((lon + Math.atan2(Math.sin(bearing)*Math.sin(d)*Math.cos(lat),
      Math.cos(d)-Math.sin(lat)*Math.sin(point.Latitude))) * 180) / Math.PI;
    point.Latitude = (point.Latitude * 180) / Math.PI;
    Points.push(point);
  }

  var distanceLayer = map.GetShapeLayerByIndex(distanceShapeLayerIndex);
  var circle;
  if (distanceCircleShapeId == -1) {
    circle = new VEShape(VEShapeType.Polyline, Points); 
    circle.HideIcon();    
    distanceLayer.AddShape(circle);
    distanceCircleShapeId = circle.GetID();
  }  
  else {
    circle = distanceLayer.GetShapeByID(distanceCircleShapeId);
    circle.SetPoints = Points;  
  }  
  // map.SetMapView(Points);
}  
 
        