///////////////////////////////////////////////////////////////////////////////
//	Core
///////////////////////////////////////////////////////////////////////////////
/**
 * The Bud Global object.
 * @title  Bud Global
 * @module Bud
 */

/**
 * The Bud global namespace object.
 * @namespace
 * @class Bud
 * @static
 */
var Bud = {};

///////////////////////////////////////////////////////////////////////////////
//	Environment
///////////////////////////////////////////////////////////////////////////////
/**
 * The Bud Environment
 * @module env
 * @title Environment
 */

/**
 * @namespace Bud
 * @title Bud Environment
 * @class env
 * @static
 */
Bud.env = {};

///////////////////////////////////////////////////////////////////////////////
//	Language
///////////////////////////////////////////////////////////////////////////////
/**
 * The Language Components
 * @module lang
 * @title Language Components
 */

/**
 * The lang class
 * @namespace Bud
 * @class lang
 * @static
 */
Bud.lang = {};

///////////////////////////////////////////////////////////////////////////////
//	User Interface Components
///////////////////////////////////////////////////////////////////////////////
/**
 * The User Interface Components
 * @module ui
 * @title User Interface Components
 */

/**
 * The ui class
 * @namespace Bud
 * @class ui
 * @static
 */
Bud.ui = {};

Bud.ui.Gallery = (function () {
	var Gallery = function (options) {
		this.currentIndex = null;
		this.galleryItems = null;
		this.lastIndex = null;
		this.navigationItems = null;

		if (typeof options.galleryItems !== 'undefined') {
			this.setGalleryItems(options.galleryItems);
		}

		if (typeof options.navigationItems !== 'undefined') {
			this.setNavigationItems(options.navigationItems);
		}
	};

	var proto = Gallery.prototype;

	proto.goTo = function (index) {
		if (typeof this.galleryItems[index] !== 'undefined' && this.currentIndex !== index) {
			this.lastIndex = (typeof this.currentIndex !== 'undefined') ? this.currentIndex : null;
			this.currentIndex = index;
			$(this).trigger('update', [index]);
		}
		return index;
	};

	proto.next = function () {
		var nextSlide = (this.currentIndex || 0) + 1;
		$(this).trigger('next', [this.goTo(nextSlide)]);
	};

	proto.previous = function () {
		var previousSlide = (this.currentIndex || 0) + 1;
		$(this).trigger('previous', [this.goTo(previousSlide)]);
	};

	proto.setGalleryItems = function (galleryItems) {
		this.galleryItems = galleryItems;
	};

	proto.setNavigationItems = function (navigationItems) {
		var that = this;
		this.navigationItems = navigationItems;
		$(this.navigationItems).each(function (index) {
			$(this).bind('click', Bud.util.Event.createDelegate(that, that.handleNavigationClick));
		});
	};

	proto.handleNavigationClick = function (event) {
		event.preventDefault();
		for (var i = 0, j = this.navigationItems.length; i < j; i = i + 1) {
			if (this.navigationItems[i] === event.currentTarget) {
				this.goTo(i);
				break;
			}
		}
	};

	return Gallery;
}());

///////////////////////////////////////////////////////////////////////////////
//	Utilities
///////////////////////////////////////////////////////////////////////////////
/**
 * A collection of useful utilities.
 * @module util
 * @title Utilities
 */

/**
 * The util class
 * @namespace Bud
 * @class util
 * @static
 */
Bud.util = {};

/**
 * The Event utility.
 * @namespace Bud.util
 * @class Event
 * @static
 */
Bud.util.Event = {
	/**
	 * A helper method that creates a function to call the specified function
	 * within the context of the specified object.
	 * @method createDelegate
	 * @param context {Object} The object that will become <code>this</code>
	 * when the specified function is called.
	 * @param func {Function} The function to be called.
	 * @return {Function}
	 */
	createDelegate: function (context, func) {
		return function () {
			// Call function within context of specified object
			func.apply(context, arguments);
		};
	},
	/**
	 * Dummy event handler that prevents default event behavior.
	 * @method dummyEventHandler
	 * @param e {Event}
	 */
	dummyEventHandler: function (e) {
		e.preventDefault();
	}
};