/**
 * @class HD.FeatureStoriesWidget
 * @description The purpose of FeatureStoriesWidget is to provide a mechanism to display events. 
 * 				Registered as hd_feature_stories_widget.
 * @constructor
 * @extends HD.Widget
 * @see HD.FeatureStoriesWidget.hooks
 * @see HD.FeatureStoriesWidget.templates
 * @see HD.community.Media.hooks
 * @property {object} 	config
 *                    	The configuration for the widget.
 * @property {object} 	[config.hooks=HD.FeatureStoriesWidget.hooks]
 *                 		Customized subset of hooks (merged with the defaults).
 * @property {number} 	config.pageSize
 *                    	The number of stories to show on a page.
 *                    	Default is 3.
 * @property {number} 	config.previewLength
 *                    	The number of characters of the preview text to be shown.
 *                    	Default is 140.
 * @property {string} 	config.contentFeed
 *                    	Type of media feed to use.
 *                    	Default is 'getPopular'.
 * @property {boolean} 	config.randomize
 *                    	Randomly sort the returned media.
 *                    	Default is false.
 * @property {object}  	[config.mediaHooks]
 *                 		Customized subset of hooks for HD.community.media.
 *                 		Used for all media types
 * @property {object} 	[config.templates=HD.FeatureStoriesWidget.templates]
 *                 		Customized subset of templates (merged with the defaults).
 */
HD.FeatureStoriesWidget = function(config) {
    this.config = config || {};
	this.config.pageSize = this.config.pageSize || 3;
	this.config.previewLength = this.config.previewLength || 140;
	this.config.contentFeed = this.config.contentFeed || 'getPopular';
	this.config.randomize = this.config.randomize || false;
	this.config.mediaHooks = this.config.mediaHooks || HD.community.Media.hooks;
	
	/** Observer collection */
    this.observers = [];
	this.loadTemplates(arguments.callee);
};

/**
 * The collection of default templates.
 * @fieldOf HD.FeatureStoriesWidget
 */
HD.FeatureStoriesWidget.templates = {
		
	/**
	 * Label for the widget
	 * @memberOf HD.FeatureStoriesWidget
	 */	
	featureStoriesLabel : 'Feature Stories',
	
	/**
	 * View story text for the widget
	 * @memberOf HD.FeatureStoriesWidget
	 */	
	viewStoryText       : 'View Story',
	
	/**
	 * View all stories text for the widget
	 * @memberOf HD.FeatureStoriesWidget
	 */	
	viewAllStoriesText  : 'View All Stories',
	
	/**
	 * Watch video text for the widget
	 * @memberOf HD.FeatureStoriesWidget
	 */	
	watchVideoText      : 'Watch Video',
	
	/**
	 * @constant
	 * @return {string} Label for the widget: featureStoriesLabel
	 * @memberOf HD.FeatureStoriesWidget
	 */
	getFeatureStoriesLabel : function() {
		return this.featureStoriesLabel;
	},
	
	/**
	 * @constant
	 * @return {string} View story text for the widget: viewStoryText
	 * @memberOf HD.FeatureStoriesWidget
	 */
	getViewStoryText : function() {
		return this.viewStoryText;
	},
	
	/**
	 * @constant
	 * @return {string} View all stories text for the widget: viewAllStoriesText
	 * @memberOf HD.FeatureStoriesWidget
	 */
	getViewAllStoriesText : function() {
		return this.viewAllStoriesText;
	},
	
	/**
	 * @constant
	 * @return {string} Watch video text for the widget: watchVideoText
	 * @memberOf HD.FeatureStoriesWidget
	 */
	getWatchVideoText : function() {
		return this.watchVideoText;
	},
	
	/**
	 * @constant
	 * @return {string} Main template for the widget
	 * @memberOf HD.FeatureStoriesWidget
	 */
	getHtml : function() {
		return this.html;
	},
	
	/** 
	 * Main template for the widget
	 * @memberOf HD.FeatureStoriesWidget
	 * @type jst_template
	 */	
	html :  '\
		<div class="${classes.FEATURE_STORIES} ${classes.WIDGET}">\
			<span class="${classes.TITLE}">${templates.getFeatureStoriesLabel()}</span>\
			<ul class="${classes.LIST}">\
				{for item in items}\
					<li class="${hooks.STORY}">${item|facade}\
						{if community.isVideo(item.contentType)}\
							<span class="${classes.VIDEO}"><a href="#featAnchor${item_index}" name="featAnchor${item_index}" class="${classes.VIEW} ${classes.CONTROL}">${templates.getWatchVideoText()}</a></span>\
						{else}\
							<span class="${classes.PHOTO}"><a href="#featAnchor${item_index}" name="featAnchor${item_index}" class="${classes.VIEW} ${classes.CONTROL}">${templates.getViewStoryText()}</a></span>\
						{/if}\
					</li>\
				{/for}\
			</ul>\
			<a href="#featAnchorAll" name="featAnchorAll" class="${classes.VIEW_ALL} ${classes.CONTROL} ${hooks.VIEW_ALL}">${templates.getViewAllStoriesText()}</a>\
		</div>'
};

(function() {
	var classes = HD.CSS_CLASSES;
	
	/**
	 * The collection of hooks
	 */
	HD.FeatureStoriesWidget.hooks = {
		
		/**
		 * Standalone: 0..n<br />
		 * Use: Story Container<br />
		 * @memberOf HD.FeatureStoriesWidget
		 */
		STORY : classes.FEATURE_STORIES + '-story',
		
		
		/**
		 * Standalone: (1)<br />
		 * Use: View all stories link/button<br />
		 * @memberOf HD.FeatureStoriesWidget
		 */
		VIEW_ALL : classes.FEATURE_STORIES + '-viewall'
		
	};
})();

HD.FeatureStoriesWidget.prototype = {
    
	/**
	 * Monitors events by HD.FeatureStoriesWidget.
	 * @param {string} eventName
	 *                 The name of the event
	 * @param {object} [eventData]
	 *                 Data for the event
	 */
    update : function(eventName, eventData) {
    	if(eventName == this.config.contentFeed+'_Start') {
    		this.loading(true);
    	} else if(eventName == this.config.contentFeed+'_Finish') {
    		this.loading(false);
			// Randomize the media if requested.
			if (this.config.randomize) {
				eventData.media.sort(function() { return 0.5 - Math.random(); });
			}
    		this.render(eventData);
    	}
    },
    
    /**
	 * Sets event listeners for the widget.
	 * @param {object} [data]
	 *                 Event data from the render phase
	 */
    setListeners: function(data) {
    	var classes = HD.CSS_CLASSES;
    	var parentEl = this.getParent();
    	var media = data.media;

		// Grab child elements.
		var items = HD.getByClass(this.config.hooks.STORY, '*', parentEl);
    	var viewAll = HD.getByClass(this.config.hooks.VIEW_ALL, '*', parentEl);
		var self = this;
		var j = 0;
		for (var i = 0, limit = Math.min(media.length, this.config.pageSize || 3); i < limit; i++) {
			(function() {
				var itemMedia = media[i];
				var fn = function() {
					self.notifyObservers('viewFeatureStory', itemMedia);
					return false;
				};
				if (items[i]) {
					items[i].onclick = fn;
				
					// Inject the rating.
			    	var avgRatingEl = HD.getByClass(self.config.mediaHooks.MEDIA_RATING_AVG, '*', items[i])[0] || null;
			    	var ratingsEl = avgRatingEl && (HD.getByClass(self.config.mediaHooks.MEDIA_RATING_STAR, '*', avgRatingEl)[0] || null);
			    	var numOfVotesEl = avgRatingEl && (HD.getByClass(self.config.mediaHooks.MEDIA_VOTES, '*', avgRatingEl)[0] || null);
					if (ratingsEl && numOfVotesEl){
						var staticRating = new HD.util.StarRating({
							// elements to render data in
							starRatingParent : ratingsEl,
							numOfVotesParent : numOfVotesEl,
				
							// data values
							numOfVotes : itemMedia.numberOfVotes,
							averageRating : itemMedia.rating,
				    		isStatic : true,
				    		itemId : itemMedia.mediaId,
	    		
				    		// config options
				    		numOfDecimals: 1,
				    		requiresLogin: false
				    	});
					}
				}
		
				// Override category clicked events
				if (!!itemMedia.category && items[i]) {
					var catEl = HD.getByClass(self.config.mediaHooks.MEDIA_CATEGORY, '*', items[i]);
					if (catEl[0]) {
						catEl[0].onclick = function(e) {
							self.notifyObservers('viewCategory', itemMedia.category);
							if (!e) var e = window.event;
							e.cancelBubble = true;
							if (e.stopPropagation) e.stopPropagation();
						};
					}
				}

				// Override tag clicked events
				if (itemMedia.tags && itemMedia.tags.length > 0 && items[i]) {
					var tagEls = HD.getByClass(self.config.mediaHooks.MEDIA_TAG, '*', items[i]);
					for (var k = 0, len = tagEls.length; k < len; k++) {
						(function() {
							var tag = itemMedia.tags[k];
							tagEls[k].onclick = function(e) {
								self.notifyObservers('viewTag', tag);
								if (!e) var e = window.event;
								e.cancelBubble = true;
								if (e.stopPropagation) e.stopPropagation();
							};
						})();
					}
				}
			})();
			j+=2;
    	}
		
		if (viewAll[0]){
	   		viewAll[0].onclick = function() {
				self.notifyObservers('viewAllFeatureStories', media);
				return false;
			};
		}
    },
    
    /**
	 * Renders the HTML for the widget based on dynamic data.
	 * @param {object} [data]
	 *                 Event data from the render phase
	 * @returns {string} HTML for the widget
	 */
    getHtml: function(data) {
		// Grab the subset of media and abbreviate the descriptions.
		var media = (data && data.media && data.media.slice(0, Math.min(data.media.length, this.config.pageSize || 3))) || [];
		for (var i = 0; i < media.length; i++) {
			media[i].description = HD.util.Common.ellipseText(media[i].description, this.config.previewLength);
		}
		return this.processTemplate(this.config.templates.getHtml(), {
			ratingClasses : HD.util.StarRating.CSS_CLASSES,
			items         : media,
			community	  : HD.community
		});
    }
};

HD.extend(HD.FeatureStoriesWidget, [HD.Widget]);

HD.register('hd_feature_stories_widget', 'HD.FeatureStoriesWidget', {version: "1.0", build: "1"});

