///short for Alp Systems
AS = { };

AS.SlideAnimate = new Class({

	durationSecs: .5,
	onFinished: null,
	
	start: function(thisId, nextId, offset) {
		
		//slide left or right depending on offset negative/positive.
		if(offset >= 0) {
			offset = 1;
		} else {
			offset = -1;
		}
		
		//position next div properly at the start of the animation:
		$(nextId).style.left = (offset * $(thisId).offsetWidth) + "px";
		
		this.thisId = thisId;
		this.nextId = nextId;
		this.offset = offset;
		this.currentFrame = 0;
		
		this.totalFrames = this.durationSecs * this.framesPerSecond;
		
		this.play();
	},
	
	thisId: null,
	nextId: null,
	offset: 1,
	currentFrame: 0,
	framesPerSecond: 30,
	totalFrames: null,
	
	play: function() {
		
		//calculate where the div should be on this frame:
		var currentPos = (this.currentFrame/this.totalFrames) * $(this.thisId).offsetWidth;
		
		$(this.nextId).style.left = (this.offset * $(this.thisId).offsetWidth - this.offset*currentPos) + "px";
		$(this.thisId).style.left = (-1 * this.offset*currentPos) + "px";
		
		this.currentFrame++;

		if(this.currentFrame <= this.totalFrames) {
			window.setTimeout(this.play.bind(this), 1000 * 1/this.framesPerSecond);
		} else {
			if(this.onFinished != null) {
				this.onFinished();
			}
		}
	}
});

AS.Slideshow = new Class({

	////public:
	initialize: function() { },
	images: [],				//either filenames or URLs
	delay: 5000, 			//in milliseconds
	baseUrl: "",			//prefix to add to each image URL, should end in "/"
	thisImgId: "ssCurrent",	//main <img> ID
	nextImgId: "ssNext",	//next (preloading) <img> ID
	imageSize: [320,200],	//size of the image in the slideshows
	effect: new AS.SlideAnimate(),
	
	start: function() {
		
		if(this.images.length <= 1) {
			//nothing to do - only one image (or maybe none at all)
			return;
		}

		if(!this.isRunning) {
			this.isRunning = true;
			
			//First time ever called. Pre-load the next image but assume
			//current image already showing:
			$(this.nextImgId).src = this.baseUrl + this.images[1];

			///We'll switch to the next image as soon as it's loaded or the delay times
			///out, whichever comes LAST:
			this.timeout = setTimeout(this.start.bind(this), this.delay);

			///Call us back when the next image loads. later we swap so set handler on both.:
			//$(this.nextImgId).onload = this.onNextLoaded.bind(this, this.nextImgId);
			//$(this.thisImgId).onload = this.onNextLoaded.bind(this, this.thisImgId);
		} else {
			this.isTimedOut = true;
			//if(this.isNextLoaded) {
				this.showNext();
			//} //else wait until the next one is loaded
		}
	},
	
	jumpNext: function() {
		this.jumpTo(1);
	},
	
	jumpPrev: function() {
		this.jumpTo(-1);
	},
	
	jumpTo: function(offset) {
		
		if(this.images.length <= 1) {
			//not enough images
			return;
		}
		
		if(this.isAnimating) {
			//We're in a transition already. Ignore them.
			return;
		}
		
		//Cancel any timeout, we'll restart the timer after:
		if(this.timeout != null) {
			window.clearTimeout(this.timeout);
		}
		
		if(offset >= 0) {
			//easy - just show the next one:
			this.showNext();
		} else {
			//hmm, the previous will probably be loaded, we hope...
			this.currentIndex = this.adjustWithLooping(-1);
			$(this.nextImgId).src = this.baseUrl + this.images[this.currentIndex];
			this.showNext("hackalreadydone", -1);
		}
	},
	
	adjustWithLooping: function(offset) {
		if(offset < 0 && this.currentIndex == 0) {
			return this.images.length-1;
		} else {
			return (this.currentIndex+1*offset) % this.images.length;
		}
	},

	
	////private:
	
	currentIndex: 0,
	isRunning: false,
	timeout: null,
	isNextLoaded: false,
	isTimedOut: false,
	isAnimating: false,
	
	showNext: function(flag, offset) {

		if(typeof(flag) == "undefined" || flag != "hackalreadydone" ) {
			this.currentIndex = this.adjustWithLooping(1);
			offset = 1
		} //else HACKHERE - a bit screwy, means we've already set currentIndex.
		
		this.effect.onFinished = this.onEffectFinished.bind(this);
		this.isAnimating = true;
		this.effect.start(this.thisImgId, this.nextImgId, offset);

	},
	
	onEffectFinished: function() {
		
		//swap this and next:
		var temp = this.thisImgId;
		this.thisImgId = this.nextImgId;
		this.nextImgId = temp;
		
		//preload next-next:
		$(this.nextImgId).src = this.baseUrl + this.images[this.adjustWithLooping(1)];
		
		this.isNextLoaded = false;
		this.isTimedOut = false;
		this.isAnimating = false;
		this.timeout = setTimeout(this.showNext.bind(this), this.delay);
	},

	onNextLoaded: function(id) {
		
		if(id != this.nextImgId) {
			//loading on thisImgId... we don't care.
			return;
		}
		
		this.isNextLoaded = true;
		
		if(this.isTimedOut) {
			this.showNext();
		}
	}
	
});


function opacity(id, opacStart, opacEnd, millisec) {
    //speed for each frame
    var speed = Math.round(millisec / 100);
    var timer = 0;

    //determine the direction for the blending, if start and end are the same nothing happens
    if(opacStart > opacEnd) {
        for(i = opacStart; i >= opacEnd; i--) {
            setTimeout("changeOpac(" + i + ",'" + id + "')",(timer * speed));
            timer++;
        }
    } else if(opacStart < opacEnd) {
        for(i = opacStart; i <= opacEnd; i++)
            {
            setTimeout("changeOpac(" + i + ",'" + id + "')",(timer * speed));
            timer++;
        }
    }
}

//change the opacity for different browsers
function changeOpac(opacity, id) {
    var object = document.getElementById(id).style;
    object.opacity = (opacity / 100);
    object.MozOpacity = (opacity / 100);
    object.KhtmlOpacity = (opacity / 100);
    object.filter = "alpha(opacity=" + opacity + ")";
} 

