/*	****************************************************************************************
	DivSlider
	----------------------------------------------------------------------------------------
	This class can be used to create sliding effects for <divs>.
	----------------------------------------------------------------------------------------
	Use:
	1. Link this file: 		<script src="divslider.js" type="text/javascript"></script>
	2. Create an instance: 	var sliThis = new DivSlider();
	3. Create the divs:		<div id="x" ... 
	4. Add the divs:		sliThis.AddDiv('x');
	5. Set some properties: sliNews.SliderOptions.Width = {width of the divs};
							sliNews.SliderOptions.Height = {width of the divs};
							...
	6. Call the creator:	sliThis.RefreshState();
	7. Bind click-events:	<a href="#" onclick="sliNews.SlidePrevious();">Previous</a>
							<a href="#" onclick="sliNews.SlideNext();">Next</a>
	Ready.
	----------------------------------------------------------------------------------------
	A. Schmidt 
	copyright © 2009 www.codingfreaks.de
	
	This program is free software; you can redistribute it and/or modify it under the terms 
	of the GNU General Public License as published by the Free Software Foundation; either 
	version 3 of the License, or (at your option) any later version.
	
	This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
	without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
	See the GNU General Public License for more details.

	You should have received a copy of the GNU General Public License along with this program; 
	if not, see http://www.gnu.org/licenses/

	project-page: http://www.codingfreaks.de	
	----------------------------------------------------------------------------------------
	created:	12.04.2009
	changed:	12.04.2009
	----------------------------------------------------------------------------------------
	version:	1.0.1
	**************************************************************************************** */
		
function DivSlider()
{
	
	/*
	This construct defines all slider-related options which can be set.
	*/
	this.SliderOptions =  
	{
		Left: 0,					// The X-coordinate of the origin.
		Top: 0,						// The Y-coordinate of the origin.
		Width: 100,					// The width of the divs which should be slided.
		Height: 100,				// The height of the divs which should be slided.
		Current: 0,					// The offset (0-based) of the div which should be visible at startup.
		SlideDivs: new Array(),		// The array of div-ids (string).
		Direction: 1,				// The direction to scroll through (don't set directly!)
		Duration: 1,				// The duration in seconds for a complete switch.
		Steps: 30,					// The steps taken to reach the transformation.
		CurrentStep: 0,				// The step which is currently active (don't touch!)
		FlippedScroll: 0,			// Set this to 1 to flip the scroll-direction.
		EaseDown: 0,				// Set this to 1 to get some ease-effect at the end of the animation.
		SpeedUp: 0,					// Set this to 1 to get some speed-up-effect at the end of the animation.
		IsRunning: 0,				// 1 if the animation is currently running (don't touch).
		Timer: false				// A handle to the currently active timer (don't touch).
	};
	
	/*
	Enumeration of possible directions.
	*/
	this.Direction = 
	{
		Horizontal: 1,				// The animation will scroll on the x-axis.
		Vertical: 2					// The animation will scroll on the y-axis.
	};	

	/*
	Method to add divs to the collection.
	*/
	this.AddDiv = function(strDiv)
	{		
		eleDiv = document.getElementById(strDiv);
		this.SliderOptions.SlideDivs.push(strDiv);
		eleDiv.style.position = 'absolute';
		eleDiv.style.display = this.SliderOptions.SlideDivs.length == (this.SliderOptions.Current + 1) ? 'block' : 'none';
	};	
	
	/*
	Method to initialize the divs.
	*/
	this.RefreshState = function()
	{
		if (this.SliderOptions.IsRunning == 0)
		{
			for(i=0; i < this.SliderOptions.SlideDivs.length; i++)
			{			
				strID = this.SliderOptions.SlideDivs[i];
				eleDiv = document.getElementById(strID);
				if (i == (this.SliderOptions.Current))
					eleDiv.style.display = 'block';
				else
					eleDiv.style.display = 'none';
			}
		}
	}
	
	/*
	Method to slide to the previous div.	
	*/
	this.SlideNext = function()
	{
		if (this.SliderOptions.IsRunning == 0 &&
			this.SliderOptions.Current < this.SliderOptions.SlideDivs.length - 1)
		{
			this.SliderOptions.IsRunning = 1;
			this.SliderOptions.CurrentStep = 0;
			this.StopTimer();
			intDirection = -1;
			if (this.SliderOptions.FlippedScroll == 1)
				intDirection = intDirection * -1;
			this.SetBeginPosition(this.NextElement(), intDirection);
			this.SetCurrentBeginPosition(this.CurrentElement());
			eleNext = this.NextElement();
			var instance = this;
			this.SliderOptions.Timer = window.setInterval(function() { instance.DoSlide(intDirection, eleNext); }, this.TimerDelay());
		}
	}
	
	/*
	Method to slide to the next div.
	*/
	this.SlidePrevious = function()
	{
		if (this.SliderOptions.IsRunning == 0 &&
			this.SliderOptions.Current > 0)
		{			
			this.SliderOptions.IsRunning = 1;
			this.SliderOptions.CurrentStep = 0;
			this.StopTimer();
			intDirection = 1;
			if (this.SliderOptions.FlippedScroll == 1)
				intDirection = intDirection * -1;
			this.SetBeginPosition(this.PreviousElement(), intDirection);			
			this.SetCurrentBeginPosition(this.CurrentElement());
			elePrev = this.PreviousElement();
			var instance = this;
			this.SliderOptions.Timer = window.setInterval(function() { instance.DoSlide(intDirection, elePrev); }, this.TimerDelay());	
		}
	}

	/*
	Returns the delay in milliseconds between each slide-step.
	*/
	this.TimerDelay = function()
	{		
		return Math.round((this.SliderOptions.Duration * 1000) / this.SliderOptions.Steps);
	}
	
	/*
	Returns the currently needed step-length. This method also calculates speed-effects.
	*/
	this.StepLength = function()
	{
		intLen = Math.round(this.SliderOptions.Height / this.SliderOptions.Steps);
		if (this.SliderOptions.CurrentStep > (this.SliderOptions.Steps / 2))
		{
			if (this.SliderOptions.EaseDown == 1)
			{
				intLen -= (this.SliderOptions.CurrentStep/this.SliderOptions.Steps);
			}
			if (this.SliderOptions.SpeedUp == 1)
			{
				intLen *= 1 + Math.round(this.SliderOptions.CurrentStep / this.SliderOptions.Steps);
			}
		}
		if (intLen < 1)
			intLen = 1;
		return intLen;
	}
	
	/*
	Returns the currently active slide-div-element.
	*/
	this.CurrentElement = function()
	{	
		return document.getElementById(this.SliderOptions.SlideDivs[this.SliderOptions.Current]);
	}
	
	/*
	Returns the previously active slide-div-element.
	*/
	this.PreviousElement = function()
	{
		return document.getElementById(this.SliderOptions.SlideDivs[this.SliderOptions.Current - 1]);		
	}
	
	/*
	Returns the next slide-div-element.
	*/	
	this.NextElement = function()
	{
		return document.getElementById(this.SliderOptions.SlideDivs[this.SliderOptions.Current + 1]);
	}
	
	/*
	Performs the slide-operation (called inside a timer-loop).
	*/	
	this.DoSlide = function(intDirection, eleNext)
	{					
		this.SliderOptions.CurrentStep++;
		var eleCurrent = this.CurrentElement();				
		
		var intCurrentTop = Math.round(parseInt(eleCurrent.style.top));
		var intCurrentLeft = Math.round(parseInt(eleCurrent.style.left));					
		var intNextTop = Math.round(parseInt(eleNext.style.top));
		var intNextLeft = Math.round(parseInt(eleNext.style.left));	
			
		blnDone = 0;				
		if (this.SliderOptions.Direction == this.Direction.Vertical)
		{	
			if (intDirection == 1)
			{
				intCurrentTop += this.StepLength();
				intNextTop = intCurrentTop - this.SliderOptions.Height;					
				
				eleCurrent.style.top = intCurrentTop + 'px';			
				eleNext.style.top = intNextTop + 'px';				
				if (intNextTop >= this.SliderOptions.Top)
				{
					blnDone = 1;						
				}
			}
			else
			{
				intCurrentTop -= this.StepLength();			
				intNextTop = intCurrentTop + this.SliderOptions.Height;
				
				eleCurrent.style.top = intCurrentTop + 'px';
				eleNext.style.top = intNextTop + 'px';			
				
				if (intNextTop <= this.SliderOptions.Top)
				{
					blnDone = 1;	
				}
			}
		}
		else if (this.SliderOptions.Direction == this.Direction.Horizontal)
		{
			if (intDirection == -1)
			{				
				intCurrentLeft += this.StepLength();
				intNextLeft = intCurrentLeft - this.SliderOptions.Width;
				
				eleCurrent.style.left = intCurrentLeft + 'px';
				eleNext.style.left = intNextLeft + 'px';
				
				if (intNextLeft >= this.SliderOptions.Left)
				{
					blnDone = 1;	
				}
			}
			else
			{					
				intCurrentLeft -= this.StepLength();
				intNextLeft = intCurrentLeft + this.SliderOptions.Width;
				
				eleCurrent.style.left = intCurrentLeft + 'px';
				eleNext.style.left = intNextLeft + 'px';
				
				if (intNextLeft <= this.SliderOptions.Left)
				{
					blnDone = 1;	
				}
			}			
		}
	
		if (blnDone == 1)
		{			
			eleNext.style.top = this.SliderOptions.Top + 'px';
			eleNext.style.left = this.SliderOptions.Top + 'px';
			eleCurrent.style.display = 'none';
			if (this.SliderOptions.FlippedScroll == 1)
			{
				if (intDirection == 1)
					this.SliderOptions.Current++;
				else
					this.SliderOptions.Current--;
			}
			else
			{
					if (intDirection == 1)
					this.SliderOptions.Current--;
				else
					this.SliderOptions.Current++;
			}
			
			this.StopTimer();
			this.SliderOptions.IsRunning = 0;
			return;
		}		
	}
	
	/*
	Sets the position of an element to the absolute start-position.
	*/	
	this.SetCurrentBeginPosition = function(eleCurrent)
	{
		eleCurrent.style.top = this.SliderOptions.Top;
		eleCurrent.style.left = this.SliderOptions.Left;
	}
	
	/*
	Moves the next visible slide-element to the appropriate start-position
	depending on the selected slide-settings.
	*/	
	this.SetBeginPosition = function(eleSlideIn, intDirection)
	{		
		var intTop;
		var intLeft;
		if (this.SliderOptions.Direction == this.Direction.Vertical)
		{
			if (intDirection == 1)
			{
				// top to bottom
				intTop = this.SliderOptions.Top - this.SliderOptions.Height;
				intLeft = this.SliderOptions.Left;	
			}
			else
			{
				// bottom to top	
				intTop = this.SliderOptions.Top + this.SliderOptions.Height;
				intLeft = this.SliderOptions.Left;
			}								
		}
		else if (this.SliderOptions.Direction == this.Direction.Horizontal)
		{				
			if (intDirection == -1)
			{
				// left to right
				intTop = this.SliderOptions.Top;
				intLeft = this.SliderOptions.Left - this.SliderOptions.Width;					
			}
			else 
			{				
				// right ro left
				intTop = this.SliderOptions.Top;
				intLeft = this.SliderOptions.Left + this.SliderOptions.Width;
			}
		}
		eleSlideIn.style.left = intLeft + 'px';
		eleSlideIn.style.top = intTop + 'px';		
		eleSlideIn.style.display = 'block';		
	}
	
	/*
	Stops the calling of DoSlide() immediate.
	*/
	this.StopTimer = function()
	{		
		window.clearInterval(this.SliderOptions.Timer);		
	}
}




