/**
 * @fileoverview	explorelongisland.com Deal of the Day Module Javascript
 * @author			Michael Bester <mbester@schematic.com>
 * @version			1.0
 * @dependencies	jquery.js (v.1.3.x)
 *					global.js
 */

( XLI.DealOfTheDay = function() {

	/**
		A Flag to keep track of whether or not we've initialized this object.
	*/
	var initialized = false;

	/**
		Deal of the day Filters
	*/
	var FILTERS = {
		'dining'	: "Dining Deals",
		'beauty'	: "Beauty Deals"
	};

	/**
	 *	Set Some Constants
	 */
	var CONSTANTS = {

		// The URL for deal data
		DATA_URL : "http://longisland.newsday.com/polopoly/JSON_feed.php",

		// Add to favorites base URL
		ADD_TO_FAVES_URL : "/favorites/add/",

		// ID for the DoD module
		MODULE_ID : "#dealOfTheDay",

		// head class
		HEAD_CLASS : "head",

		// body class
		BODY_CLASS : "body",

		// Name to apply to the category filter radio buttons.
		FILTER_RADIO_NAME : 'category',

		// Button class
		BUTTON_CLASS : 'button',

		// More class
		MORE_CLASS : 'more',

		// Loading class
		LOADING_CLASS : 'loading',

		// Show label text
		SHOW_LABEL_TEXT : 'Show: ',

		// All label text :
		ALL_LABEL_TEXT : ' All Deals',

		// Toggle button closed Text
		BUTTON_CLOSED_TEXT : 'Explore Deals',

		// Toggle button open Text
		BUTTON_OPEN_TEXT : 'Hide Deals',

		// Save to favorites text.
		SAVE_TO_FAVES_TEXT : 'Save to Favorites',

		// Scroll Speed (in milliseconds)
		SCROLL_SPEED : 500
	};

	/**
	 *	Element References as returned by JQuery
	 *	references created as needed
	 */
	var $elements = {

		document : null,

		// The DoD module
		module : null,

		// the module head
		moduleHead : null,

		// The module body
		moduleBody : null,

		// wrapper element for the body.
		bodyWrapper : null,

		// Filters
		filters	: null,

		// scrollable area
		scrollable : null,

		// Deal list
		dealList : null,

		// The "Explore Deals" button
		toggleButton : null

	};

	/**
	 *	Shorthand references to the CONSTANTS and $elements.
	 */
	var C	= CONSTANTS;
	var $e	= $elements;

	/**
		Initialize the module, creating the extra HTML necessary for explore deals.
	*/
	initDOD = function() {

		var H = {
			DIV			: '<div></div>',
			UL			: '<ul></ul>',
			P			: '<p></p>',
			A			: '<a></a>',
			FIELDSET	: '<fieldset></fieldset>',
			LABEL		: '<label></label>',
			INPUT		: '<input />'
		};

		// Find elements we'll need.
		$e.document		= $(document);
		$e.moduleHead	= $e.module.find('.' + C.HEAD_CLASS);

		// Create the body and set it up for animation
		$e.moduleBody	= $(H.DIV)
							.addClass(C.BODY_CLASS)
							.css({
								'position' : 'relative',
								'top' : '-1000px'
							});

		$e.bodyWrapper	= $(H.DIV)
							.css({
								'position' : 'relative',
								'overflow' : 'hidden',
								'height' : 0
							})
							.append($e.moduleBody)
							.appendTo($e.module);

		// Set up elements we'll need in the body.
		// ...filters...
		$e.filters		= $(H.FIELDSET)
							.append(
								$(H.P).text(C.SHOW_LABEL_TEXT),
								$(H.LABEL)
									.append(
										$('<input type="radio" value="" name="' + C.FILTER_RADIO_NAME + '" />')
											//.bind('change', updateDeals)
											.bind('click', updateDeals),
										C.ALL_LABEL_TEXT
									)
							);

		$.each(FILTERS, function(key, label){
			$e.filters.append(
				$(H.LABEL)
					.append(
						$('<input type="radio" value="' + key + '" name="' + C.FILTER_RADIO_NAME + '" />')
							//.bind('change', updateDeals)
							.bind('click', updateDeals),
						label
					)
			);
		});

		$e.filters.appendTo($e.moduleBody);

		// ..the target list...
		$e.dealList		= $(H.UL);

		// ...the scrollable section...
		$e.scrollable	= $(H.DIV)
							.addClass(XLI.Global.C.SCROLLABLE_CLASS)
							.append($e.dealList)
							.appendTo($e.moduleBody)
							.jScrollPane();

		// ...and finally, the "explore deals button"
		$e.toggleButton	= $(H.A)
							.bind('click', toggleBody)
							.text(C.BUTTON_CLOSED_TEXT)
							.addClass(C.BUTTON_CLASS);

		$(H.P)
			.addClass(C.MORE_CLASS)
			.append($e.toggleButton)
			.appendTo($e.moduleHead);


	};

	/**
		Some flags which state
		 	- whether the body is open or closed
			- whether or not we're animating
			- whether we've made our first XHR
	 */
	var state = "closed";
	var animating = false;
	var populated = false;

	/**
	 * Opens and closes the deal of the day body.
	 * @private
	 * @returns nothing
	 */
	var toggleBody = function(e) {
		e.preventDefault();

		if (animating) {
			return;
		}

		animating = true;

		var height = $e.moduleBody.outerHeight(true);

		if (state === "closed") {
			// Slide in the body.
			$e.moduleBody
				.css({
					'top' : 0 - height
				})
				.animate({
					'top' : 0
				},  C.SCROLL_SPEED, 'easeOutQuad', function(){
					state = "open";
					animating = false;
					$e.toggleButton.text(C.BUTTON_OPEN_TEXT);
				});

			// Got to open up the body wrapper as well
			$e.bodyWrapper.animate({
				'height' : height
			},  C.SCROLL_SPEED, 'easeOutQuad');

			// If we haven't populated the list, let's preselect the first item (all)
			if (!populated) {
				$e.filters.find('input[type=radio]:first')
					.trigger('click')
					.trigger('change');
			}

		} else {
			// Slide out the body.
			$e.moduleBody
				.css({
					'top' : 0
				})
				.animate({
					'top' : 0 - height
				},  C.SCROLL_SPEED, 'easeOutQuad', function(){
					state = "closed";
					animating = false;
					$e.toggleButton.text(C.BUTTON_CLOSED_TEXT);
				});

			// Got to scroll up the body wrapper as well
			$e.bodyWrapper.animate({
				'height' : 0
			},  C.SCROLL_SPEED, 'easeOutQuad');
		}
	};

	/**
	 * Initializes the XHR to get deal data
	 * @private
	 * @returns nothing
	 */
	var updateDeals = function() {
		// the radio that was clicked
		var $this = $(this);

		try {

			$e.dealList.empty();
			$e.scrollable
				.addClass(C.LOADING_CLASS)
				.jScrollPane();

			$.ajax({
				url			: C.DATA_URL,
				dataType	: 'jsonp',
				data		: ($this.attr('name') + '=' + $this.val()),
				error		: function(xhr, message){
					$e.scrollable.removeClass(C.LOADING_CLASS);
					XLI.Debug.error("Response Error requesting Deal of the day Data :" + message);
				},
				success		: function(json){
					$e.scrollable.removeClass(C.LOADING_CLASS);
					populateList(json);
				}
			});
		} catch(e) {
			$e.scrollable.removeClass(C.LOADING_CLASS);
			XLI.Debug.error("Ajax Error requesting Deal of the day Data :" + e.message);
		}
	};

	/**
	 * Takes a successful response and populates the list with the data
	 * @private
	 * @param {Object} json The json data that gets returned from the updateDeals XHR
	 * @returns nothing
	 */
	var populateList = function(json) {
		if (!$.isArray(json.deals)) {
			return;
		}

		$.each(json.deals, function(){
			$('<li></li>')
				.append(
					$('<a></a>')
						.addClass(XLI.Global.C.IR_CLASS)
						.addClass('iframe')
						.attr('title', C.SAVE_TO_FAVES_TEXT)
						.attr('href', C.ADD_TO_FAVES_URL + this.href.substring(this.href.indexOf('?'), this.href.length))
						.append(
							$('<span></span>'),
							C.SAVE_TO_FAVES_TEXT
						)
						// Set up the lightbox
						.fancybox({
							'zoomOpacity'			: true,
							'zoomSpeedIn'			: 300,
							'zoomSpeedOut'			: 300,
							'easingIn'				: 'linear',
							'easingOut'				: 'linear',
							'hideOnContentClick'	: false,
							'frameWidth'			: 300,
							'frameHeight'			: 200
						}),
					$('<a></a>')
						.attr('href', this.href)
						.text(this.description)
				)
				.appendTo($e.dealList);
		});

		// Reinitialize the scrollbar
		$e.scrollable.jScrollPane();
	};

	return {

		/**
		 * Sets up the Deal of the day section.
		 * @public
		 * @returns nothing
		 */
		initialize : function() {
			if (initialized) {
				return;
			}

			// Create a reference to the module.
			$e.module = $(C.MODULE_ID);

			// And bail out if we can't find it.
			if (!$e.module.length) {
				return;
			}

			initDOD();

			initialized = true;
		}

	};

}());


/**
	Fire it up.
*/
$(document).ready(XLI.DealOfTheDay.initialize);