/**
 * automated slideshow images
 * subclass of: bestfit
 *
 * - initializes itself
 *
 * requires:
 * - jquery.js
 * - object.js
 * - bestfit.js
 */

jQuery(function ($) {
	(function () {
		var
			slideshow = window.slideshow = {
				"options": {
					"duration": 1000,
					"pause": 5000
				},
				"mysuper": window.bestfit
			},
			$window = $(window);





		function controllerDispatchTransition() {
			this.view.transition(this.model.current, this.model.getIndexNext(), this.options.duration, $.proxy(this.showNext, this));
			this.model.next();
		}

		function controllerInit($viewElement, $sheet) {
			this.options = slideshow.options;
			this.model = Object.create(slideshow.model);
			this.view = Object.create(slideshow.view);

			this.mysuper.init.apply(this, [$viewElement, $sheet]);

			// if we have fewer than 2 images, we only need resizing and stop here
			if (2 > this.view.countImages()) {
				return;
			}

			this.showStart();
		}

		function controllerShowNext() {
			this.startTime = new Date().getTime();
			this.model.getImageNext()
				.done($.proxy(this.view.switchImage, this.view))
				.done($.proxy(this.dispatchRealignment, this))
				.done($.proxy(this.showScheduleTransition, this));
		}

		function controllerShowScheduleTransition() {
			var remaining = Math.max(1, this.options.pause - new Date().getTime() + this.startTime);
			this.transitionTimeout = setTimeout($.proxy(this.dispatchTransition, this), remaining);
		}

		function controllerShowStart() {
			this.dispatchBestFit()
				.done($.proxy(this.showNext, this));
		}





		function modelPathnameSourceAttributes(dimensions) {
			return (window.location.pathname + "/").replace("//", "/") + "bgimage/" + dimensions.width + "/" + dimensions.height;
		}





		function viewGetItemElements() {
			var $result = $();

			this.$imgElements.each(function (i, imgElement) {
				$result = $result.add($(imgElement).closest(".item"));
			});

			return $result;
		}

		function viewGetInnerElements() {
			var $result = $();

			this.$itemElements.each(function (i, itemElement) {
				$result = $result.add($(".inner img", itemElement));
			});

			return $result;
		}

		function viewInit($element, $sheet) {
			this.mysuper.init.apply(this, [$element, $sheet]);
			this.$itemElements = this.getItemElements();
			this.$innerElements = this.getInnerElements();

			this.$itemElements
				.css("z-index", 0)
				.eq(0)
					.css("z-index", 1).show();

			this.$imgElements
				.hide()
				.eq(0)
					.show();

			this.$innerElements
				.hide()
				.eq(0)
					.show();
		}

		function viewTransition(indexCurrent, indexNext, duration, callback) {
			var
				$imgElements = this.$imgElements,
				$innerElements = this.$innerElements;
			this.alignImage(indexNext);

			$imgElements.eq(indexCurrent).fadeOut(duration, function () {
				$(this).closest(".item").css("z-index", 0).show();
			});
			$innerElements.eq(indexCurrent).hide();

			$imgElements.eq(indexNext).fadeIn(duration, function () {
				$(this).closest(".item").css("z-index", 1);
				$innerElements.eq(indexNext).show();
				callback();
			});
		}





		slideshow.controller = $.extend({}, slideshow.mysuper.controller, {
			dispatchTransition: controllerDispatchTransition,
			init: controllerInit,
			showNext: controllerShowNext,
			showScheduleTransition: controllerShowScheduleTransition,
			showStart: controllerShowStart,
			mysuper: slideshow.mysuper.controller
		});

		slideshow.model = $.extend({}, slideshow.mysuper.model, {
			pathnameSourceAttributes: modelPathnameSourceAttributes,
			mysuper: slideshow.mysuper.model
		});

		slideshow.view = $.extend({}, slideshow.mysuper.view, {
			getInnerElements: viewGetInnerElements,
			getItemElements: viewGetItemElements,
			init: viewInit,
			transition: viewTransition,
			mysuper: slideshow.mysuper.view
		});
	}());





	var slideshow = Object.create(window.slideshow.controller);
	slideshow.init($("#image"), $("#sheet"));
});
