﻿
// This is the AJAX/ATLAS client side object that handles feeding events to the
// VE Map for display.  It will use the existing data service to retrieve 
// clustered events for the view bounds and populate the VE map layers with
// icon/shapes for the event type.

Type.registerNamespace("ReportStorms");

//
// ReportStorms.DataClient:      
//  Creates the data client jscript "object"
//  inputs - 
//      map -- the defined map object that will receive the data service data (events)
//
ReportStorms.DataClient = function (map)
  {
  // _service needs to be set to the C# class that implements the webservice
  // Then, all the ATLAS AJAX magic from ASP.NET can be used to make the 
  // background AJAX calls.
  // ReportStorms.ReportStormsData is defined in ReportStormsData.asmx.cs
    this._service = ReportStorms.ReportStormsData;
    this._map = map;
    this._shapes = null;    
    this._GetMapDataDelegate = Function.createDelegate(this, this.GetMapData);
  // update the viewable events whenever the map changes view  
    this._map.AttachEvent("onendzoom", this._GetMapDataDelegate);        
  // category -- rarely if ever changes  
    this._currentEventCategory = EventCategory.Weather;  // see Constants.js
  // icon names lists  
    this._iconNames = [];            // empty array
    this._iconClusterNames = [];     // empty array
    this._enumerationLoaded = false; // nothing loaded yet
  // GetEventCategory -- query the current event category display filter  
    this.GetEventCategory = function()
      {
      return this._currentEventCategory;
      }
    
  // SetEventCategory -- set the current event category display filter, and update the map data
    this.SetEventCategory = function(eventCategory)
      {
      this._currentEventCategory = eventCategory;
      this.GetMapData();
      }
  } // object definition

// functions that access the data layer (database)
ReportStorms.DataClient.prototype = {
    //
    // GetMapData:
    //  grab the current map view bounds and zoom level and asyncronously call the web service
    //  to get clustered events.    
    //
    GetMapData : function()
      {
      //
      // FIXME: Handle 3D and Birdseye views
      //
      // Gather the information required for the query
        if(this._enumerationLoaded == false) return;
        var origin = this._map.GetCenter();
	      var zoom   = this._map.GetZoomLevel();
	      var today = new Date();
	      today.setHours(0, 0, 0, 0);
	      var midnight = new Date(today.toUTCString());
	      
        this._service.GetClusteredEventsForDay(midnight, zoom, Function.createDelegate(this, this.OnMapDataLoaded), this.OnError);
      },
    //
    // OnMapDataLoaded:
    //  ATLAS call back on successful reception of event data.  Parse out the results
    //  and populate the map with shapes
    //  input:
    //      results - the string result from C# class ReportStorms.ReportStormsData.GetBoundedEventsByCategory2D
    //
    OnMapDataLoaded : function(results)
      {
      // results come back as a simple string (not XML)
      // where each event is separated by a "|", and each field by a ":"
      // the field are  lat  - latitude
      //                lon  - longitude
      //                ids  - clustered ids list, each separated by a ","
      //                icon - parent icon for the cluster
        
        var layer = new VEShapeLayer();
        var length = results.length;
        for(i = 0; i < length; i++)
          {
            var cluster = results[i];
            var lat = cluster.Lat;
            var lon = cluster.Lon;
            var iconID = cluster.Icon;
            var iconName = this._iconNames[iconID];
            var eventID = cluster.EventIds[0];
            if(cluster.EventIds.length > 1)
              iconName = this._iconClusterNames[iconID];
            var newShape = new VEShape(VEShapeType.Pushpin, new VELatLong(lat, lon));
            newShape.SetDescription("" + eventID);
          // "correctPNG()" right here        
            if(Sys.Browser.agent == Sys.Browser.InternetExplorer && (Sys.Browser.version == 6))
              {
              var divText = "<div STYLE=\"position:relative;" +
                            "height:32px;" +
                            "width:32px;" +
                            "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='icons/" + iconName  + "',sizingMethod='scale');\"></div>";
              newShape.SetCustomIcon(divText);
              }
            else 
              newShape.SetCustomIcon("<img src='icons/" + iconName + "' width='32' height='32'/>");        
  
            layer.AddShape(newShape);
        }
        // remove previous layer  
        if(this._layer != null)
          {
          this._map.DeleteShapeLayer(this._layer);
          this._layer = null;
          }
      // insert the new layer    
        this._layer = layer;
        this._map.AddShapeLayer(this._layer); 
    },
    //
    // LINQGetEventTypesEnumeration:
    //  Get the icon types information (id-->iconname mapping)
    //
    LINQGetEventTypesEnumeration : function()
      {
        this._service.LINQGetEventTypesEnumeration(Function.createDelegate(this, this.OnLINQGetEventTypesEnumerationLoaded), this.OnError);
      }, 
      
    OnLINQGetEventTypesEnumerationLoaded : function(results)
      {
      // results come back as a simple string (not XML)
      // where each event is separated by a "|", and each field by a ":"
      // the field are  iconID   - integer id in original table
      //                iconName - image name icon on web server at local path
      //                iconClusterName - image name icon on web server at local path if it's the cluster icon
        var length = results.length;
        for(i = 0; i < length; i++)
          {
            var eventType = results[i];
            var iconID = eventType.event_type_id;
            var iconName = eventType.event_type_icon;
            var iconClusterName = eventType.event_type_icon_cluster;
            this._iconNames[iconID] = iconName;
            this._iconClusterNames[iconID] = iconClusterName;
          }  
        this._enumerationLoaded = true;
        this.GetMapData();
      },

    
    /*
    //
    // GetEventBalloon:
    //  Call the web service and get the balloon text for a given event ID
    //  inputs - 
    //      int eventID - the database id of the event we want balloon text for
    //      callback handler - the name of a function that takes the string output
    //          of reportstorms.reportstormsData.GetEventBalloon as an input
    //
    GetEventBalloon : function(eventID, handler){
        this._service.GetEventBalloon(eventID, handler, this.OnError);
    },
    //
    // GetEventImageURL:
    //  Call the web service and get the balloon text for a give event ID
    //  inputs - 
    //      int eventID - the database id of the event we want the image URL for
    //      callback handler - the name of a function that takes the string output
    //          of reportstorms.reportstormsData.GetEventImageURL as an input
    //
    GetEventImageURL : function(eventID, handler){
        this._service.GetEventImageURL(eventID, handler, this.OnError);
    },
    //
    // GetEventMovieURL:
    //  Call the web service and get the balloon text for a give event ID
    //  inputs - 
    //      int eventID - the database id of the event we want the movie URL for
    //      callback handler - the name of a function that takes the string output
    //          of reportstorms.reportstormsData.GetEventMovieURL as an input
    //
    GetEventMovieURL : function(eventID, handler){
        this._service.GetEventMovieURL(eventID, handler, this.OnError);
    },
    */
    
    //
    // OnError:
    //  ATLAS callback when there's an error making an asyncronous call to a 
    //  web service.
    //
    OnError : function(error){
        var stackTrace = error.get_stackTrace();
        var message = error.get_message();
        var statusCode = error.get_statusCode();
        var exceptionType = error.get_exceptionType();
        var timedout = error.get_timedOut();
       
        // Display the error.    
        var RsltElem = "VE_EventDataClient.js " +
            "Stack Trace:\n\n" +  stackTrace + "\n\n" +
            "Service Error: [" + message + "]\n\n" +
            "Status Code: [" + statusCode + "]\n\n" +
            "Exception Type: [" + exceptionType + "]\n\n" +
            "Timedout: [" + timedout + "]";
        alert(RsltElem);
        //util_Error(RsltElem);
    },
    
    Dispose: function() {        
        if (this._map != null) {
            this._map.DetachEvent("onchangeview", this.GetMapDataDelegate);               
            this._map.Dispose();
        } 
        this._service = null;
        this._shapes = null; 
        this.GetMapDataDelegate = null;   
    }

}

ReportStorms.DataClient.registerClass('ReportStorms.DataClient', null, Sys.IDisposable);

if (typeof(Sys) !== "undefined") Sys.Application.notifyScriptLoaded();