/*
	BUG JS:
	elemento.offsetWidth no detecta automáticamente la anchura
	de contenido dinámico dentro del div. elemento.offsetHeight
	si lo hace.
	
	Para que funcione correctamente hay que establecer el width
	del elemento por CSS
*/

function ViewPort(instanceName)
{
	this.instanceName = instanceName;
	this.containerId = instanceName + "contenedor";
	this.containedId = instanceName + "contenido";
	this.containerWidth = 0;
	this.containedWidth = 0;
	this.containerHeight = 0;
	this.containedHeight = 0;
	this.moveByPixelsX = 0;
	this.moveByPixelsY = 0;
	this.currentXOffset = 0;
	this.currentYOffset = 0;
	this.transitionSpeed = 1;
	this.clickThreshold = 200;
	this.interval = null;
	this.smoothScrollSpeed = 10;
	this.smoothScrollDuration = 0.05;
	this.smoothScrollInterval = 75;
	this.maximaAceleracion = 30;
	this.timer = 0;
	this.posiciones = new Array();
	this.posiciones[0] = Array(0,0);


	this.anyadeMapa = function (posicion, x, y)
	{
		this.posiciones[posicion] = Array(x, y);
	}

	this.moverTo = function (posicion)
	{
		coordenadas = this.posiciones[posicion];
		coordX = -coordenadas[0];
		coordY = -coordenadas[1];
		MoveByX = -(-this.currentXOffset + coordenadas[0]);
		MoveByY = -(-this.currentYOffset + coordenadas[1]);
		this.currentXOffset -= MoveByX;
		this.currentYOffset -= MoveByY;
		Effect.MoveBy(this.containedId, MoveByY, MoveByX, { duration: this.transitionSpeed, 
			queue: {position: 'end', scope: this.containedId, limit:3 }});
	}

	this.setMoveByPixelsX = function(pixels)
	{
		this.moveByPixelsX = pixels;
	}

	this.setMoveByPixelsY = function(pixels)
	{
		this.moveByPixelsY = pixels;
	}
	
	
	this.mover = function(direction)
	{
		Xoffset = this.moveByPixelsX;
		Yoffset = this.moveByPixelsY;
		
		if(direction == 'left')
		{
			Yoffset = 0;
			
			if( (this.currentXOffset + Xoffset + this.containerWidth) > this.containedWidth)
			{
				Xoffset = 0;
			}
			this.currentXOffset += Xoffset;
			Xoffset *= -1;
		}
		
		if(direction == 'right')
		{
			Yoffset = 0;
			
			if( (this.currentXOffset - Xoffset) < 0)
			{
				Xoffset = 0;
			}
			this.currentXOffset -= Xoffset;
		}
		
		if(direction == 'up')
		{
			Xoffset = 0;
			
			if( (this.currentYOffset + Yoffset + this.containerHeight) > this.containedHeight)
			{
				Yoffset = 0;
			}
			this.currentYOffset += Yoffset;
			Yoffset *= -1;
		}
		
		if(direction == 'down')
		{
			Xoffset = 0;
			
			if( (this.currentYOffset - Yoffset) < 0)
			{
				Yoffset = 0;
			}
			this.currentYOffset -= Yoffset;
		}
		
		Effect.MoveBy(this.containedId, Yoffset, Xoffset, {duration: this.transitionSpeed, 
			queue: {position: 'end', scope: this.containedId, limit:3}});
	}

	this.printHTML = function()
	{
		document.write("<div id='" + this.instanceName + "arriba'"); 
		document.write(" onmousedown=\"" + this.instanceName + ".setTimer('arriba');\"");
		document.write(" onmouseup=\"" + this.instanceName + ".veteArriba();\"");
		document.write(" onmouseout=\"" + this.instanceName + ".stopTimer();\"></div>");
		
		document.write("<div id='" + this.instanceName + "izquierda'"); 
		document.write(" onmousedown=\"" + this.instanceName + ".setTimer('izquierda');\"");
		document.write(" onmouseup=\"" + this.instanceName + ".veteIzquierda();\"");
		document.write(" onmouseout=\"" + this.instanceName + ".stopTimer();\"></div>");

		/*document.write("<div id='" + this.containerId + "'>");
		document.write("<div id='" + this.containedId + "'>" + contenido + "</div>");
		document.write("</div>");*/

		document.write("<div id='" + this.instanceName + "derecha'"); 
		document.write(" onmousedown=\"" + this.instanceName + ".setTimer('derecha');\"");
		document.write(" onmouseup=\"" + this.instanceName + ".veteDerecha();\"");
		document.write(" onmouseout=\"" + this.instanceName + ".stopTimer();\"></div>");
		
		document.write("<div id='" + this.instanceName + "abajo'"); 
		document.write(" onmousedown=\"" + this.instanceName + ".setTimer('abajo');\"");
		document.write(" onmouseup=\"" + this.instanceName + ".veteAbajo();\"");
		document.write(" onmouseout=\"" + this.instanceName + ".stopTimer();\"></div>");
		
		document.write("<div id='" + this.instanceName + "reset'"); 
		document.write(" onclick=\"" + this.instanceName + ".reset();\"></div>");
		
		this.inicializar();
	}

	this.inicializar = function()
	{
		this.containerWidth = $(this.containerId).offsetWidth;
		this.containedWidth = $(this.containedId).offsetWidth;
		this.containerHeight = $(this.containerId).offsetHeight;
		this.containedHeight = $(this.containedId).offsetHeight;
		this.moveByPixelsX = Math.floor(this.containedWidth / ((this.containedWidth / this.containerWidth)));
		this.moveByPixelsY = Math.floor(this.containedHeight / ((this.containedHeight / this.containerHeight)));
	}
	
	this.setTimer = function(direccion)
	{
		now = new Date();
		this.timer = now.getTime();
		
		if(direccion == 'arriba')
		{
			this.veteArribaSmooth();
		}
		
		if(direccion == 'abajo')
		{
			this.veteAbajoSmooth();
		}
		
		if(direccion == 'derecha')
		{
			this.veteDerechaSmooth();
		}
		
		if(direccion == 'izquierda')
		{
			this.veteIzquierdaSmooth();
		}
		
	}

	this.stopTimer = function()
	{
		clearInterval(this.interval);
	}

	this.veteArriba = function()
	{
		now = new Date();
		Yoffset = this.moveByPixelsY;
		
		if(now.getTime() < (this.timer + this.clickThreshold))
		{
			if( (this.currentYOffset - Yoffset) < 0)
			{
				Yoffset = this.currentYOffset;
			}
				
			this.currentYOffset -= Yoffset;
			
			clearInterval(this.interval);
			
			Effect.MoveBy(this.containedId, Yoffset, 0, {duration: this.transitionSpeed, 
			queue: {position: 'end', scope: this.containedId, limit:3}});
		}
		else
		{
			diferencia = this.currentYOffset - (Math.round(this.currentYOffset/this.moveByPixelsY)*this.moveByPixelsY);
			this.currentYOffset -= diferencia;
			Effect.MoveBy(this.containedId, diferencia, 0, {duration: this.transitionSpeed, 
			queue: {position: 'end', scope: this.containedId, limit:3}});
			clearInterval(this.interval);
		}
	}
	
	this.veteArribaSmooth = function()
	{
		now = new Date();
		
		if(now.getTime() > (this.timer + this.clickThreshold))
		{	
			Yoffset = this.acelera();
			
			if( (this.currentYOffset - Yoffset) < 0)
			{
				Yoffset = this.currentYOffset;
			}
			this.currentYOffset -= Yoffset;
		
			Effect.MoveBy(this.containedId, Yoffset, 0, {duration: this.smoothScrollDuration, 
			queue: {position: 'end', scope: this.containedId, limit:3}});
		}

		this.interval = setTimeout(this.instanceName + ".veteArribaSmooth()", this.smoothScrollInterval);
	}

	this.veteAbajo = function()
	{
		now = new Date();
		Yoffset = this.moveByPixelsY;
		
		if(now.getTime() < (this.timer + this.clickThreshold))
		{			
			if( (this.currentYOffset + Yoffset + this.containerHeight) > this.containedHeight)
			{
				Yoffset = this.containedHeight - this.currentYOffset - this.containerHeight;
				if(Yoffset < 0)
				{
					Yoffset = 0;
				}
			}
			
			this.currentYOffset += Yoffset;
			Yoffset *= -1;
			
			clearInterval(this.interval);
			
			Effect.MoveBy(this.containedId, Yoffset, 0, {duration: this.transitionSpeed, 
			queue: {position: 'end', scope: this.containedId, limit:3}});
		}
		else
		{
			if((this.currentYOffset + this.containerHeight) < this.containedHeight)
			{
				diferencia = this.currentYOffset - (Math.round(this.currentYOffset/this.moveByPixelsY)*this.moveByPixelsY);
				this.currentYOffset -= diferencia;
				Effect.MoveBy(this.containedId, diferencia, 0, {duration: this.transitionSpeed, 
				queue: {position: 'end', scope: this.containedId, limit:3}});
			}
			clearInterval(this.interval);
		}
	}
	
	this.veteAbajoSmooth = function()
	{
		now = new Date();
	
		if(now.getTime() > (this.timer + this.clickThreshold))
		{
			Yoffset = this.acelera();
			if((this.currentYOffset + Yoffset + this.containerHeight) > this.containedHeight)
			{
				Yoffset = this.containedHeight - this.currentYOffset - this.containerHeight;
			}
			this.currentYOffset += Yoffset;
			Yoffset *= -1;
		
			Effect.MoveBy(this.containedId, Yoffset, 0, {duration: this.smoothScrollDuration, 
			queue: {position: 'end', scope: this.containedId, limit:3}});
		}

		this.interval = setTimeout(this.instanceName + ".veteAbajoSmooth()", this.smoothScrollInterval);
	}

	this.veteDerecha = function()
	{
		now = new Date();
		Xoffset = this.moveByPixelsX;
		
		if(now.getTime() < (this.timer + this.clickThreshold))
		{						
			if( (this.currentXOffset + Xoffset + this.containerWidth) > this.containedWidth)
			{
				Xoffset = this.containedWidth - this.currentXOffset - this.containerWidth;
				if(Xoffset < 0)
				{
					Xoffset = 0;
				}
			}
			this.currentXOffset += Xoffset;
			Xoffset *= -1;
			
			clearInterval(this.interval);
			Effect.MoveBy(this.containedId, 0, Xoffset, {duration: this.transitionSpeed, 
			queue: {position: 'end', scope: this.containedId, limit:6}});
		}
		else
		{
			if((this.currentXOffset + this.containerWidth) != this.containedWidth)
			{
				diferencia = this.currentXOffset - (Math.round(this.currentXOffset/this.moveByPixelsX)*this.moveByPixelsX);
				this.currentXOffset -= diferencia;
				Effect.MoveBy(this.containedId, 0, diferencia, {duration: this.transitionSpeed, 
				queue: {position: 'end', scope: this.containedId, limit:6}});
			}
			clearInterval(this.interval);
		}
	}
	
	this.veteDerechaSmooth = function()
	{
		now = new Date();
	
		if(now.getTime() > (this.timer + this.clickThreshold))
		{
			Xoffset = this.acelera();
			if( (this.currentXOffset + Xoffset + this.containerWidth) > this.containedWidth)
			{
				Xoffset = this.containedWidth - this.currentXOffset - this.containerWidth;
			}
			this.currentXOffset += Xoffset;
			Xoffset *= -1;
		
			Effect.MoveBy(this.containedId, 0, Xoffset, {duration: this.smoothScrollDuration, 
			queue: {position: 'end', scope: this.containedId, limit:3}});
		}

		this.interval = setTimeout(this.instanceName + ".veteDerechaSmooth()", this.smoothScrollInterval);
	}

	this.veteIzquierda = function()
	{
		now = new Date();
		Xoffset = this.moveByPixelsX;
		Yoffset = this.moveByPixelsY;
		
		if(now.getTime() < (this.timer + this.clickThreshold))
		{						
			if( (this.currentXOffset - Xoffset) < 0)
			{
				Xoffset = this.currentXOffset;
			}
			this.currentXOffset -= Xoffset;
			
			clearInterval(this.interval);
			Effect.MoveBy(this.containedId, 0, Xoffset, {duration: this.transitionSpeed, 
			queue: {position: 'end', scope: this.containedId, limit:3}});
		}
		else
		{
			diferencia = this.currentXOffset - (Math.round(this.currentXOffset/this.moveByPixelsX)*this.moveByPixelsX);
			this.currentXOffset -= diferencia;
			Effect.MoveBy(this.containedId, 0, diferencia, {duration: this.transitionSpeed, 
			queue: {position: 'end', scope: this.containedId, limit:3}});
			clearInterval(this.interval);
		}
	}
	
	this.veteIzquierdaSmooth = function()
	{
		now = new Date();
	
		if(now.getTime() > (this.timer + this.clickThreshold))
		{
			Xoffset = this.acelera();
			if( (this.currentXOffset - Xoffset) < 0)
			{
				Xoffset = this.currentXOffset;
			}
			this.currentXOffset -= Xoffset;
		
			Effect.MoveBy(this.containedId, 0, Xoffset, {duration: this.smoothScrollDuration, 
			queue: {position: 'end', scope: this.containedId, limit:3}});
		}

		this.interval = setTimeout(this.instanceName + ".veteIzquierdaSmooth()", this.smoothScrollInterval);
	}

	this.reset = function()
	{
		x = this.currentXOffset;
		y = this.currentYOffset;

		this.currentXOffset = 0;
		this.currentYOffset = 0;
		
		Effect.MoveBy(this.containedId, y, x, {duration: 1, 
			queue: {position: 'end', scope: this.containedId, limit:3}});
	}

	this.acelera = function()
	{
		now = new Date();
		aceleracionPorUnidad = Math.round(this.maximaAceleracion / this.smoothScrollSpeed);
		
		velocidad = this.smoothScrollSpeed;
		factor = Math.round((now.getTime() - this.timer)/300);
		
		if(now.getTime() > (this.timer + 200))
		{
			velocidad = (aceleracionPorUnidad*factor) + this.smoothScrollSpeed;
		}
		
		if(velocidad > this.maximaAceleracion)
		{
			velocidad = this.maximaAceleracion + this.smoothScrollSpeed;
		}
		
		return velocidad;
	}

}
