(function() { 

	var mu = m2.util;

	/**
	 * @namespace
	 * 
	 */
	m2.widget.user.Registration = {
		
		/**
		 * @type m2.dialog   handle to the dialog
		 * @private
		 */
		_dialog : null,

		/**
		 * @type String   registration type
		 * @private
		 */		
        _type : null,
        
        /**
         * Omniture screen name
         */
        _screen : null,
        
		/**
		 * The state of the sign up dialog
		 * @type boolean
		 */
		isSignUpInit : false,
		
		/**
		 * This function is called from the https child frame to initialze the dialog
		 * @param {Object} data  The data object from the httpsChild.  Contains the dialog size.
		 * @scope httpParent
		 */
		initSignUpDialog : function(data) {
			// This check is necessary because the updateDialogContent method causes the iframe to reload, and 
			// thus this will be called mulitple times.
			if (this.isSignUpInit) {
				// The data always has the dimensions of the dialog so update the size.
				m2.dialog.update(data, "signupDialog");
				return;
			}
			var self = this;
			var  l = m2.$("iframeLoadingMessage");
			l.parentNode.removeChild(l);
			var f = m2.$("signupFrame");
			f.style.height = data.size.height + "px";
			// toggle display so the content positions properly
			f.style.position = "static";
			f.style.display = "block";
			f.style.frameborder = "0";
			f.style.scrolling = "NO";
			f.style.marginwidth = "0";
			f.style.allowTransparency = "true";
			m2.util.setStyle(f,"opacity",1);
			// animate the dialog to the correct size based on the data
			m2.dialog.update(data, "signupDialog");
			// set init state
			this.isSignUpInit = true;
			
		},

        initSignUpContents : function() {
            this.updateScreenName('MQ08MySignUp');
            m2.util.DWR.callService(RegistrationService.initCreateIdentity,m2.widget.user.Registration.handleInitSignUpContents);
        },
        
        handleInitSignUpContents : {
	        SUCCESS : function(r) {
        		if(m2.$("signUpForm")){
	                var form = m2.$("signUpForm");
	                // set initial captcha image
	                m2.widget.user.getCaptchaImage();
	
	                // set the security questions
	                var questions = r.data.questions;
	                var question;
	                var questionCount = questions.length;
	                var asqIdElem = form.asqId;
	                asqIdElem.options[questionCount - 1] = null;
	                for (var i = 0; i < questionCount; ++i) {
	                        question = questions[i];
	                        asqIdElem.options[i] = new Option(question.text, question.id);
	                }
	            }
        	}
        },
        
		/**
		 * Function will show the SignUp dialog
		 * @scope httpParent
		 */
		showSignUpDialog : function() {
            $a('MQ08MySignUp');
			this.isSignUpInit = false;
			// open the dialog
			this.dialog = m2.dialog.open({
				dialogName : "signupDialog",
				content : '<div style="text-align:center;font-weight:bold;" id="iframeLoadingMessage">' + m2.Label.Loading + '...</div>',
				modal : true,
				showCloseButton : false,
				size : {width:545,height:44},
				position : {y:130},
				closeOnBackgroundClick : false,
				allowOverflow : false
			});
	        
			// create the signup frame
			m2.util.Iframe.create({
				id    : "signupFrame",
				src   : m2.util.getSecureUrl() + "/signup#" + m2.util.toJson(m2.util.getBaseUrlForHash()),
				// NOTE: Position absolute is required or the page will jump around as the frame gets added to the 
				// end of the document
				style : {height:"1px",width:"525px",position:"absolute",scrolling:"no",overflow:"hidden"},
				node : this.dialog.contentEl
			});
		},
        
        /**
         * Function will submit the choose type form
         * @param {DomNode} form  the form dom node
         * @scope httpsChild
         */
        submitChooseType : function(form) {
            var data = m2.util.FormUtil.getValues(form);
            var type = data.type;
            this._type = type;
            
            if (type == 'o') {
                // ONS (email).
                $awsn('MQ08MyContinueOpenID', this._screen);
                this.updateScreenName('MQ08MyNewAcctOpenID');
                m2.$('screenNameField').style.display = "none";
                m2.$('alternateEmailField').style.display = "none";
            } else {
                // SNS (screen name).
                $awsn('MQ08MyContinueAOL', this._screen);
                this.updateScreenName('MQ08MyNewAcctAOL');
                m2.$('emailField').style.display = "none";
                m2.$('emailReTypeField').style.display = "none";
            }
            
            m2.$('chooseTypeScreen').style.display = "none";
            m2.$('signUpScreen').style.display = "block";
            
            m2.util.Iframe.sendDocumentDimensions();
        },
        
        /**
         * Function will submit the sign up form
         * @param {DomNode} form  the form dom node
         * @scope httpsChild
         */
        submitSignUp : function(form) {
            // show processing message in the parent
            m2.util.Iframe.sendMessage("loading", {message:"Processing..."});
            var self = this;
            m2.util.DWR.callService(RegistrationService.submitCreateIdentity,self.handleSubmitSignUp,m2.util.FormUtil.getValuesForDWR(form),m2.widget.user.Registration._type);
        },
        
        /**
         * Function will handle the response from submitSignUp
         * @param {Object} r  the response object
         * @scope httpsChild
         */
        handleSubmitSignUp : {
            // successful registration
            SUCCESS: function(r){
                $awsn('MQ08MySubmit', m2.widget.user.Registration._screen);
                // submit for login
                m2.util.Iframe.sendMessage("hideLoading");
                m2.widget.user.Registration.updateScreenName('MQ08MySuccess');
                m2.$('signUpScreen').style.display = "none";

                if (m2.widget.user.Registration._type == 'o') {
                    m2.User.data = null;
                    
                    m2.$('confirmEmail').innerHTML = r.data.user.loginId;
                    m2.$('confirmEmailScreen').style.display = "block";
                    m2.util.Iframe.sendDocumentDimensions();
                } else {
                    // Track user to login after confirmation is closed.
                    m2.User.data = r.data.user;
                    
                    m2.$('confirmScreenName').innerHTML = r.data.user.loginId;
                    m2.$('confirmScreenNameScreen').style.display = "block";
                    m2.util.Iframe.sendDocumentDimensions();
                }
            },

            // show the errors
            VALIDATION_ERROR : function(r) {
                $awsn('MQ08MyError', m2.widget.user.Registration._screen);
                // mark errors
                var errors = r.errors;
                m2.util.FormUtil.markErrors(errors, m2.$("signUpForm"), null, "error");
                
                // display a single error
                var message = m2.Label.registrationError;
                
                if (errors && (errors.length == 1)) {
                    var error = errors[0];
                    
                    // override generic message for "non standard" validation errors
                    if ((error.code == "registrationFailed") ||
                        (error.code == "screenNameUnavailable") ||
                        (error.code == "emailDomainInvalid")) {
                        message = error.message;
                    }
                } 
                
    			m2.$("messageArea").innerHTML = message;
    			m2.$("messageArea").className = "error";
                
                // for debugging specific errors
                if (r.errors) {
                    var text = "";
                    var errors = r.errors;
                    var errorCount = errors.length;
                    var error;
                    
                    for (var i = 0; i < errorCount; ++i) {
                        error = errors[i];
                        text += "field: ";
                        text += error.field;
                        text += ", code: ";
                        text += error.code;
                        text += "<br/>";
                    }
                    
                    if(m2.$("debugArea")) m2.$("debugArea").innerHTML = text;
                }

                // refresh the captcha word if incorrect
                for (var i = 0;i < r.errors.length;i++) {
                    if (r.errors[i].code == "captchaWordMismatch") {
                        m2.widget.user.getCaptchaImage();
                        m2.$("captchaWord").value = "";
                    }
                }
                // update the parent to the appropriate view
                m2.util.Iframe.sendMessage("hideLoading");
                m2.util.Iframe.sendDocumentDimensions();
            },

            // some sort of failure
            FAILURE : function(r) {
                // update the parent to the appropriate view
				m2.$('signUpScreen').style.display = "none";
				m2.$('errorScreen').style.display = "block";
                m2.util.Iframe.sendMessage("hideLoading");
                m2.util.Iframe.sendDocumentDimensions();
            }
        },  
             
        /**
         * Submits the confirmation action.
         */        
        submitConfirmation : function() {
            var data = m2.User.data;
            
            if (data) {
                // Login will refresh page so no ad refresh for the action.
                $awsn('MQ08MyClose', this._screen);
                m2.widget.user.showWelcomePage = true; 
                m2.widget.user.Login.doLogin({loginId:data.loginId,password:data.password});
            } else {
                var data = { actionName : 'MQ08MyClose', screenName : this._screen, type : this._type, isCancel : false };
                m2.util.Iframe.sendMessage("closeSignUpDialog", data);
            }
        },
              
        /**
         * Cancels sign up.
         */        
        cancelSignUp : function(actionName) {
            if (this._screen == 'MQ08MySuccess') {
                // Dialog close button clicked from confirmation screen.  Perform same action as if
                // the normal close button was clicked.
                this.submitConfirmation();
            } else {
                var data = { actionName : actionName, screenName : this._screen, type : this._type, isCancel : true };
                m2.util.Iframe.sendMessage("closeSignUpDialog", data);
            }
        },
        
        /**
         * Shows the login dialog.
         */
        showLoginDialog : function() {
            var data = { actionName : 'MQ08MySignIn', screenName : this._screen, type : this._type, isCancel : true };
            m2.util.Iframe.sendMessage("showLoginDialog", data);
        },
        
        /**
         * Closes the sign up dialog.
         * 
         * @param {Object} data
         */
        closeSignUpDialog : function(data) {
            // Check if anything to close.
            if (!m2.dialog.hasDialog("signupDialog")) {
                return;
            } 
            
            // Log action.
            $awsn(data.actionName, data.screenName, 'r');
            
            // Close the dialog.
            m2.dialog.close("signupDialog");
            
			// for IE.  the current document loses focus due to the iframe being destroyed.  focus on the first "a" tag of the
			// page to restore the focus.
			//
			// TODO: This should be moved to the dialog.js file to prevent general occurances of iframe dialog's closing
			//       but has not due to one issue.  ex.  If the page is scrolled and we focus on the first "a" tag
			//       as in this solution, the page will jump to the top.  So .. there needs to be a better way to determine 
			//       what element to focus on after an iframe dialog closes.  
			if (m2.isIE) {
				try{
					document.body.getElementsByTagName("input")[0].focus();
				}catch(err){}
			}
            
            // Clean up if cancel.
            if (data.isCancel) {
                // Running in the parent (possiby non-dotcom) window so execute cancel in the context of a hidden
                // child (always dotcom) frame.
				m2.util.Iframe.create({
					id:"signupCancelFrame",
					src: m2.util.getSecureUrl() + "/signup?type=" + data.type + "&action=c",
					hidden: true
				});
            }
        },
        
        /**
         * Function will handle the processing of cleaning up the data from a successful cancel
         */
        cancelSuccess : function(type) {
            try {
            	m2.util.DWR.callService(RegistrationService.cancelCreateIdentity,m2.widget.user.Registration.handleCancelSuccess,type);
            } catch (e) {
            	// For some reason RegistrationService is not defined sometimes.  In any case, a failure here should not be visible
            	// to the user
            	// TODO: It seems that sometimes the iframe remoting has a race condition where this gets invoked but does not
            	// have access to RegistrationService.  In order to see it, uncomment the throw below and run at high speed in Selenium
            	// under Firefox 3.
            	//throw e;
            }
        },

        /**
         * function handles the service callback for cancelling registration.
         * @scope httpParent
         */
        handleCancelSuccess : {
            SUCCESS: function(){
                // do nothin
            },
            FAILURE : function() {
                // do nothin
            }
        },

        /**
         * Updates the screen name in both the current and parent contexts.
         * 
         * @param {String} screenName screen name
         */        
        updateScreenName : function(screenName) {
            this._screen = screenName;
        },
        
        /**
         * Gets the Omniture screen name.
         */
        getScreenName : function() {
            return this._screen;
        }
        
	};

})();
