/*
	vsGallery is an gallery slide show object constructor. It sets up the overlay to dim the screen,
	and the overlay pane.

	Note:
	* vsGallery requires following YUI classes to work: yahoo-min.js, yahoo-dom-event.js,
	  event-min.js, animation-min.js, json-min.js, connection-min.js
*/
function vsGallery() {
	this.slides = new Array;
	this.tbs = new Array;
	this.titles = new Array;
	this.tbImages = new Array;
	this.nextSlide = 0;
	this.currentSlide = 0;
	this.animating = false;
	this.loadedSlides = 0;
	// create a overlay bg to cover all HTML BODY portion
	var bgOverlay = document.createElement('div');
	bgOverlay.style.position = 'absolute';
	bgOverlay.style.top = '0px';
	bgOverlay.style.left = '0px';
	if (document.body && (document.body.scrollWidth || document.body.scrollHeight)) {
		var pageWidth = document.body.scrollWidth + 'px';
		var pageHeight = document.body.scrollHeight + 'px';
    } else if (document.body.offsetWidth) {
		var pageWidth = document.body.offsetWidth + 'px';
		var pageHeight = document.body.offsetHeight + 'px';
    } else {
		var pageWidth = '100%';
		var pageHeight = '100%';
    }
	bgOverlay.style.width = pageWidth;
	bgOverlay.style.height = pageHeight;
	bgOverlay.style.display = 'none';
	bgOverlay.style.zIndex = '10';
	bgOverlay.style.backgroundColor = '#000'
	this.bgOverlay = document.body.appendChild(bgOverlay);
	// initialize gallery box - root div
	var box = document.createElement('div');
	box.className = 'vsGallery';
	box.style.display = 'none';
	box.style.zIndex = '11';
	box.style.position = 'absolute';
	if (arguments.length > 0)
		this.boxDiv = document.getElementById(arguments[0]).appendChild(box);
	else
		this.boxDiv = document.body.appendChild(box);
	// read the remote gallery HTML
	YAHOO.util.Connect.asyncRequest('GET', 'gallery.html', {
			success: function(o) {
				o.argument.boxDiv.innerHTML = o.responseText;
				o.argument._init();
			},
			failure: function(o) {
			},
			argument: this
		}, null);
}

/*

	vsGallery.setSlides sets the slides, thumbnails, titles
	
	args:
		slideUrls				Array conatins URLs of slides
		tbUrls					Array contains URLs of slide thumbnails
		titles					Array contains title strings for each slides
		defaultSlide			[Optional] The first slide to be shown, otherwise the first slide
								in the slideUrls will be shown.
		
*/
vsGallery.prototype.setSlides = function(slideUrls, tbUrls, titles) {
	var li, tb, div;
	
	delete this.slides;
	delete this.tbs;
	delete this.titles;
	delete this.tbImages;
	this.slides = new Array(slideUrls.length);
	this.tbImages = new Array(tbUrls.length);
	this.tbs = tbUrls;
	this.titles = titles;
	this.tbDiv.innerHTML = '';
	this.loadedSlides = 0;
	if (arguments.length > 3)
		var curSlide = arguments[3];
	else
		var curSlide = 0;
	if (curSlide < 0 || curSlide > slideUrls.length)
		curSlide = 0;
	for (var i = 0; i < slideUrls.length; i++) {
		// load or create HTML for slides
		if (slideUrls[i].lastIndexOf('.jpg') != -1 ||
			slideUrls[i].lastIndexOf('.png') != -1 ||
			slideUrls[i].lastIndexOf('.gif') != -1) {
			// create HTML code for image only slide
			this.slides[i] = '<div align="center"><img src="' + slideUrls[i] + '" /"></div>';
			this.loadedSlides++;
		} else {
			YAHOO.util.Connect.asyncRequest('GET', slideUrls[i], {
					success: function(o) {
						o.argument.obj.slides[o.argument.index] = o.responseText;
						o.argument.obj.loadedSlides++;
						if (o.argument.obj.loadedSlides >= o.argument.obj.slides.length)
							o.argument.obj.showSlide(o.argument.curSlide, true);
					},
					failure: function(o) {
					},
					argument: { obj: this, index: i, curSlide: curSlide }
				}, null);
		}
		// add thumbnails
		div = document.createElement('div');
		div.title = titles[i];
		div = this.tbDiv.appendChild(div);
		li = document.createElement('a');
		tb = document.createElement('img');
		tb.src = tbUrls[i];
		li.appendChild(tb);
		li = div.appendChild(li);
		this.tbImages[i] = li;
		YAHOO.util.Event.addListener(this.tbImages[i], 'click', this._toSlide,
									 { gallery: this, index: i });
	}
	if (this.loadedSlides >= slideUrls.length)
		this.showSlide(curSlide, true);
}

/*
	vsGallery.showSlide() set the specified slide as the current slide and show it with cross-fade
	transition (optionally).
	
	args:
		index					The slide index	you want to show
		withXFade				[Optionally] true if you want to cross-fade transition
	
*/
vsGallery.prototype.showSlide = function(index) {
	if (this.animating)
		return;
	if (arguments.length > 1 && arguments[1]) {
		this.frames[1].innerHTML = this.slides[index];
		this.frames[1].style.display = 'block';
		YAHOO.util.Dom.setStyle(this.frames[1], 'opacity', 0);
		var anim0 = new YAHOO.util.Anim(this.frames[0], { opacity: { from: 1, to: 0 } }, 0.3, YAHOO.util.Easing.easeOut);
		var anim1 = new YAHOO.util.Anim(this.frames[1], { opacity: { from: 0, to: 1 } }, 0.3, YAHOO.util.Easing.easeOut);
		this.nextSlide = index;
		this._hiliteTB(index, this.currentSlide);
		this.animating = true;
		anim0.animate();
		anim1.animate();
		anim0.onComplete.subscribe(this._fadeToPost, this);
	}  else {
		this.frames[1].style.display = 'none';
		this.frames[0].style.display = 'block';
		this.frames[0].innerHTML = this.slides[index];
		YAHOO.util.Dom.setStyle(this.frames[0], 'opacity', 1);
		this._hiliteTB(index, this.currentSlide);
		this.animating = false;
		this.currentSlide = index;
		this.nextSlide = index;
	}
}

/*
	vsGalelery._hiliteTB() hilite the specified slide thumbanil and unhilite the current one.
*/
vsGallery.prototype._hiliteTB = function(index, oldIndex) {
	this.tbImages[oldIndex].className = '';
	this.tbImages[index].className = 'active';
	// alert('index=' + index + ', oldIndex=' + oldIndex);
}

vsGallery.prototype._toSlide = function(e, obj) {
	obj.gallery.showSlide(obj.index, true);
}

/*
*/
vsGallery.prototype._fadeToPost = function(type, args, me) {
	me.frames[0].style.display = 'none';
	me.frames[0].style.left = '0px';
	var tempDiv = me.frames[0];
	me.frames[0] = me.frames[1];
	me.frames[1] = tempDiv;
	me.animating = false;
	me.currentSlide = me.nextSlide;
	
	document.getElementById('vsGalTitle').innerHTML = me.titles[me.currentSlide];
}

/*
	vsGallery.show() shows the gallery box
*/
vsGallery.prototype.show = function() {
	// adjust bg overlay
	if (document.body && (document.body.scrollWidth || document.body.scrollHeight)) {
		var pageWidth = document.body.scrollWidth + 'px';
		var pageHeight = document.body.scrollHeight + 'px';
    } else if (document.body.offsetWidth) {
		var pageWidth = document.body.offsetWidth + 'px';
		var pageHeight = document.body.offsetHeight + 'px';
    } else {
		var pageWidth = '100%';
		var pageHeight = '100%';
    }
    this.bgOverlay.style.width = pageWidth;
    this.bgOverlay.style.height = pageHeight;
	this.bgOverlay.style.display = 'block';
	YAHOO.util.Dom.setStyle(this.bgOverlay, 'opacity', 0.8);
	// center the box
	this.boxDiv.style.display = 'block';
	var x = Math.round((YAHOO.util.Dom.getViewportWidth() - this.boxDiv.offsetWidth) / 2) +
			YAHOO.util.Dom.getDocumentScrollLeft();
	var y = Math.round((YAHOO.util.Dom.getViewportHeight() - this.boxDiv.offsetHeight) / 2) +
			YAHOO.util.Dom.getDocumentScrollTop();
	YAHOO.util.Dom.setXY(this.boxDiv, [x, y]);
}

/*
	vsGallery.hide() hides the gallery box
*/
vsGallery.prototype.hide = function() {
	this.bgOverlay.style.display = 'none';
	this.boxDiv.style.display = 'none';
}

vsGallery.prototype.showNextSlide = function() {
	if (this.animating)
		return;
	this.nextSlide = this.currentSlide + 1;
	if (this.nextSlide >= this.slides.length)
		this.nextSlide = 0;
	this.frames[1].innerHTML = this.slides[this.nextSlide];
	this.frames[1].style.left = this.frames[0].offsetWidth;
	this.frames[1].style.display = 'block';
	YAHOO.util.Dom.setStyle(this.frames[1], 'opacity', 1);
	var anim0 = new YAHOO.util.Motion(this.frames[0], { points: { by: [-(this.frames[0].offsetWidth), 0] } }, 0.5, YAHOO.util.Easing.easeOut);
	var anim1 = new YAHOO.util.Motion(this.frames[1], { points: { by: [-(this.frames[0].offsetWidth), 0] } }, 0.5, YAHOO.util.Easing.easeOut);
	anim0.onComplete.subscribe(this._fadeToPost, this);
	anim0.animate();
	anim1.animate();
	this._hiliteTB(this.nextSlide, this.currentSlide);
	this.animating = true;
}

vsGallery.prototype.showPrevSlide = function() {
	if (this.animating)
		return;
	this.nextSlide = this.currentSlide - 1;
	if (this.nextSlide < 0)
		this.nextSlide = this.slides.length - 1;
	this.frames[1].innerHTML = this.slides[this.nextSlide];
	this.frames[1].style.left = -this.frames[0].offsetWidth;
	this.frames[1].style.display = 'block';
	YAHOO.util.Dom.setStyle(this.frames[1], 'opacity', 1);
	var anim0 = new YAHOO.util.Motion(this.frames[0], { points: { by: [this.frames[0].offsetWidth, 0] } }, 0.5, YAHOO.util.Easing.easeOut);
	var anim1 = new YAHOO.util.Motion(this.frames[1], { points: { by: [this.frames[0].offsetWidth, 0] } }, 0.5, YAHOO.util.Easing.easeOut);
	anim0.onComplete.subscribe(this._fadeToPost, this);
	anim0.animate();
	anim1.animate();
	this._hiliteTB(this.nextSlide, this.currentSlide);
	this.animating = true;
}


/*
	vsGallery._init() continues all the setup after the HTML code loaded. Internal function.
*/
vsGallery.prototype._init = function() {
	// get the frame divs
	this.frames = YAHOO.util.Dom.getElementsByClassName('vsGalFrames', 'div', this.boxDiv);
	// get thumbnails pane
	var divs = YAHOO.util.Dom.getElementsByClassName('vsGalThumbs', 'div', this.boxDiv);
	this.tbDiv = divs[0];
	// set up event listeners
	// close box
	divs = YAHOO.util.Dom.getElementsByClassName('vsGalClose', 'div', this.boxDiv);
	this.closeDiv = divs[0];
	YAHOO.util.Event.addListener(this.closeDiv, 'click', function(e, obj) { obj.hide(); }, this);
	// left & right arrows
	YAHOO.util.Event.addListener('vsGalNavLeft', 'click', function(e, obj) { obj.showPrevSlide(); }, this);
	YAHOO.util.Event.addListener('vsGalNavRight', 'click', function(e, obj) { obj.showNextSlide(); }, this);
}