/**
 * @fileOverview
 * Account Management namespace. This file additionally contains the message
 * and validation namespaces.
 *
 * @namespace AccountManagement
 * @author Jon Ferrer <jon.ferrer@mlb.com>
 *
 * @requires jQuery.js
 * @requires bam.js
 * @requires bam.popModule.js
 */
window.AM = window.AccountManagement = (function(){
	var 
    
    _params = {
		"loginFlowUrl": '/enterworkflow.do?flowId=registration.ajax.wizard&c_id=mlb'
	},

    /** @exports _self as AccountManagement */
	_self = {
		/** 
         * Triggers helpful debugging behavior, like logging to window.console,
         * when set to TRUE
         *
         * @public
         * @property
         */
		"debugMode" : false,

		/** 
         * Facade for window.console.log() that only outputs logging when
         * AccountManagement.debugMode === TRUE
         *
         * @public
         */
		"log" : function(out){
			if (!!_self.debugMode && typeof console!=='undefined'){ console.log(out); }
		},

        /**
         * Adds configuration parameters to AccountManagement namespace
         * 
         * @param {object} p Parameter object to add
         */
		"setupParams" : function(p){
			$.extend(_params,p);
		},
	
		/**
		 * Message module for Account Management. 
		 *
		 * Uses bam.popModule for 'success' messages, otherwise displays 
		 * messaging in DOM elements on the page.
         *
         * @namespace AccountManagement.message
		 */
		"message" : (function(){

			// load pop module for popup messages
			/*bam.loadSync('/shared/scripts/bam/bam.popModule.js');
			bam.popModule.init({
				css : '/style/account_management/bam.popModule.css'	
			});*/

            /** @exports _module as AccountManagement.message */
			var _module = {
				/**
				 * Resets HTML message in a message DOM element
				 *
				 * @param {String} _container  jQuery selector for message container
				 */
				"reset" : function(_container) {
					var _msgContainer = $(_container);
					_msgContainer.html('').removeClass().addClass('msg').hide();
				},

				/**
				 * Displays HTML message in a message DOM element
				 *
				 * @param {String} _html       html to display
				 * @param {String} _container  jquery selector for message container
				 * @param {String} _class      optional class to add to message container
				 */
				"display" : function(_html, _container, _class) {
                    var _msgContainer;

					if (_class=='success'||_class=='flash'){

                        // lazy-load and initialize bam.popModule, if necessary
                        if( ! bam.popModule) {
                            bam.loadSync(bam.homePath + "bam.popModule.js");
                            bam.popModule.init({
                                "css" : "/style/account_management/bam.popModule.css"	
                            });
                        }

						bam.popModule.setWidth(400);
						bam.popModule.show({
							htmlContent : _html
						});
						bam.popModule.exitAfterPause( '3000', { forceOverlayHide: true } );
					}
					else {
						_msgContainer = $(_container);
						_msgContainer.html(_html).removeClass().addClass('msg '+_class).show('slow');
					}
				}
			};
			return _module;
		})(),
		
		/** 
		 * Validation module for Account Managment.
		 *
		 * Contains methods for handling client-side (ie: form validation) and server-side (ie: action messaging) errors
		 *
		 * @namespace AccountManagement.validation  
		 */
		"validation" : (function(){
			bam.loadSync(bam.homePath + "bam.forms.js");

            /** @exports _module as AccountManagement.validation */
			var _module = {

				/**
				 * Displays length of form field characters vs max character length.
				 *
				 * Requires a matching DOM element with id="[fieldId]Count" for displaying
				 * the count.
				 *
				 * @param {fieldId} id of form field to count
				 * @param {max}     max number of characters
				 */
				"bindCharLimitCount" : function (fieldId,max) {
					function _countChars(fieldId) {
						var clen    = parseInt($('#'+fieldId).val().length, 10),
						    elCount = $('#'+fieldId+'Count');
						
						elCount.html("Characters Used: " + clen + "/"+ max);
						if (clen>max)
							elCount.addClass('error');
						else 
							elCount.removeClass('error');
						
					}
					// init char count
					_countChars(fieldId);

					// bind char count to field change/keypress
					$('#'+fieldId).keyup(
						function(){ _countChars(fieldId); }
					).change(
						function(){ _countChars(fieldId); }
					);
				},

				/** 
				 * Handles form validation errors
				 *
				 * @param {Object} propsParams               JSON object of parameters for the function
				 * @param {Object} propsParam.e              error object passed from bam.forms module
				 * @param {String} propsParam.formContainer  jQuery selector for the DOM element containing the invalid form 
				 * @param {String} propsParam.msgContainer   jQuery selector for DOM element that displays messaging. msgContainer is a child of formContainer.
				 * @param {String} propsParam.labelTags      jQuery selector for DOM elements containing the invalid labels/fields
				 * @param {String} propsParam.scrollTo       page scrolls to this portion of the page to ensure that the messaging is visible. (top|msgContainer)
				 */
				"handleFormValidationErrors" : function(propsParams){
					var params = {
						e             : null,
						formContainer : 'form',
						msgContainer  : '.msg',
						labelTags     : 'label',
						scrollTo      : 'top'
					};
					$.extend(params, propsParams);
					var _cMsg = params.formContainer+" "+params.msgContainer;
					var _scrollTarget = (params.scrollTo=='msgContainer') ? $(_cMsg).offset().top : 0;
					var _html = ['<ul>'];
					
					// reset errors
					_self.message.reset(_cMsg);
					$(params.formContainer+" .error").removeClass("error");

					// create error html
					for(var i=0;i<params.e.length;i++) {
						_html.push("<li>" + params.e[i].message + "</li>");
						$(params.e[i].element)
							.parents(params.labelTags)
							.addClass("error");
					}
					_html.push("</ul>");

					_self.message.display(_html.join(""),_cMsg,'error');
					
					$('html,body').animate({scrollTop: _scrollTarget }, 1000);

					return false;
				},

				/**
				 * Handles registration services response errors.
				 *
				 * Uses bam.actionMessages to resolve error codes/messages from the server and AccountManagement.messages
				 * to alert the user.
				 *
				 * @param {String} source    Service action that sent the error
				 * @param {Object} msg       Message object from bam.actionMessages
				 * @param {String} container jQuery selector for DOM element that displays message
				 */
				"handleServerErrors" : function(propsParams) {
					var params = {
						source        : null,
						msg           : null,
						formContainer : 'form',
						msgContainer  : '.msg',
						labelTags     : 'label',
						scrollTo      : 'top'
					},
                    
                    _err,
                    _html;

					$.extend(params, propsParams);

                    _self.log(params);

					////
					// if user is not logged in, redirect to login flow
					//
					if ((params.msg.code=='-1000'||params.msg.code=='-1100'||params.msg.code=='-1400'||params.msg.code=='-51000') && params.source!=='Password.update'){
						window.location = _params.loginFlowUrl;
						return;
					}

					_err  = _self.validation.Errors.GetMessage(params.msg);
					_html = [];

                    _self.log(_err);
					
					if (_err!==null){
						_html.push("<ul>");
						
						_html.push((_err.toString()!='undefined') ? "<li>"+ _err.toString() : "<li>");

						var _detailsLen = _err.details.length;
						if(_detailsLen>0){
							var _id, _d, _i=0;

							_html.push('<ul>');

							while (_i<_detailsLen) {
								_d  = _err.details[_i];
								_id = _d.key;
								_id = _id.replace('.','_');
								$(params.formContainer+' #'+_id).parents(params.labelTags).addClass('error');	

								if (_detailsLen>1) { _html.push('<li>'+_d.message+'</li>'); }

								_i++;
							}

							_html.push('</ul>');
						}
						_html.push('</li>');
						_html.push('</ul>');

						_self.message.display(_html.join(""),params.formContainer+" "+params.msgContainer,'error');
					}
				},

				// Alias for bam.actionMessages
				"Errors" : bam.actionMessages,

				/**
				 * Tests validity of char length of a form field value.
				 *
				 * Field should have a "max" attribute that stores the max number to validate against. Field 
				 * can have optional "min" attribute as well.
				 */ 
				"isInvalidLength" : new bam.forms.Check("isInvalidLength"),

				/**
				 * Tests if a form field value contains only alpha characters and common punctuation
				 */
				"isAlphaCommonPunctuation" : new bam.forms.Check("isAlphaCommonPunctuation"),

				/**
				 * Tests if a form field value contains only alpha characters and extended punctuation
				 */
				"isAlphaExtendedCommonPunctuation" : new bam.forms.Check("isAlphaExtendedCommonPunctuation")	

			};

			// load Action Messages
			_module.Errors.DefaultCategory = 'registration';
			_module.Errors.LoadMessages(
					"/shared/actionMessages/getjson.jsp?xml=/shared/actionMessages/xml/registration.xml"
			);

			//load client-side validation checks
			_module.isInvalidLength.check = function(fel) {
				var 

                len = parseInt(fel.value.length, 10) + 1,
                min = fel.getAttribute("min") ? parseInt(fel.getAttribute("min"), 10) : 0,
                max = fel.getAttribute("max") ? parseInt(fel.getAttribute("max"), 10) : parseInt(len, 10);

				this.message = (min===0) ? "@field must be less than " + max + " characters long" : "@field must be between " + min + " and " + max + " characters long";
				return (len < min || len > max);
			};

			_module.isAlphaCommonPunctuation.check = function(fel){
				var val = fel.value;
				this.message = "@field should contain alphabetic characters or common punctuation";
				return !(/^[A-Za-z \.,\-\'&]*$/.test(val));

			};

			_module.isAlphaExtendedCommonPunctuation.check = function(fel){
				var val = fel.value;
				this.message = "@field should contain alphabetic characters or common punctuation";
				return !(/^[A-Za-z 0-9.\-:;\,\+=\_\!\@#\$%\^&\*\(\)\'\"\n]*$/.test(val));
			};

			return _module;
		})()
	
	};

	return _self;
})();


