
function EuclideanProjection(mapWidth, mapHeight, mapZoom){
	this.mapWidth = mapWidth;
	this.mapHeight = mapHeight;
	this.mapZoom = mapZoom;
	this.paddedMapWidth = new Array(mapZoom.length);
	this.paddedMapHeight = new Array(mapZoom.length);
	
	this.pixelsPerLonDegree=[];
	this.pixelsPerLonRadian=[];
	this.pixelsPerLatDegree=[];
	this.pixelsPerLatRadian=[];
	this.pixelOrigo=[];
	this.pixelsPadding=[];

	for(var d=0;d<mapZoom.length;d++){

		var currentwidth = (this.mapWidth * this.mapZoom[d])/100;
		var currentheight = (this.mapHeight * this.mapZoom[d])/100;
		this.paddedMapWidth[d] = Math.ceil(currentwidth/256)*256;
		this.paddedMapHeight[d] = Math.ceil(currentheight/256)*256;
		this.pixelsPerLonDegree.push(currentwidth*2/360);
		this.pixelsPerLonRadian.push(currentwidth*2/(2*Math.PI));
		this.pixelsPerLatDegree.push(currentheight*2/360);
		this.pixelsPerLatRadian.push(currentheight*2/(2*Math.PI));		
		this.pixelOrigo.push(new GPoint(this.paddedMapWidth[d]/2, this.paddedMapHeight[d]/2));
		this.pixelsPadding[d] = new GPoint( -0, -0);
//    this.pixelsPadding[d] = new GPoint( -(this.paddedMapWidth[d] - currentwidth)/18,
                                          //-(this.paddedMapHeight[d] - currentheight)/18);
    //alert(this.pixelsPadding[d])
	}
}

// == Attach it to the GProjection() class ==
EuclideanProjection.prototype=new GProjection();

/*
    	PictureProjection.prototype.fromLatLngToPixel = function (latlng, zoom)
    	{
    		var x = latlng.lng();
    		var y = latlng.lat();
    
    		// To show the origional formula, the below code is not optimized.
    		//x = x * (picture_width_array[zoom]*2) / 360 - (picture_width_array[zoom]*2)/2/2;
    		//y = y * (picture_height_array[zoom]*2) / 180 - (picture_height_array[zoom]*2)/2/2;    
    		
    		x = x * (picture_width*2*picture_zoom_array[zoom]/100) / 360 - (picture_width_array[zoom]*2)/2/2;
    		y = y * (picture_height*2*picture_zoom_array[zoom]/100) / 180 - (picture_height_array[zoom]*2)/2/2 - (picture_height_array[zoom] - (picture_height*picture_zoom_array[zoom]/100))/2;
    		
    		var p = new GPoint(x, y);
    
    		return  p;
    	}
*/

// == A method for converting latitudes and longitudes to pixel coordinates ==
EuclideanProjection.prototype.fromLatLngToPixel=function(a,b){

	var c=Math.round(this.pixelOrigo[b].x+a.lng()*this.pixelsPerLonDegree[b]);
	var i = 1;
	if (a.lat() < 0) i = -1;
	var delta = i*this.pixelsPadding[b].y * Math.abs(a.lat()/90);
	var d=Math.round(delta+this.pixelOrigo[b].y+(-2*a.lat())*this.pixelsPerLatDegree[b]);

	//var d = -Math.round(a.lat() * (this.mapHeight*2*this.mapZoom[b]/100) / 180 - this.paddedMapHeight[b]*2/2/2 - (this.paddedMapHeight[b] - (this.mapHeight*this.mapZoom[b]/100))/2);
	
	//alert(- (this.paddedMapHeight[b] - (this.mapHeight*this.mapZoom[b]/100))/2);
	// - (this.paddedMapHeight[b] - (this.mapHeight*this.mapZoom[b]/100))/2
	//- (this.paddedMapHeight[b]*2)/2/2
	return new GPoint(c,d);
};

/*
    	PictureProjection.prototype.fromPixelToLatLng = function (pixel, zoom, unbounded)
    	{
    		// To show the origional formula, the below code is not optimized.
    		//var lng = (pixel.x +  (picture_width_array[zoom]*2)/2/2) * 360 /(picture_width_array[zoom]*2);
    		//var lat = (pixel.y +  (picture_height_array[zoom]*2)/2/2) * 180 / (picture_height_array[zoom]*2);
    		//alert(zoom);
    		var lng = (pixel.x +  (picture_width_array[zoom]*2)/2/2) * 360 /(picture_width*2*picture_zoom_array[zoom]/100);
    		var lat = (pixel.y +  (picture_height_array[zoom]*2)/2/2 +  (picture_height_array[zoom] - (picture_height*picture_zoom_array[zoom]/100))/2 ) * 180 /(picture_height*2*picture_zoom_array[zoom]/100);
    		
    		p = new GLatLng(lat, lng);
    
    		return p;
*/

// == a method for converting pixel coordinates to latitudes and longitudes ==
EuclideanProjection.prototype.fromPixelToLatLng=function(a,b,c){
	var d=(a.x-this.pixelOrigo[b].x)/this.pixelsPerLonDegree[b];
	var i = 1;
	if (a.y > this.pixelOrigo[b].y) i = -1;
	var delta = -i*this.pixelsPadding[b].y * Math.abs((a.y-this.pixelOrigo[b].y)/this.pixelOrigo[b].y);
	var e=-0.5*(delta+a.y-this.pixelOrigo[b].y)/this.pixelsPerLatDegree[b];
	
	//var e = -(a.y +  (this.paddedMapHeight[b]*2)/2/2 +  (this.paddedMapHeight[b] - this.mapHeight*this.mapZoom[b]/100)/2 ) * 180 /(this.mapHeight*2*this.mapZoom[b]/100);


	//(this.paddedMapHeight[b] - (this.mapHeight*this.mapZoom[b]/100))/2
	//alert((this.paddedMapHeight[b]*2)/2/2 +  (this.paddedMapHeight[b] - (this.mapHeight*this.mapZoom[b]/100))/2 );
	//alert((this.paddedMapHeight[b] - (this.mapHeight*this.mapZoom[b]/100))/2);
	return new GLatLng(e,d,c);
};

// == a method that checks if the y value is in range, and wraps the x value ==
EuclideanProjection.prototype.tileCheckRange=function(a,b,c){
	var xb= Math.ceil(this.paddedMapWidth[b]/256*2);
	var yb= Math.ceil(this.paddedMapHeight[b]/256*2);

	if (a.y<0||a.y>=yb) {
		return false;
	}
	
	return true
}

// == a method that returns the width of the tilespace ==
EuclideanProjection.prototype.getWrapWidth=function(zoom) {
	return this.paddedMapWidth[zoom]*2;
}

