
/**
 * @requires core/Control.js
 */

/*

		TODO:
			locales
			doc
			style (global?)
			create a hotspot class using x,y, layer and html atributes

*/

MapTipsCustom = OpenLayers.Class(eGV.Control,{
 
     /** 
     * APIProperty: Map object
     * {<OpenLayers.Map>} 
     */	
 		map: null,		
		
		div: null,
	 /** 
     * Property: hotspots
     * (json object)
     */
		hotspots: null,
	/** 
     * Property: divWidth
     * (integer)
     */
		divWidth:100,
	/** 
     * Property: xMargin
     * (integer)
     */		
		xMargin:0,
		
    /**
     * Constructor: eGV.Control.MapTips
     *
     * Parameters:
     * options - {Object} Hashtable of extra options to tag onto the control
     */  
	initialize: function(options){
						
			this.hotspots = options.hotspots;

            options = options || [];
            eGV.Control.prototype.initialize.apply(this, [options]);

     		this.displayClass = 
      		this.CLASS_NAME.replace("eGV.", "egv").replace(/\./g, "");
			
			OpenLayers.Util.extend(this, options);

			if (!this.map || typeof(this.map) == "function") {
				this.map = eGV.getMap();
			}
			
			this.div = document.createElement('div'); 
			this.div.style.zIndex = this.map.Z_INDEX_BASE['Control'] +
                                    this.map.controls.length;
			this.div.style.width = this.divWidth;
            this.div.style.position = "relative";
			this.map.viewPortDiv.appendChild(this.div);		
			OpenLayers.Element.addClass(this.div, this.displayClass);

			this.setMap();
			


		},
	 /**
     * Method: setMap
     */	
	setMap: function() {
           eGV.Control.prototype.setMap.apply(this);
			this.map.events.register("mousemove", this , this.showTips);
			OpenLayers.Event.observe(this.div, "mousemove", this.block);
            this.map.events.register("movestart", this , OpenLayers.Function.bindAsEventListener(this.hideTips, {"divTips":this.div}));
            
            return this.map;
    },		
	 /**
     * Method: destroy
     */	
    destroy: function() {
         if (this.map) {
             this.map.events.unregister('mousemove', this, this.showTips);
         }
         eGV.Control.prototype.destroy.apply(this, arguments);
    },	
   	/**
     * Method: block
     * Parameters:
     * evt - mouse event
     */	
    block:function(evt){
        OpenLayers.Event.stop(evt);
  	},
   	/**
     * Method: showTips
     * Parameters:
     * evt - mouse event
     */		
    showTips:function(evt) {

      var lonLat = this.getCoords(evt);
      this.drawTips(lonLat, evt);
		
    },
   	/**
     * Method: getCoords
     * Parameters:
     * evt - mouse event
     */	
    getCoords:function(evt) {
     	var lonLat;
     	  if (evt == null) {
            lonLat = new OpenLayers.LonLat(0, 0);
        } else {

            lonLat = this.map.getLonLatFromPixel(evt.xy);
            
	        var projSrc = this.map.getProjectionObject();
	        var projDest = this.map.displayProjection;
	        if(projDest != null && projSrc.projCode != projDest.projCode)
	        	lonLat.transform(projSrc, projDest);
	        
            if (!lonLat) { 
                // map has not yet been properly initialized
                return;
            }    
        }
     	  return lonLat;
				
    },

    hideTips: function(evt) {
        this.divTips.style.visibility = "hidden";
    },

   	/**
     * Method: drawTips
     * Parameters:
     * evt - mouse event
     * lonLat - OpenLayers.LonLat
     */			
    drawTips:function(lonLat, evt) {
        if (this.hotspots) {
            // local variables
            var nTolerance = Math.abs(this.map.getExtent().left - this.map.getExtent().right)/75;

            // find hotspot
            var closest = { "distance": nTolerance*nTolerance, "index": false, "x": 0, "y": 0 };
            for (var i=0; i<this.hotspots.length; i++) {
                if (this.hotspots[i]) {
                    if (this.checkVisible(this.hotspots[i])) {
                        var dx = Math.abs(lonLat.lon -  this.hotspots[i].x);
                        var dy = Math.abs(lonLat.lat - this.hotspots[i].y);
                        var dm = dx*dx + dy*dy;
                        if (dm < closest.distance) {
                            closest.distance = dm;
                            closest.index = i;
                        }
                    }
                }
            }

            // show map tip
            if (closest.index !== false) {
                if (closest.index !== this.mapTipCurrentIndex) {
                    hotspot = this.hotspots[closest.index];
                    x=evt.xy.x;
                    y=evt.xy.y;
                    this.div.style.visibility="visible";
                    this.div.innerHTML=hotspot.html;
                    if (this.map.size.w - x < this.divWidth) x -= this.divWidth;
                    this.div.style.left=(this.xMargin + x -5)+'px';
                    if (this.map.size.h - y < this.div.offsetHeight) y -= this.div.offsetHeight;
                    this.div.style.top=y -5 +'px';
                }
            } else {
                if(this.div){
                    this.div.style.visibility="hidden";
                }
            }
            this.mapTipCurrentIndex = closest.index;
        }
    },

   	/**
     * Method: block
     * Parameters:
     * value - hotspot (Object)
     */	
    checkVisible:function(value){
          var layer = null;
    	  if (value.layer){
    	  	for (i =0; i < this.map.connections.length; i ++){
    	  		currentConnection = this.map.connections[i];
                layer = currentConnection.getLayerByName(value.layer)
                if (layer) {
                  if (layer.getVisibility() === true)
                    return true;
                }
    	  	}// end for connections    	  	
    	  }
          return false;
    },

		 
		CLASS_NAME: "eGV.Control.MapTips"
	}
);