dojo.require('gmap.src');

dojo.provide('gmap.controls');

dojo.declare( 'gmap.controls', null,
{
    baseURL: '',		// URL de base (récupérée via ezurl())
    gmap: null,			// La GMap à laquelle ajouter les contrôles
    panAmpl: 10,		// Le nombre de pixels auquel correspond un pan
    arrHandler: [],		// Le tableau des handlers des connections
    centerLat: 0,		// La latitude où recentrer la carte
    centerLng: 0,		// La longitude où recentrer la carte
    domPanZoomControl: null,	// Le div correspondant aux contrôles de zoom et de pan
    domMapTypeControl: null,	// Le div correspondant au contrôle de choix de type de carte

    /**
     * Constructeur
     * @param params Les paramètres à passer au constructeur
     * @param srcNodeRef Le noeud de référence
     */
    constructor: function( params, srcNodeRef )
    {
	this.gmap = params.gmap;
	this.panAmpl = params.panAmpl;
	this.baseURL = params.baseURL;
	this.centerLat = params.lat;
	this.centerLng = params.lng;
	// CONSTRUCTION
	this.buildPanZoomControl();
	this.buildMapTypeControl();
	
	// CONNECTION
	this.arrHandler = [];
	this.arrHandler.push( google.maps.event.addListenerOnce(  this.gmap, 'idle', dojo.hitch( this, this.idleReceived ) ) );
    },
    
    idleReceived : function(){
    	setTimeout(dojo.hitch( this, this.connect ),1000);
    },
    
    /**
     * Construction du contrôle de zoom et pan et ajout dans le dom
     */    
    buildPanZoomControl: function()
    {
	var innerHTML =
	
	// PAN CONTROL
	'<p class="notxt">'
	.concat( ezjs.i18n( 'opievoy/gmap', 'Panning the map', '', {}, this.baseURL ) )
	.concat( '</p><ul class="move"><li><button id="moveTop"><span>' )
	.concat( ezjs.i18n( 'opievoy/gmap', 'Pan up', '', {}, this.baseURL ) )
	.concat( '</span></button></li><li><button id="moveRight"><span>' )
	.concat( ezjs.i18n( 'opievoy/gmap', 'Pan right', '', {}, this.baseURL ) )
	.concat( '</span></button></li><li><button id="moveBottom"><span>' )
	.concat( ezjs.i18n( 'opievoy/gmap', 'Pan down', '', {}, this.baseURL ) )
	.concat( '</span></button></li><li><button id="moveLeft"><span>' )
	.concat( ezjs.i18n( 'opievoy/gmap', 'Pan left', '', {}, this.baseURL ) )
	.concat( '</span></button></li><li><button id="moveCenter"><span>' )
	.concat( ezjs.i18n( 'opievoy/gmap', 'Move to center of the county', '', {}, this.baseURL ) )
	.concat( '</span></button></li></ul>' )
	
	// ZOOM CONTROL
	.concat( '<p class="notxt">' )
	.concat( ezjs.i18n( 'opievoy/gmap', 'Setting zoom level', '', {}, this.baseURL ) )
	.concat( '</p><ul class="zoom"><li><a title="' )
	.concat( ezjs.i18n( 'opievoy/gmap', 'Zoom in', '', {}, this.baseURL ) )
	.concat( '" id="zoomin" href="#map_ancre"><span>' )
	.concat( ezjs.i18n( 'opievoy/gmap', 'Zoom in', '', {}, this.baseURL ) )
	.concat( '</span></a></li><li><a title="zoom 11" id="zoomlevel11" href="#map_ancre"><span>11</span></a></li><li><a title="zoom 10" id="zoomlevel10" href="#map_ancre"><span>10</span></a></li><li><a title="zoom 9" id="zoomlevel9" href="#map_ancre"><span>9</span></a></li><li><a title="zoom 8" id="zoomlevel8" href="#map_ancre"><span>8</span></a></li><li><a title="zoom 7" id="zoomlevel7" href="#map_ancre"><span>7</a></span></li><li><a title="zoom 6" id="zoomlevel6" href="#map_ancre"><span>6</span></a></li><li><a title="zoom 5" id="zoomlevel5" href="#map_ancre"><span>5</span></a></li><li><a title="zoom 4" id="zoomlevel4" href="#map_ancre"><span>4</span></a></li><li><a title="zoom 3" id="zoomlevel3" href="#map_ancre"><span>3</span></a></li><li><a title="zoom 2" id="zoomlevel2" href="#map_ancre"><span>2</span></a></li><li><a title="zoom 1" id="zoomlevel1" href="#map_ancre"><span>1</span></a></li><li><a title="zoom 0" id="zoomlevel0" href="#map_ancre"><span>0</span></a></li>' )
	.concat( '<li><a title="' )
	.concat( ezjs.i18n( 'opievoy/gmap', 'Zoom out', '', {}, this.baseURL ) )
	.concat( '" id="zoomout" href="#map_ancre"><span>' )
	.concat( ezjs.i18n( 'opievoy/gmap', 'Zoom out', '', {}, this.baseURL ) )
	.concat( '</span></a></li></ul>' )

	this.domPanZoomControl = dojo.create( 'div', {'class': 'controls', innerHTML: innerHTML} );
	this.gmap.controls[google.maps.ControlPosition.TOP_LEFT].push( this.domPanZoomControl );
    },
    
    /**
     * Construction du contrôle de choix de type de carte
     */ 
    buildMapTypeControl: function()
    {
	var innerHTML = 
	    
	'<p class="notxt">'
	.concat( ezjs.i18n( 'opievoy/gmap', 'Map type', '', {}, this.baseURL ) )
	.concat( '</p><ul class="view"><li><button id="normalView">' )
	.concat( ezjs.i18n( 'opievoy/gmap', 'Normal', '', {}, this.baseURL ) )
	.concat( '</button></li><li><button id="hybrideView">' )
	.concat( ezjs.i18n( 'opievoy/gmap', 'Hybrid', '', {}, this.baseURL ) )
	.concat( '</button></li></ul>' )
	;

	this.domMapTypeControl = dojo.create( 'div', {'class': 'controls', innerHTML: innerHTML} );
	this.gmap.controls[google.maps.ControlPosition.TOP_RIGHT].push( this.domMapTypeControl );
    },
        
    /**
     * Connection des contrôles aux méthodes de contrôle de la carte
     */        
    connect: function()
    {
	// CONNECTER LES BOUTONS AUX METHODES
	this.arrHandler.push( google.maps.event.addDomListener( dojo.byId( 'zoomin' ) , 'click', dojo.hitch( this, this.zoomIn ) ) );
	this.arrHandler.push( google.maps.event.addDomListener( dojo.byId( 'zoomout' ) , 'click', dojo.hitch( this, this.zoomOut ) ) );
	this.arrHandler.push( google.maps.event.addDomListener( dojo.byId( 'moveTop' ) , 'click', dojo.hitch( this, this.panUp ) ) );
	this.arrHandler.push( google.maps.event.addDomListener( dojo.byId( 'moveRight' ) , 'click', dojo.hitch( this, this.panRight ) ) );
	this.arrHandler.push( google.maps.event.addDomListener( dojo.byId( 'moveBottom' ) , 'click', dojo.hitch( this, this.panDown ) ) );
	this.arrHandler.push( google.maps.event.addDomListener( dojo.byId( 'moveLeft' ) , 'click', dojo.hitch( this, this.panLeft ) ) );
	this.arrHandler.push( google.maps.event.addDomListener( dojo.byId( 'moveCenter' ) , 'click', dojo.hitch( this, this.moveCenter ) ) );
	this.arrHandler.push( google.maps.event.addDomListener( dojo.byId( 'normalView' ) , 'click', dojo.hitch( this, this.setMapTypeId, google.maps.MapTypeId.ROADMAP ) ) ); 
	this.arrHandler.push( google.maps.event.addDomListener( dojo.byId( 'hybrideView' ) , 'click', dojo.hitch( this, this.setMapTypeId, google.maps.MapTypeId.HYBRID ) ) ); 
	for( var i = 0 ; i < 12 ; ++i )
	{
	    this.connectZoomButton( i );
	}
	
	// FIXER UNE CLASSE SUR LE ZOOM ACTIF
	var domButton = dojo.byId( 'zoomlevel'.concat( this.gmap.zoom - this.gmap.minZoom ) );
	dojo.addClass( domButton.parentNode, 'current' );	
	
	// POUR FAIRE APPARAITRE L'ICONE STREET VIEW, FORCER LE CHANGEMENT DE TYPE DE CARTE
	this.gmap.setMapTypeId( google.maps.MapTypeId[ezjs.ini( 'GMapSettings', 'MapTypeId', 'gmap.ini', this.baseURL )] );	
	
	// METTRE A JOUR LE SLIDER DU ZOOM
	this.arrHandler.push( google.maps.event.addListener( this.gmap, 'zoom_changed', dojo.hitch( this, this.refreshSlider ) ) );
    },
    
    /**
     * Connecter un bouton du slider du zoom
     */       
    connectZoomButton: function( i )
    {
	this.arrHandler.push( google.maps.event.addDomListener( dojo.byId( 'zoomlevel'.concat( i ) ) , 'click', dojo.hitch( this, this.setZoom, i ) ) );
    },
    
    /**
     * Mise à jour des styles dans le slider pour prendre en considération le niveau de zoom actuel
     */      
    refreshSlider: function()
    {
	for( var i = 0 ; i < 12 ; ++i )
	{
	    var domButton = dojo.byId( 'zoomlevel'.concat( i ) );
	    dojo.removeClass( domButton.parentNode, 'current' );
	}
	domButton = dojo.byId( 'zoomlevel'.concat( this.gmap.zoom - this.gmap.minZoom ) );
	dojo.addClass( domButton.parentNode, 'current' );
    },
    
    /**
     * Recentrer la carte aux coordonnées initiales
     */        
    moveCenter: function()
    {
	this.gmap.setCenter( new google.maps.LatLng( this.centerLat, this.centerLng ) );
    },
    
    /**
     * Incrémenter le niveau de zoom
     */     
    zoomIn: function()
    {
	if( this.gmap.zoom - this.gmap.minZoom < 11 )
	{
	    this.setZoom( this.gmap.zoom - this.gmap.minZoom + 1 );
	}
    },
    
    /**
     * Décrémenter le niveau de zoom
     */     
    zoomOut: function()
    {
	if( this.gmap.zoom > this.gmap.minZoom )
	{	
	    this.setZoom( this.gmap.zoom - this.gmap.minZoom - 1 );
	}
    },   
    
    /**
     * Fixer le niveau de zoom
     * @param i int Niveau de zoom à fixer
     */     
    setZoom: function( i )
    {
	this.gmap.setZoom( i + this.gmap.minZoom );
	this.refreshSlider();
    },
    
    /**
     * Se déplacer vers le haut
     */  
    panUp: function()
    {
	this.gmap.panBy( 0, -this.panAmpl );
    },

    /**
     * Se déplacer vers la droite
     */  
    panRight: function()
    {
	this.gmap.panBy( this.panAmpl, 0 );
    },
    
    /**
     * Se déplacer vers le bas
     */      
    panDown: function()
    {
	this.gmap.panBy( 0, this.panAmpl );
    },
    
    /**
     * Se déplacer vers la gauche
     */      
    panLeft: function()
    {
	this.gmap.panBy( -this.panAmpl, 0 );
    },
    
    /**
     * Fixer le type de carte
     * @param typeID google.maps.MapTypeId Type de la carte à afficher
     */         
    setMapTypeId: function( typeId )
    {
	this.gmap.setMapTypeId( typeId );
    },
    
    /**
     * Destructeur
     */    
    destroy: function()
    {
	// DECONNECTE LES CONTROLES
	var h;
	while ((h = this.arrHandler.pop()) != undefined)
	{
		dojo.disconnect(h);
	}
	
	// RETIRE LES CONTROLES DE LA CARTE
	while( this.gmap.controls[google.maps.ControlPosition.TOP_RIGHT].pop() != undefined );
	while( this.gmap.controls[google.maps.ControlPosition.TOP_LEFT].pop() != undefined );
	
	// SUPPRIME LES NOEUDS
	dojo.destroy( this.domPanZoomControl );
	dojo.destroy( this.domMapTypeControl );
    }    
    
}); 
