// slideshow class
var SlideShow = new Class({
	Implements: [Options, Events],
	options: {
		/*
		onShow: $empty, 
		@params		displayed => html Element (current slide)
					displayedIndex => zero based index number of current slide
					hidden => html Element (previous slide)
					hiddenIndex => zero based index of previous slide
		*/
		holder: null,
		panels: [],
		delay: 5000,
		paused: false
	},
	initialize: function (options) {
		this.setOptions(options);
		this.isWebkit = (Browser.Engine.name == 'webkit');
		var scope = this;
		this.options.panels.each(function (itm, i, a) {
			var fadeFx = new Fx.Tween(itm, {property: 'opacity', duration: 500});
			fadeFx.addEvent('complete', scope.fadeComplete.bind(scope));
			itm.store('fadeFx', fadeFx);
			// set initial item values
			if (i > 0) {
				scope.setDisplay(itm, false);
				itm.setStyle('z-index', '1');
			}
		});
		this.boundedUserOver = this.userOver.bind(this);
		this.boundedUserOut = this.userOut.bind(this);
		this.fireEvent('show', [this.options.panels[0], this.current, null, 0], 500); // wait a bit
		if (!this.options.paused) {
			this.resume();
		}
	},
	
	timer: null,
	animating: false,
	paused: true, 
	current: 0,
	mouseIsOver: false,
	boundedUserOver: null,
	boundedUserOut: null,
	isWebkit: false,
	pause: function () {
		if (!this.options.paused) {
			this.options.paused = true;
			this.pauseShow();
			this.options.holder.removeEvent('mouseover', this.boundedUserOver);
			this.options.holder.removeEvent('mouseout', this.boundedUserOut);
		}
	},
	resume: function () {
		if (this.options.paused) {
			this.options.paused = false;
			this.startShow();
			this.options.holder.addEvent('mouseover', this.boundedUserOver);
			this.options.holder.addEvent('mouseout', this.boundedUserOut);
		}
	},
	startShow: function () {
		$clear(this.timer);
		this.timer = this.showNext.delay(this.options.delay, this);
	},
	showNext: function () {
		this.animating = true;
		var nxtId = (this.current == this.options.panels.length - 1) ? 0 : this.current + 1;
		this.fadeIn(this.options.panels[nxtId], this.options.panels[this.current]);
		this.current = nxtId;
	},
	fadeIn: function (itm, prev) {
		var fx = itm.retrieve('fadeFx');
		itm.store('prevItem', prev);
		fx.set(0);
		// bring to front
		prev.setStyle('z-index', '1');
		itm.setStyle('z-index', '2');
		this.setDisplay(itm, true);
		fx.start(0, 1);
	},
	fadeComplete: function (e) {
		this.animating = false;
		var prev = e.retrieve('prevItem');
		this.setDisplay(prev, false);
		if (!this.options.paused) {
			if (!this.mouseIsOver) {
				this.startShow();
			}
		}
		this.fireEvent('show', [e, this.current, prev, (this.current == 0) ? this.options.panels.length - 1 : this.current - 1]);
	},
	userOver: function(e) {
		this.mouseIsOver = true;
		this.pauseShow();
	},
	userOut: function(e) {
		this.mouseIsOver = false;
		this.startShow();
	},
	pauseShow: function (e) {
		$clear(this.timer);
	},
	getSlideCount: function() {
		return this.options.panels.length;
	},
	setSlide: function(newId) {
		this.pauseShow();
		this.fadeIn(this.options.panels[newId], this.options.panels[this.current]);
		this.current = newId;
	},
	setDisplay: function(pnl, show) {
		var prop = (this.isWebkit) ? 'visibility' : 'display';
		var val = (this.isWebkit) ? (show) ? 'visible' : 'hidden' : (show) ? 'block' : 'none';
		pnl.setStyle(prop, val);
	}
	
});

// slide show controls class
var SlideShowControls = new Class({
	Implements: [Options, Events],
	options: {
		/*
		onSlideChange: $empty
		@params		newId => id of slide requested by user
		*/
		nextImage: '',
		prevImage: '',
		currentSlideImage: '',
		slideImage: '',
		usePngFix: false,
		holder: null,
		slideShow: null
	},
	initialize: function (options) {
		this.setOptions(options);
		prev = new Element('img', {
			'src': this.options.prevImage,
			'alt': 'previous',
			'class': (this.options.usePngFix) ? 'prev pngFix' : 'prev'
		});
		prev.addEvent('click', this.showPrev.bind(this));
		next = new Element('img', {
			'src': this.options.nextImage,
			'alt': 'next',
			'class': (this.options.usePngFix) ? 'next pngFix' : 'next'
		});
		next.addEvent('click', this.showNext.bind(this));
		var list = new Element('ol', {});
		this.buildItems(list);
		prev.inject(this.options.holder);
		list.inject(this.options.holder);
		next.inject(this.options.holder);
	},
	prev: null,
	next:null,
	buttons: [],
	current: 0,
	buildItems: function (list) {
		var count = this.options.slideShow.getSlideCount();
		var i;
		var itm;
		var img;
		for (i=0; i<count; i++) {
			itm = new Element('li', {});
			itm.store('slideId', i);
			itm.addEvent('click', this.selectSlide.bind(this));
			img = this.createButton((i == this.current), i);
			img.inject(itm);
			itm.inject(list);
			this.buttons.push(itm);
		}
	},
	createButton: function (isCurrent, idx) {
		img = new Element('img', {
			'src': (isCurrent) ? this.options.currentSlideImage : this.options.slideImage,
			'alt': 'go to slide ' + idx,
			'class': (this.options.usePngFix) ? 'pngFix' : ''
		});
		return img;
	},
	selectSlide: function (e) {
		var idx = e.target.getParent().retrieve('slideId');
		this.setSlide(idx, true);
	},
	setSlide: function (newId, doEvent) {
		if (newId != this.current) {
			var doEvent = (doEvent == null) ? false : doEvent;
			var img = this.createButton(false, this.current);
			img.replaces(this.buttons[this.current].getFirst());
			var cur = this.createButton(true, newId);
			cur.replaces(this.buttons[newId].getFirst());
			this.current = newId;
			if (doEvent) {
				this.fireEvent('slideChange', newId);
			}
		}
	},
	showPrev: function (e) {
		this.setSlide((this.current == 0) ? this.buttons.length - 1 : this.current - 1, true);
	},
	showNext: function (e) {
		this.setSlide((this.current == this.buttons.length - 1) ? 0 : this.current + 1, true);
	}
});

/* ---- Class to hide/show content - mainly the login panel ----- */
// slide show controls class
var SlidingPanel = new Class({
	Implements: [Options, Events],
	options: {
		/*
		// all events pass 1 param: panel => this.options.panel
		onPanelShowing:
		onPanelShown:
		onPanelHiding
		onPanelHidden:
		*/
		panel: null,
		controls: [],
		useTween: false,
		isVerticle: true,
		axis: 'top',
		duration: 1000
	},
	showing: false,
	initialize: function (options) {
		this.setOptions(options);
		this.isWebkit = (Browser.Engine.name == 'webkit');
		this.boundHidePanel = this.documentHidePanel.bind(this);
		this.panelHeight = this.options.panel.getSize().y;
		this.setControls();
		if (this.options.useTween) {
			this.initTweens();
		}
		this.togglePanelDisplay(false);
	},
	animFx: {},
	inSettings: {},
	outSettings: {},
	boundHidePanel: null,
	panelHeight: 0,
	isWebkit: false,
	initTweens: function () {
		this.animFx = new Fx.Tween(this.options.panel, {property:this.options.axis, duration:this.options.duration});
		this.inSettings = {end:0};
		this.outSettings = {end:0 - this.panelHeight};
		this.options.panel.setStyle('top', 0 - this.panelHeight);
	},
	setControls: function () {
		var scope = this;
		this.options.controls.each(function(itm, i, a) {
			itm.addEvent('click', scope.toggleDisplay.bind(scope));
		});
	},
	toggleDisplay: function (e) {
		if (!this.showing) {
			this.showPanel();
		} else {
			this.hidePanel();
		}
		return false;
	},
	showPanel: function () {
		if (!this.showing) {
			this.showing = true;
			document.addEvent('click', this.boundHidePanel);
			this.fireEvent('panelShowing', [this.options.panel, this.panelHeight]);
			this.togglePanelDisplay(true);
			if (this.options.useTween) {
				this.animFx.cancel();
				this.animFx.removeEvents('complete');
				this.animFx.addEvent('complete', this.inAnimDone.bind(this));
				this.animFx.start(this.inSettings.end);
			} else {
				this.fireEvent('panelShown', [this.options.panel, this.panelHeight]);
			}
		}
	},
	inAnimDone: function () {
		this.fireEvent('panelShown', [this.options.panel, this.panelHeight]);
	},
	documentHidePanel: function (e) {
		if ($(e.target).getParent("#" + this.options.panel.get('id')) == null) {
			this.hidePanel();
		}
	},
	hidePanel: function () {
		document.removeEvent('click', this.boundHidePanel);
		if (this.showing) {
			this.fireEvent('panelHiding', [this.options.panel, this.panelHeight]);
			this.showing = false;
			if (this.options.useTween) {
				this.animFx.cancel();
				this.animFx.removeEvents('complete');
				this.animFx.addEvent('complete', this.outAnimDone.bind(this));
				this.animFx.start(this.outSettings.end);
			} else {
				this.togglePanelDisplay(false);
				this.fireEvent('panelHidden', [this.options.panel, this.panelHeight]);
			}
		}
	},
	outAnimDone: function () {
		this.togglePanelDisplay(false);
		this.fireEvent('panelHidden', [this.options.panel, this.panelHeight]);
	},
	togglePanelDisplay: function(show) {
		var prop = (this.isWebkit) ? 'visibility' : 'display';
		var val = (this.isWebkit) ? (show) ? 'visible' : 'hidden' : (show) ? 'block' : 'none';
		this.options.panel.setStyle(prop, val);
	}
});

/* --- VS Class ---- */
var ViewSwitcher = new Class({
	Implements: [Options, Events],
	options: {
		holder: null,
		navClass: "vsNav",
		contentClass: "vsContent" 
	},
	initialize: function (options) {
		this.setOptions(options);
		this.options.holder.getElements(this.getContentClass()).each(function (itm, i, a) {
			if (i > 0) {
				itm.addClass('hidden');
			} else {
				itm.addClass('vsCurrentContent');
			}
		});
		var lnk = this.options.holder.getElement(this.getNavClass('li a'));
		lnk.toggleClass('vsInactive');
		lnk.toggleClass('vsActive');
		this.options.holder.getElement(this.getNavClass()).removeClass('hidden'); // show if hidden
		var scope = this;
		this.options.holder.getElements(this.getNavClass('li a')).each(function (itm, i, a) {
			itm.addEvent('click', scope.switchView.bind(scope));
		});
	},
	switchView: function (e) {
		var itm = e.target;
		var targId = itm.get('href').split('#')[1];
		// reset current selection
		var oldLnk = this.options.holder.getElement(this.getNavClass('li a.vsActive'));
		if (oldLnk != null) {
			oldLnk.toggleClass('vsInactive');
			oldLnk.toggleClass('vsActive');	
		}
		var oldC = this.options.holder.getElement('.vsCurrentContent');
		if (oldC != null) {
			oldC.toggleClass('hidden');
			oldC.toggleClass('vsCurrentContent');
		}
		// set up new selection
		itm.toggleClass('vsInactive');
		itm.toggleClass('vsActive');
		var newC = this.options.holder.getElement("#" + targId);
		newC.toggleClass('hidden');
		newC.toggleClass('vsCurrentContent');
		e.stop();	
	},
	getNavClass: function(selector) {
		return (selector == null) ? "." + this.options.navClass : "." + this.options.navClass + " " + selector;
	},
	getContentClass: function() {
		return "." + this.options.contentClass;
	}
	
});