/*************************************************************************[info]
  JS DOCUMENT:        GoogleMap.js
  DATA:               29/10/2008
  COMPANY:            Onlime S.n.c.
 
  LAST EDIT:          23/02/09

  PURPOSE:            GoogleMap object
  
  CHANGES:
  --------
  -
    
  TODO LIST:
  ----------  
  -...
*******************************************************************************/
(function(){
/*******************************************************************************
  [GOOGLEMAP OBJECT]  
*******************************************************************************/
var listenerGoogleMap = null; // event.listener

GoogleMap = function( obj, parameters )
{ 
  this.map                  = null;         // GMap2
  this.obj                  = null;         // DOM
  this.objLoaderMarkers     = null;         // DOM
  this.typeControl          = null;
  this.mapControl           = null;
  this.geocoder             = null;         // GClientGeocoder
  this.markers              = [];           // Array GMarker
  this.tmpArrMarkersDetail  = null;
  this.tabAccuracy          = new Array(2,4,6,10,12,13,16,16,17); 
  
  // Richiamo l'inizializzazione
  this.init( obj, parameters );
}

/** init
@obj
@parameters small_controls
@parameters default_area[zoom,luogo]
@parameters AjaxCall
@parameters loaderMarkers
*/
GoogleMap.prototype.init = function( obj, parameters  )  //default_area, small_controls
{ 
  parameters = parameters || {};
   
  if ( !$(obj) ) return null;
  this.obj = $(obj);
  
  // sembra che risolvi i problemi di centramento punti..
  var opts = {
    size: new GSize( parseInt( $(obj).fn.css('width') ), parseInt( $(obj).fn.css('height') ) )
  };
  
  this.map = new GMap2( this.obj, opts );
  
  if ( !this.map ) return null;
  
  // Attach eventi window.unload
  if ( !listenerGoogleMap ) 
  {
    listenerGoogleMap = $E.add( window, "unload", GUnload, false ); // event.listener
  } 
  
  if ( parameters["setUIToDefault"] === true )
  {
    this.map.setUIToDefault();
  }
  else
  {
    // mappa - satellite - ibrida
    this.typeControl = new GMapTypeControl();
    this.map.addControl( this.typeControl );
    
    if ( parameters["small_controls"] === true )
    {
      // controller small
      this.mapControl = new GSmallMapControl();
      this.map.addControl( this.mapControl );
    }
    else
    {
      // controller con barra vert
      this.mapControl = new GLargeMapControl();
      this.map.addControl( this.mapControl );
      
      // zoom box, in basso a dx
      this.map.addControl( new GOverviewMapControl(), new GControlPosition(G_ANCHOR_BOTTOM_RIGHT, new GSize(9, 9)) );
    }
  }
  
  this.geocoder = new GClientGeocoder();
  
  if ( parameters["default_area"] )
  {
    var fn = function(point) 
      {
        if (!point) 
        {
          //alert(default_area['luogo'] + " not found");
        } 
        else
        {                 
           var zoom = parameters["default_area"]["zoom"] || 3;
           this.map.setCenter( point , zoom );
        }
      }
    fn = fn.bind ( this );
       
    this.geocoder.getLatLng( parameters["default_area"]["luogo"], fn );  
  }
  else
  {
    
    // Milano ...
    //this.map.setCenter(new GLatLng(45.470364,9.19487), 7);
  }
  
  if ( parameters["loaderMarkers"] === true ) this.addLoaderMarkers();
  if ( parameters["AjaxCall"] )               this.extractingAjaxXmlData( parameters["AjaxCall"] );
};

// required response Xml
GoogleMap.prototype.extractingAjaxXmlData = function ( objAjax, callbackFn )
{
  if ( objAjax )
  {
    var objGoogleMap = this;  // Closure
    
    if ( !objAjax.operation )
    {
      objAjax.responseType = "XML";
      objAjax.operation = function( responseXml )
        {
          var arrData = retriveRcFromXml( "arrMarkers", responseXml );
          if ( arrData )
          {
            objGoogleMap.createMarkers( arrData, callbackFn );
          }
        };
    }  
    // Chiamata Ajax  
    objAjax.sendData();  
  }
};

GoogleMap.prototype.extractingAjaxJSONData = function ( objAjax, callbackFn ){};

GoogleMap.prototype.fitMap = function ( points ) 
{
  var bounds = new GLatLngBounds();
  for (var i=0; i< points.length; i++) {
  bounds.extend(points[i]);
  }
  this.map.setZoom( this.map.getBoundsZoomLevel(bounds) );
  this.map.setCenter( bounds.getCenter() );
};
  
/* */
GoogleMap.prototype.removeMapControl = function()
{ 
  if ( this.mapControl )
  {
    this.map.removeControl( this.mapControl );
  }
};

/* */
GoogleMap.prototype.centerMap = function ( area )
{
  var fn = function(point) 
    {
      if (!point) 
      {
        return false;
      } 
      else
      {
         var zoom = area[1] || 3;
         this.map.setCenter( point , zoom );  // closure ?
         return true;
      }
     };
  fn = fn.bind ( this );
     
  this.geocoder.getLatLng( area[0], fn );
};

/* */
GoogleMap.prototype.centerMapWithAccuracy = function( strLocation ) 
{
  if (this.geocoder) 
  {
    var fn = function(response) 
      {
        if(response.Status.code!=200)
        {
          // alert('"' + address + '" not found');
        } 
        else 
        {
          place = response.Placemark[0];
          accuracy = place.AddressDetails.Accuracy;
          this.map.setCenter(
            new GLatLng(place.Point.coordinates[1],
            place.Point.coordinates[0]), this.tabAccuracy[accuracy]   // closure ?
          );
        }
      }
    fn = fn.bind ( this );
      
    this.geocoder.getLocations( strLocation, fn );
  }
};

/* */
GoogleMap.prototype.addLoaderMarkers = function( idTxtObj )
{
  if ( ! $(idTxtObj) )
  {
    var spanLoader = createElement( "span" );
    if ( idTxtObj ) spanLoader.setAttribute( "id",idTxtObj ); 
    
    spanLoader.style.cssText = ("position:absolute;"
                              + "top:0;" 
                              + "left:0;"
                              + "z-index:2;"  
                              + "width:100%;" 
                              + "height:100%;"
                              + "color:#FFF;"
                              //+ "background:#000 url('"+PATH_GOOGLEMAP+"img/loader.gif') center center no-repeat;" 
                              + "display:none;");
    
    
    this.objLoaderMarkers = $( this.obj.appendChild( spanLoader ) ) ;
  }
};

/* */
GoogleMap.prototype.createMarkers = function( arrMarkersDetail, callbackFn )
{
  if ( callbackFn ) this.prcCreateMarkers.callbackFn = callbackFn;
  
  this.tmpArrMarkersDetail = arrMarkersDetail;
  
  if ( this.objLoaderMarkers ) this.objLoaderMarkers.fn.UI.openAndFadeIn(null,{"v":20});
  
  this.prcCreateMarkers( 0 );
};

/* */
GoogleMap.prototype.prcCreateMarkers = function( idx )
{
  if ( this.tmpArrMarkersDetail )
  { 
    if ( this.tmpArrMarkersDetail[idx] )
    {
      if ( this.objLoaderMarkers )
      {
        this.objLoaderMarkers.innerHTML = ("Please wait, loading marker ... " + (idx+1) + " / "+ this.tmpArrMarkersDetail.length);
      }
      
      this.createMarker( idx, this.tmpArrMarkersDetail[idx] );
    }
    else
    {
      this.tmpArrMarkersDetail = null;
      
      if ( this.objLoaderMarkers )
      {
        var fn = function () {
            this.objLoaderMarkers.value = "";
            this.objLoaderMarkers.fn.UI.fadeOutAndClose({"v":10});                    
          }.bind( this );
        
        fn = fn.bind( this );
        window.setTimeout( fn, 1000 ); // per evitare problemi simultaneata' fadeIn/fadeOut
      }
      
      if ( this.prcCreateMarkers.callbackFn )
      {
        var temp = this.prcCreateMarkers.callbackFn;
        this.prcCreateMarkers.callbackFn = null;
        temp();
      }  
    }
  }
};

GoogleMap.prototype.createMarkers.callbackFn = null;

/** createMarker
@indice
@markerDetail address
@markerDetail icon
@markerDetail title
@markerDetail hide
@markerDetail setcenter
@markerDetail panTo
@markerDetail description
@markerDetail cbFn
*/ 
GoogleMap.prototype.createMarker = function ( indice, markerDetail ) 
{
  if (this.geocoder) 
  {
    var managerFunction = function( idx, point ) 
      {
        if (!point) 
        {
          //alert( indice + " not found");
          this.markers[idx] = null;
        } 
        else 
        { 
          /* Creazione icona marker & setting proprietá */
          var colorIcon = new GIcon(G_DEFAULT_ICON);
          colorIcon.image = markerDetail["icon"];
          colorIcon.iconSize = new GSize(32, 32);
          
          colorIcon.iconAnchor = new GPoint(15, 31);
          colorIcon.infoWindowAnchor = new GPoint(15, 9);
          colorIcon.shadow = null;
          
          /* AL MOMENTO NN UTILIZZATI
          // baseIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
          // baseIcon.shadowSize = new GSize(37, 34);
          // baseIcon.iconAnchor = new GPoint(9, 34);
          // baseIcon.infoWindowAnchor = new GPoint(9, 2);
          // baseIcon.infoShadowAnchor = new GPoint(18, 25);
          */
                          
          /* Set up Oggetto GMarkerOptions */
          markerOptions = { icon:colorIcon };
          if ( markerDetail["title"] ) markerOptions["title"] = markerDetail["title"];
          
          var marker = new GMarker(point,markerOptions);
          this.map.addOverlay(marker);
          
          if ( markerDetail["hide"] == 0 ) marker.hide();
          
          /* Centramento su punto e zoom se viene richiesto il centramento */
          if ( markerDetail["setcenter"] ) 
          {
            this.map.setCenter( point,14 );
          }
          
          /* panTo se viene richiesto l'effetto */
          if ( markerDetail["panTo"] ) 
          {
            this.map.panTo( point );
          }
          
          /* Attach evento onclick su marker se vi è descrizione */
          if ( markerDetail["description"] )
          {
            var fn = function()
            {
              //var opts = {pixelOffset:new GSize(32,5), maxWidth:250};
              var opts = null;
              marker.openInfoWindowHtml(markerDetail["description"],opts); 
            }
            GEvent.addListener( marker, "click", fn );  
          }
          
          // In caso di richiesta di callbackFn la attacco al click
          if ( markerDetail["cbFn"] )
          {
            if ( typeof( markerDetail["cbFn"] ) =='string' )
            {
              //...
            }  
            GEvent.addListener( marker, "click", markerDetail["cbFn"] );
          }
           
          this.markers[idx] = marker;
        }
        
        this.prcCreateMarkers( idx+1 );
      };
      
    managerFunction = managerFunction.bind( this,indice );
      
    this.geocoder.getLatLng( markerDetail["address"], managerFunction );
  }
};
/*******************************************************************************
  [END GOOGLEMAP OBJECT]  
*******************************************************************************/
})();
