/*
Scroll - classe para criação de barras de rolagem no navegador

	Propriedades:
		- Conteudo: id do conteudo que vai receber o scroll
		- AreaVisivel: id da div com o overflow hidden do scroll
		- SetaCima: id do elemento html que vai ser a seta para cima do scroll
		- SetaBaixo: id do elemento html que vai ser a seta para baixo do scroll
		- BotaoArraste: id do elemento html que vai ser o botão de arraste do scroll
		- AreaArraste: id do elemento html que é a área de arraste do scroll
		- Velocidade: velocidade do scroll ao clicar nas setas
		- [TempoIntervalo]: tempo do intervalo entre o incremento dos passos do menu, para controlar melhor a velocidade caso a propriedade 'velocidade' não seja suficiente. Se for omitido, assume 1ms.
		
	Métodos:
		- Init(): inicia todos os eventos e todos os cálculos do scroll. Deve ser executado após serem atribuídas todas as propriedades do scroll
		- Posicionar(): posiciona o scroll em uma certa posição. Recebe essa posição como parametro.
		
*/

//varialvel que vefifica se a barra ira aparecer
var semBarra
	
function Scroll()
{
	//armazena o objeto instânciado
	var obj = this;
	
	//inicia as variaveis que serão utilizadas
	var conteudo, areaVisivel; //variaveis do conteudo
	var setaCima, setaBaixo, botaoArraste; //variaveis dos botões de controle
	var velocidade, evento; // variáveis de configuração
	
	//verifica se o navegador é o IE
	var IE = (navigator.userAgent.indexOf('MSIE') > -1 && navigator.userAgent.toLowerCase().indexOf('opera') == -1);
	
	var relacao; //variável que armazena a proporção do tamanho do conteudo em relação ao tamanho da barra de scroll
	var yMaximo; //variavel que armazena o valor máximo de top que o botão do scroll pode ter
	var intervaloMovimento; // variavel que armazena o intervalo do movimento das setas
	var direcao; //varivável que armazena a direção do movimento do conteudo
	var tempoIntervalo; //variavel que armazena o tempo do intervalo entre o movimento do conteúdo
	var movimentarDiretamente; // flag que indica se deve ir diretamente a algum ponto do scroll[se a pessoa clicar na área de arraste]
	
	//Init(): inicia os eventos do scroll
	this.Init = function()
	{
		//armazena os objetos de acordo com as id's passadas dentro de suas respectivas variáveis
		conteudo = document.getElementById(obj.Conteudo);
		areaVisivel = document.getElementById(obj.AreaVisivel);
		setaCima = document.getElementById(obj.SetaCima);
		setaBaixo = document.getElementById(obj.SetaBaixo);
		
		botaoArraste = document.getElementById(obj.BotaoArraste);
		areaArraste = document.getElementById(obj.AreaArraste);
		
		//verifica se foi passado um tempo para o intervalo. Se não foi, o tempo padrão é 1ms
		tempoIntervalo = (obj.TempoIntervalo)? obj.TempoIntervalo : 1;
		
		//armazena a velocidade
		velocidade = obj.Velocidade;
		
		//Efetua os calculos necessários ao scroll
		Calcular();
		
		//altera o position do botão de arraste e da area de arraste itens para o funcionamento correto
		areaArraste.style.position = 'relative';
		botaoArraste.style.position = 'absolute';
		conteudo.style.position = 'absolute';
		
		
		movimentarDiretamente = true;
		
		//anula o mousemove do botão de arraste para não gerar bugs
		botaoArraste.onmousemove = function(){return false;};
		
		//verifica se a àrea do scroll é menor que o conteudo, para mostrar ou esconder o conteúdo
		//var visibilidade = (conteudo.offsetHeight < areaVisivel.offsetHeight) ? 'hidden' : 'visible';
		var visibilidade = ( (conteudo.offsetHeight - 10) < areaVisivel.offsetHeight) ? 'hidden' : 'visible';
		
		//condicao criada para casos onde nao exista o botao arraste
		var invisibilidade = 'hidden'
		
		
		setaCima.style.visibility = visibilidade;
		setaBaixo.style.visibility = visibilidade;
		
		
		if(semBarra){
			botaoArraste.style.visibility = invisibilidade;
			areaArraste.style.visibility = invisibilidade;
		
		}else{
			botaoArraste.style.visibility = visibilidade;
			areaArraste.style.visibility = visibilidade;
		}
		
		//atribui o mousedown do botão de arraste
		botaoArraste.onmousedown = function(e)
		{
			movimentarDiretamente = false;
			//armazena o evento
			if(!e) e = event;
			
			//armazena a posição do mouse
			var ymouse = (IE) ? e.clientY + document.documentElement.scrollTop : e.pageY;
			
			//calcula a diferença da posição do botão em relação ao mouse
			var dy = ymouse - botaoArraste.offsetTop;
			
			document.onmousemove = function(e)
			{
				//armazena o evento do mousemove
				if(!e) e = event;
				//armazena o y do mouse
				ymouse = (IE) ? e.clientY + document.documentElement.scrollTop : e.pageY;
				
				//verifica se  botão é o 0 [0 = o internauta soltou o mouse fora do browser e depois voltou]
				//	- obs: apenas o IE retorna o botão do mouse dentro do mousemove. os demais browsers retornam apenas no onmousedown
				if(IE)
				{
					//caso o botão estiver solto, para o arraste do botão
					if(e.button == 0) document.onmouseup();
				}
				
				//calcula o y para onde o botão de arraste deve ir
				var yFinal = ymouse - dy;
				
				//verifica se o botão não saiu dos limites
				if(yFinal <= 0) yFinal = 0;
				else if(yFinal > yMaximo) yFinal = yMaximo;
				
				//posiciona o botão da barra de rolagem e o conteúdo
				botaoArraste.style.top = yFinal + 'px';
				conteudo.style.top = (yFinal * relacao * -1) + 'px';
			}
			
			//atribui o mouseup em todo o 'document', pois o internauta pode soltar o mouse em qualquer parte da página
			document.onmouseup = function()
			{
				movimentarDiretamente = true;
				//deleta os eventos
				document.onmousemove = function(){return false;};
				document.onmouseup = function(){return false;};
			}
			
			//retorna false para anular os outros efeitos do mousemove no browser
			return false;
		}
		
		areaArraste.onmousedown = function(e)
		{
			if(movimentarDiretamente)
			{
				//armazena o evento do mousemove
				if(!e) e = event;
				
				//armazena o y do mouse
				var ymouse = (IE) ? e.clientY + document.documentElement.scrollTop : e.pageY;
				
				var posicaoFinal = ymouse - (GetPosition(areaArraste).y);
				
				obj.Posicionar(posicaoFinal);
			}
		}
		
		//atribui a direção das setas
		setaCima.direcao = -1;
		setaBaixo.direcao = 1;
		
		//anula o mousemove dos botões para evitar bugs
		setaBaixo.onmouseout = setaCima.onmouseout = function(){return false;};
		//atribui o onmousedown das setas
		setaBaixo.onmouseover = setaCima.onmouseover = function()
		{
			//altera o valor da variável direção de acordo com ao sentido da seta
			direcao = this.direcao;
			
			//move o conteudo
			Mover();
			
			//atribui o onmouseup do conteúdo
			document.onmouseout = function()
			{
				//limpa o intervalo e o evento
				document.onmouseout = null;
				clearTimeout(intervaloMovimento);
			}
			
			//retorna false para anular os outros efeitos do mousedown no browser
			return false;
		}
	}
	
	//GetPosition(): retorna a posição real de um objeto na tela
	//	- alvo: objeto a retornar a posição
	function GetPosition(alvo){
		var parent = alvo;
		
		for(var ol = alvo.offsetLeft, ot = alvo.offsetTop; parent = parent.offsetParent; )
		{
			ol += parent.offsetLeft;
			ot += parent.offsetTop;
		}
		return {x:parseInt(ol),y:parseInt(ot)};
	}
	
	//Posicionar(): posiciona o scroll em alguma posição
	//	- posicao: posição de destino
	this.Posicionar = function(posicao)
	{
		//armazena a posição final
		var yFinal = posicao;
		
		//caso a posição passada seja maior ou menor do que o tamanho permitido, limita
		if(yFinal <= 0) yFinal = 0;
		else if(yFinal > yMaximo) yFinal = yMaximo;
		
		//posiciona o conteudo e o botão do scroll
		conteudo.style.top = (yFinal * relacao * -1) + 'px';
		botaoArraste.style.top = yFinal + 'px';	
	}
	
	//Calcular(): efetua os cálculos necessários ao scroll, deve ser executada sempre que o tamanho do conteúdo for alterado
	function Calcular()
	{
		//calcula a proporção do tamanho da barra de rolagem em relação ao tamanho do conteudo
		relacao = ((conteudo.offsetHeight - areaVisivel.offsetHeight) / (areaArraste.offsetHeight - botaoArraste.offsetHeight));
		
		//calcula o y máximo que o botão de arraste pode ter
		//yMaximo = areaArraste.offsetHeight - botaoArraste.offsetHeight;
		yMaximo = conteudo.offsetHeight - 150
	}
	
	//Mover(): função interna que move o conteudo e o botão de scroll, de acordo com o valor da variavel direção [-1 sobe o conteudo, e 1 desce o conteudo]
	function Mover()
	{
		//armazena o y final, de acordo com o passo do menu e a direção
		var yFinal = (botaoArraste.offsetTop + velocidade * direcao);
		
		//limita o valor doy final dentro dos valores permitidos
		if(yFinal <= 0) yFinal = 0;
		else if(yFinal > yMaximo) yFinal = yMaximo;
		
		//posiciona o conteudo e o botão de arraste
		//conteudo.style.top = (yFinal * relacao * -1) + 'px';
		conteudo.style.top = (yFinal * 1 * -1) + 'px';
		botaoArraste.style.top = yFinal + 'px';	
		
		//chama novamente a função depois de um tempo
		intervaloMovimento = setTimeout(Mover, tempoIntervalo);
	}
}
