OSlideshow = Class.create(
{
	activeSlides:null,
	waitingSlides:null,
	curIndex:null,
	container:null,
	options:null,
	initialize:function(container, schemaFile, options)
	{
		OSlideshow.instance = this;
		this.options = options || {};
		
		//sets up our binded event listeners
		this.bindedSlideLoadHandler = this.slideLoadHandler.bind(this);
		this.bindedChangeSlide = this.changeSlide.bind(this);
			
		this.build(container);
		
		this.loadSchema(schemaFile);
	},
	//appends our container to the container given
	build:function(container)
	{
		if(!container)
			container = document.body();
			
		this.container = OBuilder('div',{id:'OSlideShow'});
		
		container.appendChild(this.container);
	},
	//loads in the slideshow schema
	loadSchema:function(schemaFile)
	{
		//if they didn't give us a schema file, just return
		if(!schemaFile)
			return;
		
		var that = this;
		new Ajax.Request(schemaFile,
		{
			onComplete:function(transport)
			{
				if(!!transport.responseJSON.slides)
					that.initializeSlides(transport.responseJSON.slides);
			}
		});
	},
	//given an array of slide definitions, initialize our slides
	initializeSlides:function(slides)
	{
		if(!slides)
			return;
		
		this.waitingSlides = {};
		this.activeSlides = [];
		
		for(var i = 0, len = slides.length; i < len; i++)
		{
			//TODO: check for other content types, not just images
			var content = OBuilder('img',{src:'slideshow/images/'+slides[i].image,slideId:'slide_'+i});
			
			Event.observe(content,'load',this.bindedSlideLoadHandler)
			
			this.waitingSlides['slide_'+i] = OBuilder('div',{},[
				OBuilder('div',{className:'Content'},[
					content
				]),
				OBuilder('h1',{},[
					slides[i].title + ":",
					OBuilder('span',{},slides[i].subtitle)
				])
			]);
		}
	},
	//a really great slide load handler
	slideLoadHandler:function(evt)
	{
		var img = Event.element(evt);
		Event.stopObserving(img, 'load', this.bindedSlideLoadHandler);
		
		//get the slide id
		var slideId = img.getAttribute('slideId');
		//get the slide from the waiting list
		var slide = this.waitingSlides[slideId];
		if(!slide)
			return;
			
		delete this.waitingSlides[slideId];
		
		this.activeSlides.push(slide);
		
		//if we haven't started the slideshow, get it going
		if(!this.started && this.activeSlides.length > 1)
		{
			this.startSlideshow();
		}
	},
	//starts the periodical executer
	startSlideshow:function()
	{
		this.started = true;
		
		//add our buttons
		this.container.appendChild(OBuilder('a',{className:'Button Left', href:'javascript:clickHandler("OSlideshow.changeSlide(null,true)")', title:'previous slide'}));
		this.container.appendChild(OBuilder('a',{className:'Button Right', href:'javascript:clickHandler("OSlideshow.changeSlide()")', title:'next slide'}));
		
		this.container.appendChild(this.activeSlides[0]);
		this.curIndex = 0;
		this.startExecuter();
	},
	startExecuter:function()
	{
		if(this.pe)
			this.pe.stop();
		this.pe = new PeriodicalExecuter(this.bindedChangeSlide, 6);
	},
	stopExecuter:function()
	{
		this.pe.stop();
	},
	//changes the slide to the next one
	changeSlide:function(pe, opt_backward)
	{
		var add = 1;
		if(!!opt_backward)
			add = -1;
			
		//get the next slide
		var nextId = (this.curIndex + add) % this.activeSlides.length;
		if(nextId < 0)
			nextId = this.activeSlides.length -1;
		var nextSlide = this.activeSlides[nextId];
		
		//hide it and add it to the frey
		$(nextSlide).hide();
		this.container.appendChild(nextSlide);
		
		//hide the current one and show the new one
		$(nextSlide).appear({duration:0.5});
		$(this.activeSlides[this.curIndex]).fade({
			duration:0.5,
			afterFinish:function(effect)
			{
				//remove it from the dom
				$(effect.element).remove();
			}
		});
		
		this.curIndex = nextId;
		
		//if we don't have the periodical executer, we are manually turning the image, so stop the
		// pe and wait to start it for 15 seconds
		if(!pe)
		{
			this.stopExecuter();
			setTimeout('clickHandler("OSlideshow.startExecuter()")',15000); // use this if we want the delay to be longer
		}
	}
});
OSlideshow.instance = null;
OSlideshow.getInstance = function()
{
	return OSlideshow.instance;
}
