﻿
/*
Map layers controller
*/

function LayerController 
        (
            varname, 
            objPointItemObtainer, 
            objMapController,
            objStatusNotificator,
            objProgressNotificator
        )
{
    //Global variable name
    this.SVarname = varname;
        
    //Descriptors retriever
    this.objPointItemObtainer = objPointItemObtainer;
       
    //Map controller object
    this.objMapController = objMapController;
      
    //Status notification object
    this.objStatusNotificator = objStatusNotificator; 
    
    //Progress notification object
    this.objProgressNotificator = objProgressNotificator;
    
    //Array of map layers currently running
    this.arrMapLayers = new Array();
                               
    this.notifyStatus = function(msg)
    {
       if ( this.objStatusNotificator != null)
          this.objStatusNotificator.changeStatus(msg);
    }                                       
    //END PRIVATE
    
    
    ////////START PUBLIC PROPERTIES
    this.objLayerControllerEventListener = null;    
    ////////END PUBLIC PROPERTIES

        
    ////////START PUBLIC FUNCTIONS
    
    this.getLayer = function(layerId)
    {
        var i; 
        for ( i = 0; i < this.arrMapLayers.length; i++)
        {
            var currlayer = this.arrMapLayers[i];
            if ( currlayer.layerId == layerId)
                return currlayer;
        }
        
        return null;
    }
        
    /* Activate Layer */
    this.activateLayer = function(layerId)
    {  
        this.notifyStatus("Obtaining layer data");
        
        //Obtaining point items                    
        var res = this.objPointItemObtainer.getPointItems(layerId)
        if ( res.value == null)
            throw res.Error;
        
        //Obtaining layer descriptor object
        var ldres = this.objPointItemObtainer.getLayerDescription(layerId);
        if ( ldres.value == null)
            throw res.Error;
                                                        
        var ml = new MapLayer(
            layerId, 
            this.objMapController,
            this.objStatusNotificator,
            this.objProgressNotificator);
                                          
        ml.objLayerControllerEventListener = this.objLayerControllerEventListener;            
        ml.arrPointItems = res.value;
        ml.objLayerDescription = ldres.value;
        
        //Saving the layer into layers collection
        this.arrMapLayers.push(ml);
             
        if ( ml.arrPointItems != null && ml.arrPointItems.length != 0)
        {                                                                           
            this.notifyStatus("Drawing objects on the map");
        
            //Now try to display the layer on the map
            ml.display();
        }
                
        //NOT REACHABLE AFTER DISPLAY
    }
    
}//end class LayerController


//GLOBAL
//var _current_MapLayer = null;


function _helper_registerMarkerEvents(objLayerControllerEventListener,
                                      layer, marker, pointitem)
{
    
    if ( objLayerControllerEventListener != null)
    { 
      marker.addOnMouseOver
      (
        function()
        {
           objLayerControllerEventListener.onMarkerMouseOver(layer, marker, pointitem);
        }
      );
      
      marker.addOnMouseOut
      (
        function()
        {
           objLayerControllerEventListener.onMarkerMouseOut(layer, marker, pointitem);
        }
      );    
      
            
      marker.addOnMouseClick
      (
        function()
        {
           objLayerControllerEventListener.onMarkerClick(layer, marker, pointitem);
        }
      );       
    }
}                                    


//CLASS MapLayer
function MapLayer
            (
                layerId,
                objMapController,        
                objStatusNotificator,
                objProgressNotificator
            )
{
    
    //Layer ID
    this.layerId = layerId;

    //Map controller instance
    this.objMapController = objMapController;
    
    //Status notification object
    this.objStatusNotificator = objStatusNotificator; 
    
    //Progress notification object
    this.objProgressNotificator = objProgressNotificator;
           
    //Object descriptors
    this.arrPointItems = new Array();
    
    //Layer descriptor object
    this.objLayerDescription = null;
   
    //Markers associated with this layer
    this.arrMarkers = new Array();
    
    this.objLayerControllerEventListener = null;
            
    //////////////SERVICE VAR    
    this._p_notifyProgress = false;
    
    this._p_SVarname = "_current_MapLayer_" + this.layerId;                                     
    
    this._service_current_PointItemIndex = 0;              
    //////////////PRIVATE FUNCTIONS
     
    this._private_suspectDrawing = function()
    {
        /*
        if ( _current_MapLayer == this)
            _current_MapLayer = null;
        */        
        eval(this._p_SVarname + "=null;");
    }
    
    this._private_isNotifiable = function()
    {   
        return this._p_notifyProgress;
    }
        
    this._helper_nextDisplayStep = function()
    {      
        var currpi = this.arrPointItems[this._service_current_PointItemIndex];
               
        var marker = this.objMapController.placeMarker("images/icons/" + this.objLayerDescription.Img,
                currpi.X, currpi.Y);
                                               
        //Setting event listeners for this marker
        _helper_registerMarkerEvents(this.objLayerControllerEventListener,  
                    this, marker, currpi);
        
        this.arrMarkers.push(marker);
        
        // Set Progress
        if (this._private_isNotifiable())
        {
            //Notifying progress
            this.objProgressNotificator.setSoFar(this._service_current_PointItemIndex + 1);
        }
                        
        if (this._service_current_PointItemIndex < this.arrPointItems.length - 1 )
        {   // Call next
              
            // Check if the current map layer was set to null, then we have  to stop
            //if ( _current_MapLayer == null)           
            //    return;           
            
            ++ this._service_current_PointItemIndex;
            var callexp =
                "if( " + this._p_SVarname + " != null) " + 
                this._p_SVarname + "._helper_nextDisplayStep();";
                    
            setTimeout(callexp, 0);
        }
        else
        {         
            //notifying about the progress status
            if (this._private_isNotifiable())
                this.objProgressNotificator.setComplete(); 
                
            //notifying the listener
            if ( this.objLayerControllerEventListener != null)
                this.objLayerControllerEventListener.onLayerActivateComplete(this);
                
            this._service_current_PointItemIndex = 0;            
        }
    }            
    
    //////////////END PRIVATE
           
    /* 
        Populate layer on the map 
    */   
    this.display = function()
    {   
                                                     
        //Preparing ... 
        //_current_MapLayer = this;        
        eval(this._p_SVarname + "=this;");
        
        this._service_current_PointItemIndex = 0;
        
        if ( this.objProgressNotificator !=  null && !this.objProgressNotificator.isInProgress())  
        {
            this._p_notifyProgress = true;
            this.objProgressNotificator.setTotal(this.arrPointItems.length);
        }
        else
            this._p_notifyProgress = false;
            
        this._helper_nextDisplayStep();
    }
    
    /* 
       Remove layer from the map
    */
    this._blocking_remove = function()
    {                                        
        this._private_suspectDrawing();
        
        if ( this.arrMarkers != null)
        { //Array of markers has actually been initialised
            var i = 0;
            for ( i = 0; i < this.arrMarkers.length; i ++)
            {
                var currmarker = this.arrMarkers[i];
                this.objMapController.removeMarker(currmarker);
            }
        }
        
        //notifying the listener
        if ( this.objLayerControllerEventListener != null)
            this.objLayerControllerEventListener.onLayerRemoveComplete(this);
        
        //alert("Finished");
    }               
}//end class MapLayer
