var FlipShow = Class.create();

FlipShow.defaults = {
	thumbnail_id_suffix : '_small',
	large_id_suffix : '_big',
	thumbnail_event : 'click',
	out_transition : Effect.Fade,
	out_duration : .5,
	in_duration : .5,
	in_transition : Effect.Appear,
	id_prefix : null
};

FlipShow.prototype = {
	loaded : false,
	initialize : function(elm, options) {
		var me = this, next, prev;
		this.elm = $(elm);

		this.options = Object.extend(Object.clone(FlipShow.defaults),Object.extend(options || {}));
		this.elm.makePositioned();
		this.slides = this.elm.immediateDescendants();
		
		if (!this.options.id_prefix){
			this.options.id_prefix = this.slides[0].id.match(/[\w_]+\d/)[0].replace(/\d+/, "");
		}
		
		if (!this.options.effect_queue){
			this.options.effect_queue = this.elm.id;
		}
		
		this.current_visible = this.slides[0];
		this.next_visible = null;
		this.last_requested_id = null;
		this.in_transition = false;
		
		this.freeze_overflow_element = null;
		
		if (this.options.freeze_overflow_id){
			this.freeze_overflow_element = $(this.options.freeze_overflow_id);
		}

		if (this.options.thumbnail_holder != 'undefined'){
			if (typeof this.options.thumbnail_holder.size == 'undefined'){
				this.options.thumbnail_holder = [this.options.thumbnail_holder];
			}
			this.options.thumbnail_holder.each(this.setupThumbnailHolder.bind(this));
		}
	},
	setupThumbnailHolder : function (id){
		var thumbnailHolder = $(id);
		var thumbnails = thumbnailHolder.descendants();
		thumbnails.each(this.setupThumbnail.bind(this));
	},
	setupThumbnail : function (thumbnail) {
		if (thumbnail.id.match(new RegExp(this.options.thumbnail_id_suffix+'$'))){
			Event.observe(thumbnail, this.options.thumbnail_event, this.thumbnailEvent.bind(this));
		}
	},
	thumbnailEvent : function (event) {
		var new_id = this.idFromThumbnailId(Event.element(event).id);
		var old_id = this.idFromLargeId(this.current_visible.id);
		if (new_id != old_id){
			this.goTo(new_id);
		}
	},
	goTo : function (id) {
		this.last_requested_id = id;
		if (!this.in_transition){

			if (typeof this.getLastRequestedElement() != 'undefined'){
				this.in_transition = true;
				this.freezeOverflow();
				this.previous_visible_element = this.current_visible;
				this.options.out_transition(this.current_visible, {duration: this.options.out_duration, 
																													 queue: { position: 'end', scope: this.options.effect_queue }, 
																													 afterFinish : this.showNext.bind(this) });
			}
		}
	},
	showNext : function() {
		if (typeof this.getLastRequestedElement() != 'undefined'){
			this.current_visible = this.getLastRequestedElement();
		}
		this.options.in_transition(this.current_visible, {duration: this.options.in_duration, 
																											queue: { position: 'end', scope: this.options.effect_queue }, 
																											afterFinish : this.afterGoTo.bind(this) });
	},
	afterGoTo : function() {
		this.current_visible.show();
		this.in_transition = false;
		this.unfreezeOverflow();
	},
	freezeOverflow : function() {
		if (this.freeze_overflow_element){
			this.freeze_overflow_element.style.overflow = "hidden";
		}
	},
	unfreezeOverflow : function() {
		if (this.freeze_overflow_element){
			this.freeze_overflow_element.style.overflow = "auto";
		}
	},
	getLastRequestedElement : function(){
		return this.elementFromLargeId(this.last_requested_id);
	},
	idFromThumbnailId : function (id_string){
		return id_string.replace(this.options.id_prefix, "").replace(this.options.thumbnail_id_suffix, "");
	},
	idFromLargeId : function (id_string){
		return id_string.replace(this.options.id_prefix, "").replace(this.options.large_id_suffix, "");
	},
	elementFromThumbnailId : function (id){
		return $(this.options.id_prefix+id+this.options.thumbnail_id_suffix);
	},
	elementFromLargeId : function (id){
		return $$("#"+this.elm.id+" #"+this.options.id_prefix+id+this.options.large_id_suffix)[0];
	}
};