/**
 * jQuery Photo Gallery
 * A JS- and jQuery-powered photo gallery.  The gallery can swap images automatically (with a fade
 * and customizable timing) or manually with forward/back controls.
 * @copyright © 2011 Jason A. Craig
 */
function jacJQueryGallery(elem_id, auto, img_time, fade_time)
{
	if(auto == null)
		auto = false;
	if(img_time == null)
		img_time = 7;
	if(fade_time == null)
		fade_time = 1.5;
	this.auto = auto;
	this.img_time = img_time*1000;
	this.fade_time = fade_time*1000;
	this.show_caption = true;
	this.show_bkgnd = true;
	this.pre_chg_f = null;
	this.post_chg_f = null;

	this._elem = $("#" + elem_id);
	this._bkgnd_elem = null;
	this._chg_timeout = null;
	this._slides = this._elem.find(".slide");
	this._jq_slds = new Array();
	this._img_widths = new Array();
	this._img_heights = new Array();
	this._gal_w = this._elem.width();
	this._gal_h = this._elem.height();
	this._prev_sld = null;
	if(this._slides.length > 0)
	{
		this._cur_sld = $(this._slides[0]);
		this._cur_idx = 0;
		this._prev_idx = this._last_idx = this._slides.length - 1;
	}
	else
	{
		this._cur_sld = null;
		this._prev_idx = this._cur_idx = this._last_idx = 0;
	}
	if(this.show_caption && this._cur_sld != null)
	{
		var cptn_elem = $("#jac-glry-cptn"), text = this._cur_sld.attr("title");
		text = text == null ? this._cur_sld.parent().attr("title") : text;
		if(cptn_elem.length == 0)
			this._elem.after('<div id="jac-glry-cptn">' + text + '</div>');
		else
			cptn_elem.text(text).show();
	}
	if(!this.auto)
	{
		$("#jac-glry-cptn").after('<div id="jac-glry-ctl"><span class="bck-ctl">&#9664;</span><span class="fwd-ctl">&#9654;</span></div>');
		var that = this;
		$("#jac-glry-ctl > .bck-ctl").click(function() { that.manual_back(); });
		$("#jac-glry-ctl > .fwd-ctl").click(function() { that.manual_fwd(); });
	}
}
jacJQueryGallery.prototype = new Object();
jacJQueryGallery.prototype.constructor = jacJQueryGallery;
jacJQueryGallery.prototype.auto;
jacJQueryGallery.prototype.img_time;
jacJQueryGallery.prototype.fade_time;
jacJQueryGallery.prototype.show_caption;
jacJQueryGallery.prototype.show_bkgnd;
jacJQueryGallery.prototype.pre_chg_f;
jacJQueryGallery.prototype.post_chg_f;
jacJQueryGallery.prototype._elem;
jacJQueryGallery.prototype._bkgnd_elem;
jacJQueryGallery.prototype._chg_timeout;
jacJQueryGallery.prototype._slides;
jacJQueryGallery.prototype._jq_slds;
jacJQueryGallery.prototype._img_widths;
jacJQueryGallery.prototype._img_heights;
jacJQueryGallery.prototype._gal_w;
jacJQueryGallery.prototype._gal_h;
jacJQueryGallery.prototype._prev_sld;
jacJQueryGallery.prototype._cur_sld;
jacJQueryGallery.prototype._prev_idx;
jacJQueryGallery.prototype._cur_idx;
jacJQueryGallery.prototype._last_idx;

function init_slide(that, i, e)
{
	var jq_elem = $(e);
	that._jq_slds.push(jq_elem);
	jq_elem.removeClass("first");
	if(i == that._cur_idx)
		jq_elem.addClass("cur");
	if(e.localName != "img")
		jq_elem = $(e).find("img");
	if(jq_elem.length < 1)
		return;
	var elem = jq_elem[0], w = elem.width, h = elem.height;
	var left = w < that._gal_w ? (Math.round((that._gal_w - w) / 2) + "px") : 0;
	var top = h < that._gal_h ? (Math.round((that._gal_h - h) / 2) + "px") : 0;
	jq_elem.css({"left": left, "top": top});
	that._img_widths.push(w);
	that._img_heights.push(h);
}

/* Start the auto gallery or, if the "auto" property has changed, initialize the manual gallery. */
jacJQueryGallery.prototype.start =
	function()
	{
		if(this._slides == null || this._slides.length <= 1)
			return;
		var that = this;
		this._slides.each(function(i, e) { init_slide(that, i, e); });
		if(this.show_bkgnd)
		{
			this._bkgnd_elem = $("#jac-glry-bkgnd");
			if(this._bkgnd_elem.length == 0)
			{
				this._elem.append("<div id=\"jac-glry-bkgnd\"></div>");
				this._bkgnd_elem = $("#jac-glry-bkgnd");
			}
		}
		var glry_ctl = $("#jac-glry-ctl");
		if(this.auto)
		{
			glry_ctl.hide();
			this._chg_timeout = window.setTimeout(function() { that.change_img(); }, this.img_time);
		}
		else if(glry_ctl.length == 0)
		{
			this._elem.after('<div id="jac-glry-ctl"><span class="bck-ctl">&#9664;</span><span class="fwd-ctl">&#9654;</span></div>');
			$("#jac-glry-ctl > .bck-ctl").click(function() { that.manual_back(); });
			$("#jac-glry-ctl > .fwd-ctl").click(function() { that.manual_fwd(); });
		}
		else
			glry_ctl.show();
		var cptn_elem = $("#jac-glry-cptn");
		if(this.show_caption)
		{
			if(cptn_elem.length == 0)
			{
				var text = "";
				if(this._cur_sld != null)
				{
					text = this._cur_sld.attr("title") == "" ? "&nbsp;" : this._cur_sld.attr("title");
					text = text ? text : this._cur_sld.parent().attr("title");
				}
				(this.auto ? this._elem : glry_ctl).after('<div id="jac-glry-cptn">' + text + '</div>');
			}
			else
				cptn_elem.show();
		}
		else
			if(cptn_elem.length > 0)
				cptn_elem.hide();
	};
/* Stop the auto gallery.  Does nothing if it is already stopped or if "auto" property is false. */
jacJQueryGallery.prototype.stop =
	function()
	{
		if(this.auto && this._chg_timeout != null)
		{
			window.clearTimeout(this._chg_timeout);
			this._chg_timeout = null;
		}
		if(this.show_caption)
			this._elem.children("#jac-glry-cptn").hide();

	};
/* Removes an image at index given. */
jacJQueryGallery.prototype.remove_slide =
	function(idx)
	{
		if(idx < 0 || idx >= this._slides.length || idx == this._cur_idx || this._slides.length <= 1)
			return;
		// Take the slides out of the arrays.
		this._slides.splice(idx, 1);
		this._jq_slds.splice(idx, 1);
		// As long as there are still >= one slide, calculate the indices.
		if(this._slides.length == 0)
		{
			this._cur_idx = this._prev_idx = this._last_idx = 0;
			this._cur_sld = this._prev_sld = null;
		}
		else
		{
			--this._last_idx;
			if(idx < this._cur_idx)
			{
				if(this._cur_idx == 0)
					this._cur_idx = this._last_idx;
				else
					--this._cur_idx;
			}
			if(idx <= this._prev_idx)
				this._prev_idx = this._cur_idx == 0 ? this._last_idx : (this._cur_idx - 1);
			this._cur_sld = this._jq_slds[this._cur_idx];
			this._prev_sld = this._jq_slds[this._prev_idx];
		}
	};

jacJQueryGallery.prototype._pre_change_img =
	function(fwd)
	{
		if(this.pre_chg_f != null)
			this.pre_chg_f();
		if(fwd == null)
			fwd = true;
		// Set the values for prev/cur index and slides.
		this._prev_idx = this._cur_idx;
		if(fwd)
		{
			if(this._cur_idx == this._last_idx)
				this._cur_idx = 0;
			else
				++this._cur_idx;
		}
		else
		{
			if(this._cur_idx == 0)
				this._cur_idx = this._last_idx;
			else
				--this._cur_idx;
		}
		this._prev_sld = this._cur_sld;
		this._cur_sld = this._jq_slds[this._cur_idx];
	};
jacJQueryGallery.prototype._post_change_img =
	function()
	{
		if(this._prev_sld == null)
			return;
		// Reset the slide and bkgnd.
		this._prev_sld.removeClass("prev").css("opacity", 1);
		if(this.show_bkgnd && this._prev_sld.hasClass("sm") && !this._cur_sld.hasClass("sm"))
			this._bkgnd_elem.removeClass("prev");
		// Set a timeout for the next slide change if the slideshow is auto.
		if(this.auto)
		{
			var that = this;
			this._chg_timeout = window.setTimeout(function() { that.change_img(); }, this.img_time);
		}
		if(this.show_caption)
		{
			var text = this._cur_sld.attr("title");
			text = text ? text : this._cur_sld.parent().attr("title");
			$("#jac-glry-cptn").empty().append(text == "" ? "&nbsp;" : text);
		}
		if(this.post_chg_f != null)
			this.post_chg_f();
	};
/* Fade to the next image. */
jacJQueryGallery.prototype.change_img =
	function()
	{
		if(this._cur_sld == null)
			return;
		this._pre_change_img(true);
		// Change the slide classes to prep for animation.
		this._prev_sld.removeClass("cur").addClass("prev");
		this._cur_sld.addClass("cur");
		// Update the background if necessary.
		var prev_sm = false, cur_sm = false, that;
		if(this.show_bkgnd)
		{
			prev_sm = this._prev_sld.hasClass("sm");
			cur_sm = this._cur_sld.hasClass("sm");
			if(prev_sm && !cur_sm)
				this._bkgnd_elem.removeClass("cur").addClass("prev");
			else if(!prev_sm && cur_sm)
				this._bkgnd_elem.addClass("cur");
		}
		// Animate the slide, bkgnd if necessary.
		that = this;
		this._prev_sld.animate({opacity: 0}, this.fade_time, function() { that._post_change_img(); });
		if(this.show_bkgnd && prev_sm && !cur_sm)
			this._bkgnd_elem.animate({opacity: 0}, this.fade_time, function() { that._bkgnd_elem.css("opacity", 1); });
	};

jacJQueryGallery.prototype._manual_chg =
	function(fwd)
	{
		if(this._cur_sld == null)
			return;
		this._pre_change_img(fwd);
		this._prev_sld.removeClass("cur");
		this._cur_sld.addClass("cur");
		if(this.show_bkgnd)
		{
			if(this._cur_sld.hasClass("sm"))
				this._bkgnd_elem.addClass("cur");
			else
				this._bkgnd_elem.removeClass("cur");
		}
		this._post_change_img();
	};
/* Move back to the previous image when "auto" is false. */
jacJQueryGallery.prototype.manual_back = function() { this._manual_chg(false); };
/* Move forward to the next image when "auto" is false. */
jacJQueryGallery.prototype.manual_fwd = function() { this._manual_chg(true); };

