/** 
 * @fileoverview This class contains the data to view EGV map and GE plugin
 *  and functions to transform coordinates
 *
 * @author Martí Pericay marti.pericay@geodata.es
 * @version 1.0 
 * @requires class.wcts.js
 */
 
 
//************************************************************************
// Public methods
//************************************************************************

/**
 * Creates the bbox object from a Localizers object
 * @param {object} element Localizers element
 * @param {int} maxscale to show the elements
 * @param {tilt} tilt for Google Earth (GE)
*/

	// Create from localizers file
	bBox.prototype.createFromLocalizers = function (element,maxscale,tilt) {

	  // parse data (where to click) parameters
	  this._parseData(element);
    
	  // parse extent parameters
	  if(element.extent_wkt) {
			var box = element.extent_wkt.slice(element.extent_wkt.indexOf("(")+1,element.extent_wkt.indexOf(")"));
			box = box.replace(","," ");
			var box_array = box.split(" ");
		} else if(element.extent) {
			var box_array = element.extent.split(",");
	  }
	  
    if(box_array) {
	    this.minx = box_array[0];
	    this.miny = box_array[1];	
	    this.maxx = box_array[2];
	    this.maxy = box_array[3];
	    this._box2scale();
	  } 

  	if(this.data && maxscale) {
  		// we recalculate the extent if a maxscale is required or if there was no extent
		  if((!box_array) || (this.scale < maxscale)) {
		    // we use element.data and the maxscale
		    this.centerx = this.datax;
		    this.centery = this.datay;
		    this.scale = maxscale;
		    this._scale2box();
		  }
		}
	  
	  if(this.hasGoogleEarth) this._parseGoogle(tilt);
	  
	  return true;
		
	} 
	
// Create from egv extent
	bBox.prototype.createFromMap = function (map,tilt) {	
		
    this.minx = map.extent.left;
    this.miny = map.extent.bottom;	
    this.maxx = map.extent.right;
    this.maxy = map.extent.top;
    
    this._box2scale();
		
		if(this.hasGoogleEarth) this._parseGoogle(tilt);
		
		return true;
	}

// Create from GE view
	bBox.prototype.createFromLatLong = function (longitude,latitude,altitude,tilt) {	
		
    this.ge.camheight = altitude;
    this.ge.centerx = longitude;
    this.ge.centery = latitude;
    this.ge.camtilt = tilt;

    var coords = this.converter.ged2utm(this.ge.centerx, this.ge.centery);
    
    this.centery = coords[1];
    this.centerx = coords[0];
    this.scale = altitude * this.altitude2scale;

    this._scale2box();
    
    return true;
	}	
	

//************************************************************************
// Private methods
//************************************************************************

/**
 * switch between point+scale and bounding box
*/
bBox.prototype._box2scale = function(){
  this.centerx = (parseFloat(this.maxx) + parseFloat(this.minx)) / 2;
	this.centery = (parseFloat(this.maxy) + parseFloat(this.miny)) / 2;
	
	var width = this.maxx - this.minx;
	this.scale = this.dpi * 100 * width / this.width / this.cpi;	
}
		
bBox.prototype._scale2box = function(){
	
	var metersW = this.scale * (this.width/(this.dpi * 100 / this.cpi));
	var metersH = metersW * this.height / this.width;
	
	this.minx = Math.round(this.centerx - metersW/2);
	this.maxx = Math.round(this.centerx) + Math.round(metersW/2);
	this.miny = Math.round(this.centery - metersH/2);
	this.maxy = Math.round(this.centery) + Math.round(metersH/2);
}	

bBox.prototype._parseData = function(element){
	  this.data = false;
	  if(element.data_wkt) {
	    var point_array = element.data_wkt.slice(element.data_wkt.indexOf("(")+1,element.data_wkt.indexOf(")"));
	    var point = point_array.split(" ");
		} else if(element.data) {
			var point = element.data.split(",");
	  }
	  if(point) {
	    this.datax = point[0];
	    this.datay = point[1];
	    this.data = true;
	  }
}
	
/**
 * parse google earth parameters
*/

bBox.prototype._parseGoogle = function(tilt){
	
	this.ge = new Object();
	var bl = this.converter.utm2ged(this.minx, this.miny);
	var tr = this.converter.utm2ged(this.maxx, this.maxy);
  this.ge.minx = bl[0];
  this.ge.miny = bl[1];	
  this.ge.maxx = tr[0];
  this.ge.maxy = tr[1];

	this.ge.camtilt = (tilt === false) ? this.defaulttilt : tilt;
	  
	this.ge.centerx = (parseFloat(this.ge.maxx) + parseFloat(this.ge.minx)) / 2;
	this.ge.centery = (parseFloat(this.ge.maxy) + parseFloat(this.ge.miny)) / 2;								
	
	//to adjust camheight and make it relative to scale
	this.ge.camheight = this.scale / this.altitude2scale;
	this.ge.camheight_degrees = (Math.asin(this.ge.camheight/this.earthradii))*(180/this.pi);
	
	// move the center backwards to try to center the view
	this.ge.camcentery = this.ge.centery;
	if(this.ge.camtilt) this.ge.camcentery -= this.ge.camheight_degrees * Math.tan(this.ge.camtilt*(this.pi/180));
}
		
//************************************************************************
// Constructor
//************************************************************************
/**
 * Constructs an empty bbox object.
 * @class
 * This is the main object   
 * @constructor
 * @return A new bbox object
 */
function bBox(hasGE){

	// REQUIRES WCTS CLASS !!!!!
	this.converter = new wcts();
	
  //informs if it we need the coords also in latlong, and weird camera positions
  this.hasGoogleEarth = hasGE;	
	
  //constants
  this.pi = Math.PI;
  this.dpi = 80;
  this.cpi = 2.54; 
  this.earthradii = 6365000; 
  
  // we assume proportionality between scale and camera altitude
  this.altitude2scale = 4.2;
  
	// GOOGLE EARTH CAMERA PARAMETERS
	this.defaulttilt = 45;  
}