/**
 * @class HD.SendFriendWidget
 * @description The purpose of SendFriendWidget is to provide a mechanism for users to 
 * 				email page content to others
 * 				Registered as hd_send_friend_widget.
 * @constructor
 * @extends HD.Widget
 * @see HD.SendFriendWidget.hooks
 * @see HD.SendFriendWidget.templates
 * @property {object} 	config
 *                    	The configuration for the widget.
 * @property {object} 	[config.hooks=HD.SendFriend.hooks]
 *                 		Customized subset of hooks (merged with the defaults).
 * @property {boolean} 	config.embedMode
 *                    	TBD
 *                    	Default is false.
 * @property {boolean} 	config.standaloneMode
 *                    	Whether the send friend widget should not be dependent on retrieving content
 *                    	Default is false.
 * @property {boolean} 	config.showTooltop
 *                    	Whether the send friend widget should show a tooltip like share widget 
 *                    	Default is false.
 * @property {boolean} 	config.sendAnother
 *                    	Whether confirmation overlay button should reopen the send form
 *                    	Default is false.
 * @property {method}	config.callback
 * 						Code to be executed when the button is clicked
 * @property {object} 	config.submission
 *                 		Submission configuration
 * @property {string} 	config.submission.url
 *                 		URL to submit entry form to
 *                 		Default is 'http://hdonline.rsys1.net/servlet/campaignrespondent'
 * @property {string}	config.submission.id
 * 						Submission id for form submission
 * 						Default is 'hdm.526'
 * @property {string}	config.submission.community
 * 						Community for form submission
 * 						Default is 'Harley-Davidson'
 * @property {string}	config.submission.media
 * 						Media ID of the content to be sent
 * 						Default is null
 * @property {string}	config.overlayHeight
 * 						Height of the overlay
 * 						Default is 290px
 * @property {string}	config.overlayWidth
 * 						Width of the overlay
 * 						Default is 425px
 * @property {method}	config.submission.getParams
 * 						Returns additional params for submission
 * 				         
 */
HD.SendFriendWidget = function(config) {
    this.config = config || {};
	this.config.embedMode = this.config.embedMode || false;
	this.config.standaloneMode = this.config.standaloneMode || false;
	this.config.showTooltip = this.config.showTooltip || false;
	this.config.sendAnother = this.config.sendAnother || false;
	this.config.callback = this.config.callback || function(media, shareUrl) {};
	this.config.submission = this.config.submission || {};
	this.config.submission.url = this.config.submission.url || 'http://hdonline.rsys1.net/servlet/campaignrespondent';
	this.config.submission.id = this.config.submission.id || 'hdm.526';
	this.config.submission.community = this.config.submission.community || window.comSiteName || 'Harley-Davidson';
	this.config.submission.media = null;
	this.config.overlayHeight = this.config.overlayHeight || "290px";
	this.config.overlayWidth = this.config.overlayWidth || "425px";
	this.config.getParams = this.config.getParams || function(params, media) {
		params.view = 'detail';
		// params.param1 = 'some value 1';
		// params.param2 = 'some value 2';
		// params.param3 = 'some value 3';
		return params;
	};
	
	/** Observer collection */
    this.observers = [];
	this.loadTemplates(arguments.callee);
};

/**
 * The collection of default templates.
 * @fieldOf HD.SendFriendWidget
 */
HD.SendFriendWidget.templates = {
		
	/**
	 * Label for the widget
	 * @memberOf HD.SendFriendWidget
	 */
	sendFriendLabel             : "Send to a Friend",
	
	/**
	 * Error text for required sender name
	 * @memberOf HD.SendFriendWidget
	 */
	errorUserNameText           : "Your Name is a required field (*)",
	
	/**
	 * Error text for required friend name
	 * @memberOf HD.SendFriendWidget
	 */
	errorFriendNameText         : "Your Friend's Name is a required field (*)",
	
	/**
	 * Error text for required friend email
	 * @memberOf HD.SendFriendWidget
	 */
	errorFriendEmailText        : "Your Friend's Email is a required field (*)",
	
	/**
	 * Error text for invalid friend email
	 * @memberOf HD.SendFriendWidget
	 */
	errorFriendEmailInvalidText : "Your Friend's Email address is not valid",
	
	/**
	 * Error text for required sender email
	 * @memberOf HD.SendFriendWidget
	 */
	errorYourEmailText          : "Your Email is a required field (*)",
	
	/**
	 * Error text for invalid sender email
	 * @memberOf HD.SendFriendWidget
	 */
	errorYourEmailInvalidText   : "Your Email address is not valid",
	
	/**
	 * Instructional text for overlay
	 * @memberOf HD.SendFriendWidget
	 */
	sendFriendInstructionalText : "<p>Send your friend a link to this page so they can become involved in the community.</p><p>Enter the name and Email address of your friend below. We will not use this information for any other purposes. Review our <a onclick=\"javascript:window.open('http://www.harley-davidson.com/wcm/Content/Pages/Utility/privacy_policy.jsp?locale=en_US', '', 'width=598,height=540,scrollbars=yes,resizable=yes,toolbar=no,location=no,menubar=no,directories=no,status=no')\" href=\"javascript:void(0)\">Privacy Policy</a> for more details.</p><p>* Indicates required fields</p>",

	/**
	 * @constant
	 * @return {string} Label for the widget: sendFriendLabel
	 * @memberOf HD.SendFriendWidget
	 */
	getSendFriendLabel : function(){
		return this.sendFriendLabel;
	},

	/**
	 * @constant
	 * @return {string} Error text for required sender name: errorUserNameText
	 * @memberOf HD.SendFriendWidget
	 */
	getErrorUserNameText : function(){
		return this.errorUserNameText;
	},

	/**
	 * @constant
	 * @return {string} Error text for required friend name: errorFriendNameText 
	 * @memberOf HD.SendFriendWidget
	 */
	getErrorFriendNameText : function(){
		return this.errorFriendNameText;
	},

	/**
	 * @constant
	 * @return {string} Error text for required friend email: errorFriendEmailText  
	 * @memberOf HD.SendFriendWidget
	 */
	getErrorFriendEmailText : function(){
		return this.errorFriendEmailText;
	},

	/**
	 * @constant
	 * @return {string} Error text for invalid friend email: errorFriendEmailInvalidText  
	 * @memberOf HD.SendFriendWidget
	 */
	getErrorFriendEmailInvalidText : function(){
		return this.errorFriendEmailInvalidText;
	},

	/**
	 * @constant
	 * @return {string} Error text for required sender email: errorYourEmailText   
	 * @memberOf HD.SendFriendWidget
	 */
	getErrorYourEmailText : function(){
		return this.errorYourEmailText;
	},

	/**
	 * @constant
	 * @return {string} Error text for invalid sender email: errorYourEmailInvalidText   
	 * @memberOf HD.SendFriendWidget
	 */
	getErrorYourEmailInvalidText : function(){
		return this.errorYourEmailInvalidText;
	},
	
	/**
	 * @constant
	 * @return {string} Instructional text for overlay: sendFriendInstructionalText 
	 * @memberOf HD.SendFriendWidget
	 */
	getInstructionalText : function(){
		return this.sendFriendInstructionalText;
	},
	
	/**
	 * @constant
	 * @return {string} Main template for the widget
	 * @memberOf HD.SendFriendWidget
	 */
	getHtml : function() {
		return this.html;
	},
	
	/** 
	 * Main template for the widget
	 * @memberOf HD.SendFriendWidget
	 * @type jst_template
	 */	
	html :  '\
		<div class="${classes.SEND_FRIEND} ${classes.WIDGET}">\
			<span class="${hooks.SENDBUTTON}">${templates.getSendFriendLabel()}</span>\
			<div class="${hooks.SENDBUTTON_TOOLTIP}">${templates.getSendFriendLabel()}</div>\
		</div>'
};

(function() {
	var classes = HD.CSS_CLASSES;
	
	/**
	 * The collection of hooks
	 */
	HD.SendFriendWidget.hooks = {
		
		/**
		 * Standalone: (1)<br />
		 * Use: Button to launch send to friend overlay<br />
		 * @memberOf HD.SendFriendWidget
		 */
		SENDBUTTON : classes.SEND_FRIEND + '-button',
		
		/**
		 * Standalone: (1)<br />
		 * Use: Tooltip for button<br />
		 * @memberOf HD.SendFriendWidget
		 */
		SENDBUTTON_TOOLTIP : classes.SEND_FRIEND + '-tooltip'
		
	};
})();

HD.SendFriendWidget.prototype = {
    
	/**
	 * Sets event listeners for the widget.
	 * @param {object} [data]
	 *                 Event data from the render phase
	 */
    setListeners : function(media) {
		if (!media) {
			return;
		}
		
		var self = this;
		// Add click events.
		var sendFriendEl = HD.getByClass(this.config.hooks.SENDBUTTON, '*', this.getParent())[0];
		
		if(sendFriendEl){
			var tooltipEl = HD.getByClass(this.config.hooks.SENDBUTTON_TOOLTIP, '*', this.getParent())[0];
			if (tooltipEl){
				sendFriendEl.onmouseover = function() {
					HD.addClass(tooltipEl, HD.CSS_CLASSES.SHARE+'Hover');
				};
				sendFriendEl.onmouseout = function() {
					HD.removeClass(tooltipEl, HD.CSS_CLASSES.SHARE+'Hover');
				};
			}
		}
		
		sendFriendEl.onclick = function() {
			self.openForm(media);
		};
    },
    
    /**
	 * Monitors events by HD.SendFriendWidget.
	 * @param {string} eventName
	 *                 The name of the event
	 * @param {object} [eventData]
	 *                 Data for the event
	 */
    update : function(eventName, eventData) {
		if (!this.config.embedMode) {
			if (this.config.standaloneMode){
	    		if(eventName == "loadSTAF_Start") {
	    			this.render(eventData);
	    		}
	    	}
	    	else if(eventName == "getMedium_Start") {
	    		this.loading(true);
	    	} else if(eventName == "getMedium_Finish") {
	    		this.loading(false);
	    		this.render(eventData);
	    	} else if(eventName == "activeItem_Change") {
	    		this.render(eventData);
	    	}
		}
    },
    
    /**
	 * 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(media) {
		if (!media) {
			return;
		}
		
		return this.processTemplate(this.config.templates.getHtml(), {});
    },
    
    /**
	 * Opens the form overlay.
	 * @param {object} [data]
	 *                 Event data from the render phase
	 */
    openForm : function(media){
    	var self = this;
    	self.config.callback(media);
		HD.util.Analytics.track(self.analyticsSendFriendString(media));
		HD.util.Common.requestContent(comSvcBaseUrl + '/hd/hd_send_friend/assets/sendToFriend.jsp?siteName=' + comSiteName, function(responseText) {
			var overlayEl = HD.util.Common.showOverlay(responseText, HD.SendFriendWidget.templates.getSendFriendLabel().toUpperCase(), self.config.overlayWidth, self.config.overlayHeight);
			
			// Add instructional text
			var instructionalEl = HD.util.Common.get('sendFriendInstructions');
			if (instructionalEl){
				instructionalEl.innerHTML = HD.SendFriendWidget.templates.getInstructionalText();
			}
			
			var formEl = overlayEl.getElementsByTagName("form")[0];

			formEl.onsubmit = function() {					
				self.handleSubmit(formEl, media);				
				return false;
			};
		});
    },

    /**
	 * Submits the form.
	 * @param {HTMLElement} form
	 *                 		The form containing the input fields
	 * @param {object} 		[eventData]
	 *                 		Data for the event
	 */
	handleSubmit : function (form, media) {
    	var errorText = '';
		var emailValidate = /.+@.+\..+/;
		var self = this;
		// Gather the data
		var userName = form.userName.value;
		var userEmail = form.userEmail.value;
		var friendName = form.friendName.value;
		var friendEmail = form.friendEmail.value;	
		var templates = HD.SendFriendWidget.templates;
		
		// Handle errors
		HD.removeClass(HD.get(HD.CSS_CLASSES.SEND_FRIEND+'-UserName'), 'hdwcValidationError');
		HD.removeClass(HD.get(HD.CSS_CLASSES.SEND_FRIEND+'-FriendName'), 'hdwcValidationError');
		HD.removeClass(HD.get(HD.CSS_CLASSES.SEND_FRIEND+'-UserEmail'), 'hdwcValidationError');
		HD.removeClass(HD.get(HD.CSS_CLASSES.SEND_FRIEND+'-FriendEmail'), 'hdwcValidationError');
		var errorsEl = HD.get('hdValidationErrors');
		
		if (!userName) {
			errorText += '<div class="hdwcErrorOverlayLarge">' + templates.getErrorUserNameText() + '</div>';
			HD.addClass(HD.get(HD.CSS_CLASSES.SEND_FRIEND+'-UserName'), 'hdwcValidationError');
		}
		if (!friendName) {
			errorText += '<div class="hdwcErrorOverlayLarge">' + templates.getErrorFriendNameText() + '</div>';
			HD.addClass(HD.get(HD.CSS_CLASSES.SEND_FRIEND+'-FriendName'), 'hdwcValidationError');
		}
		
		if (!userEmail) {
			errorText += '<div class="hdwcErrorOverlayLarge">' + templates.getErrorYourEmailText() + '</div>';
			HD.addClass(HD.get(HD.CSS_CLASSES.SEND_FRIEND+'-UserEmail'), 'hdwcValidationError');
		}
		else if (!userEmail.match(emailValidate)) {
			errorText += '<div class="hdwcErrorOverlayLarge">' + templates.getErrorYourEmailInvalidText() + '</div>';
			HD.addClass(HD.get(HD.CSS_CLASSES.SEND_FRIEND+'-UserEmail'), 'hdwcValidationError');
		}
		if (!friendEmail) {
			errorText += '<div class="hdwcErrorOverlayLarge">' + templates.getErrorFriendEmailText() + '</div>';
			HD.addClass(HD.get(HD.CSS_CLASSES.SEND_FRIEND+'-FriendEmail'), 'hdwcValidationError');
		}
		else if (!friendEmail.match(emailValidate)) {
			errorText += '<div class="hdwcErrorOverlayLarge">' + templates.errorFriendEmailInvalidText() + '</div>';
			HD.addClass(HD.get(HD.CSS_CLASSES.SEND_FRIEND+'-FriendEmail'), 'hdwcValidationError');
		}
		
		// Inject errors.
		if (errorText) {
			if (!errorsEl) {
				errorsEl = document.createElement('div');
				errorsEl.id = 'hdValidationErrors';
				var instructionsEl = HD.get('submissionInstructions');
				instructionsEl.parentNode.insertBefore(errorsEl, instructionsEl.nextSibling);
			}
			errorsEl.innerHTML = errorText;
		}
		// Submit the form.
		else {
			if (errorsEl) {
				errorsEl.parentNode.removeChild(errorsEl);
			}
			
			// Retrieve context parameters.
			this.config.submission.media = media.mediaId || '';
			var params = this.config.getParams(this.config.submission, media) || this.config.submission;
			var url = [
				params.url,
				'?_ID_=', encodeURIComponent(params.id || ''),
				'&YOURNAME=', encodeURIComponent(userName),
				'&YOUREMAIL=', encodeURIComponent(userEmail),
				'&FRIENDNAME=', encodeURIComponent(friendName),
				'&FRIENDEMAIL=', encodeURIComponent(friendEmail),
				'&communityID=', encodeURIComponent(params.community || ''),
				'&mediaID=', encodeURIComponent(params.media || ''),
				'&viewID=', encodeURIComponent(params.view || '')
			];
			for (var prop in params) {
				if (!prop.match(/^(id|community|media|view|url)$/)) {
					url.push('&', prop, '=', encodeURIComponent(params[prop]));
				}
			}
			
			// Send the request to the friend.
			HD.util.Analytics.track(this.analyticsSendFriendConfirmationString(media));
			HD.util.Common.requestContent(comSvcBaseUrl + '/hd/hd_send_friend/assets/sendToFriend.jsp?siteName=' + comSiteName + '&recip='+encodeURIComponent(friendEmail)+'&url='+escape(url.join('')), function(responseText) {
				var overlayEl = HD.util.Common.showOverlay(responseText, HD.SendFriendWidget.templates.getSendFriendLabel().toUpperCase(), self.config.overlayWidth, self.config.overlayHeight);
	
				// Change button behavior if sendAnother is enabled
				if(self.config.sendAnother){
					
					var closeEls = HD.getByClass("hdClose", "*", overlayEl);
					if(closeEls.length > 0) {
						closeEls[0].onclick = function() {
							
							self.openForm(media);
						};
					}
					
				}
			});
		}
	},
	
    /**
	 * Analytics event for when the STAF overlay is opened.
	 * @param {object} [data]
	 *                 Media data
	 * @returns {string} Analytics string
	 */
	analyticsSendFriendString : function(data) {
		return "default_analyticsSendFriendString";
	},
	
    /**
	 * Analytics event for when the STAF is completed.
	 * @param {object} [data]
	 *                 Media data
	 * @returns {string} Analytics string
	 */
	analyticsSendFriendConfirmationString : function(data) {
		return "default_analyticsSendFriendConfirmationString";
	}
};

HD.extend(HD.SendFriendWidget, [HD.Widget]);

HD.register("hd_send_friend_widget", 'HD.SendFriendWidget', {version: "1.0", build: "1"});
