﻿/*global
	window
*/
/*members
	Images, KHTMLOpacity, MozOpacity, back, backgroundImage, 
   currentIndex, currentOpacity, displayFor, fadeIn, fadeStep, filter, 
   fore, frame, images, initImage, length, opacity, opacityStep, 
   rotateImage, setOpacity, setTimeout, style
*/

"use strict";

/**
 * The intent is to have this act as an encapsulating namespace for the 
 * various unique behaviors needed on the homepage of the CSM re-launch.
 *
 * @author Christopher Brett Fuller
 * @namespace Encapsulates unique homepage functionality and behaviors
 */
var HOMEPAGE =
{
	/**
	 * This subspace of the HOMEPAGE namespace encapsulates image functions
	 * related to the CSM slideshow.
	 * 
	 * A decent bit of this was pulled from http://clagnut.com, specifically
	 * from http://clagnut.com/sandbox/imagefades/.  The original author
	 * was Richard Rutter.  The basic initImage, setOpacity, and fadeIn
	 * functions are all part of his original design and have been modified
	 * by myself to work in conjuction with rotateImage.
	 *
	 * initImage is the kicker - it takes in an array of image URLs and an object
	 * that will act as a "frame" for the various images.  At least two images 
	 * must be passed into initImage - the images will fade in, display for a set
	 * amount of time, and rotate - indefinitely.
	 * 
	 * @author Richard Rutter
	 * @author Christopher Brett Fuller
	 */
	Images: {
		/**
		 * @private
		 * @static
		 *
		 * @property {HTMLElement} frame The object to act as a frame for the 
		 * images to be rotated through.
		 */
		frame: {},

		/**
		 * @private
		 * @static
		 *
		 * @property {Array} images Array of URLs of images to fade in, display, 
		 * fade out, and rotate through.
		 */
		images: [],

		/**
		 * @private
		 * @static
		 *
		 * @property {number} currentIndex Index of the current image relative
		 * to the images array.
		 */
		currentIndex: -1,

		/**
		 * @private
		 * @static
		 * @constant
		 *
		 * @property {number} displayFor Milliseconds for which to display a 
		 * given image.
		 */
		displayFor: 5000,

		/**
		 * @private
		 * @static
		 * @constant
		 *
		 * @property {number} opacityStep How far to push up (or down) the 
		 * opacity per modification - 0 (no change - don't do this) to 
		 * 100 (all the way).
		 */
		opacityStep: 5,

		/**
		 * @private
		 * @static
		 * @constant
		 *
		 * @property {number} fadeStep How many milliseconds to wait before
		 * fading an object again.
		 */
		fadeStep: 75,

		/**
		 * @private
		 * @static
		 *
		 * @property {number} currentOpacity The current opacity of the current
		 * image.
		 */
		currentOpacity: 100,

		/**
		 * setOpacity sets the image opacity as appropriate for the given 
		 * browser.
		 *
		 * @private
		 * @static
		 */
		setOpacity: function()
		{
			/**
			 * @private
			 */
			var	scope = HOMEPAGE.Images,
					foreType = typeof (scope.frame.fore);

			foreType = (foreType === "function") ? true : false;

			// Prevent Firefox flicker and bounds checking
			scope.currentOpacity = (scope.currentOpacity >= 100) ? 99.99 :
				((scope.currentOpacity < 0) ? 0.00 : scope.currentOpacity);

			if (foreType)
			{
				// Internet Explorer
				scope.frame.fore().style.filter = "alpha(opacity:" +
					scope.currentOpacity + ")";

				// Safari < 1.2, Konqueror
				scope.frame.fore().style.KHTMLOpacity =
					scope.currentOpacity / 100;

				// Older Mozilla and Firefox
				scope.frame.fore().style.MozOpacity =
					scope.currentOpacity / 100;

				// Safari 1.2, newer Mozilla and Firefox, CSS3
				scope.frame.fore().style.opacity = scope.currentOpacity / 100;
			}
			else
			{
				// Internet Explorer
				scope.frame.fore.style.filter = "alpha(opacity:" +
					scope.currentOpacity + ")";

				// Safari < 1.2, Konqueror
				scope.frame.fore.style.KHTMLOpacity = scope.currentOpacity / 100;

				// Older Mozilla and Firefox
				scope.frame.fore.style.MozOpacity = scope.currentOpacity / 100;

				// Safari 1.2, newer Mozilla and Firefox, CSS3
				scope.frame.fore.style.opacity = scope.currentOpacity / 100;
			}
		},
		
		/**
		 * After displayFor milliseconds, the image will be rotated and the
		 * process will begin again.
		 *
		 * @private
		 * @static
		 */
		fadeIn: function()
		{
			/**
			 * @private
			 */
			var scope = HOMEPAGE.Images;

			if (scope.currentOpacity >= 0)
			{
				scope.setOpacity();
				scope.currentOpacity -= scope.opacityStep;
				window.setTimeout(scope.fadeIn, scope.fadeStep);
			}
			else
			{
				window.setTimeout(scope.rotateImage, scope.displayFor);
			}
		},

		/**
		 * rotateImage replaces the current background image in the frame with
		 * another image by pulling the next URL in the images array (if present)
		 * and changing the background's source .
		 *
		 * @private
		 * @static
		 */
		rotateImage: function()
		{
			/**
			 * @private
			 * @static
			 */
			var	scope = HOMEPAGE.Images,
					foreType = typeof (scope.frame.fore),
					backType = typeof (scope.frame.back);

			foreType = (foreType === "function") ? true : false;
			backType = (backType === "function") ? true : false;

			scope.currentIndex += 1;
			scope.currentIndex %= scope.images.length;

			if (foreType)
			{
				if (backType)
				{
					scope.frame.fore().style.backgroundImage =
						scope.frame.back().style.backgroundImage;
				}
				else
				{
					scope.frame.fore().style.backgroundImage =
						scope.frame.back.style.backgroundImage;
				}
			}
			else
			{
				if (backType)
				{
					scope.frame.fore.style.backgroundImage =
						scope.frame.back().style.backgroundImage;
				}
				else
				{
					scope.frame.fore.style.backgroundImage =
						scope.frame.back.style.backgroundImage;
				}
			}

			scope.currentOpacity = 100;
			scope.setOpacity();

			if (backType)
			{
				scope.frame.back().style.backgroundImage =
					"url(" + scope.images[scope.currentIndex] + ")";
			}
			else
			{
				scope.frame.back.style.backgroundImage =
					"url(" + scope.images[scope.currentIndex] + ")";
			}

			window.setTimeout(scope.fadeIn, scope.fadeStep);
		},

		/**
		 * initImage takes in o, an object acting as a frame for the images,
		 * an array of image URLs to be rotated through, and the initial wait
		 * before beginning rotation
		 *
		 * @public
		 * @static
		 *
		 * @param {HTMLElement} o The element acting as a frame; o must
		 * have back and fore attributes that return a reference to
		 * foreground and background objects.
		 * @param {Array} arrayURLs The array of URLSs of images to rotate
		 * through.
		 * @param {number} wait The time, in milliseconds, to wait before
		 * actually starting the rollovers.
		 */
		initImage: function(o, arrayURLs, wait)
		{
			/**
			 * @private
			 */
			var scope = HOMEPAGE.Images;

			if (!wait)
			{
				wait = scope.displayFor;
			}

			if (arrayURLs)
			{
				if (arrayURLs.length && o.back && o.fore && arrayURLs.length > 1)
				{
					scope.images = arrayURLs;
					scope.frame = o;

					window.setTimeout(scope.rotateImage, wait);
				}
			}
		}
	}};