//------------------------------------------------------------------------------
// <copyright company="Telligent Systems">
//     Copyright (c) Telligent Systems Corporation.  All rights reserved.
// </copyright> 
//------------------------------------------------------------------------------

using System;
using System.Collections;
using System.Collections.Specialized;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.ComponentModel;
using System.IO;

using CommunityServer;
using CommunityServer.Components;
using PasswordRecovery = CommunityServer.Components.PasswordRecovery;


namespace CommunityServer.Controls {

    /// <summary>
    /// This Web control displays the textboxes needed to create a new user account.
    /// The user can enter their username and email, and a warning message is displayed if
    /// either the username or email message is already taken.  Once the user enters an available
    /// username and password, they will be sent a confirmation email with their password.
    /// </summary>
    [
    ParseChildren(true)
    ]
    public class ForgottenPassword : CommunityServer.Controls.TemplatedWebControl {

        #region Member variables and contructor


        TextBox emailAddress;
        IButton sendPasswordButton;
        RequiredFieldValidator emailValidator;
        RegularExpressionValidator emailRegexValidator;
        ValidationSummary validationMsg;
        IButton nextButton;
        IText sQuestion;
        TextBox sAnswer;

        RequiredFieldValidator sAnswerValidator;
        RegularExpressionValidator sAnswerRegexValidator;

        CommunityServer.Components.PasswordRecovery recoveryMethod;

        // *********************************************************************
        //  CreateUser
        //
        /// <summary>
        /// Constructor
        /// </summary>
        // ***********************************************************************/
        public ForgottenPassword() : base() {

            
            recoveryMethod = CSContext.Current.SiteSettings.PasswordRecovery;
        }
        #endregion

        protected void ToggleEmail(bool show)
        {
            FindControl("Email_Row").Visible = show;
        }

        protected void ToggleQA(bool show)
        {
            FindControl("Question_Row").Visible = show;
            FindControl("Answer_Row").Visible = show;
            
        }

        #region Initialize skin
        // *********************************************************************
        //  Initializeskin
        //
        /// <summary>
        /// Initialize the control template and populate the control with values
        /// </summary>
        // ***********************************************************************/
        protected override void AttachChildControls() {


            // Text box for email address
            emailAddress = (TextBox) FindControl("EmailAddress");

            // Button to submit
            sendPasswordButton = FindButton("SendPassword");
            sendPasswordButton.Text = ResourceManager.GetString("ForgottenPassword_SendButton");
            sendPasswordButton.Click += new EventHandler (SendPassword_Click);

            // Validators
            emailValidator = (RequiredFieldValidator) FindControl("EmailValidator");
            emailValidator.ErrorMessage = ResourceManager.GetString("ForgottenPassword_RequiredField");
            emailRegexValidator = (RegularExpressionValidator) FindControl("EmailRegexValidator");
            emailRegexValidator.ErrorMessage = ResourceManager.GetString("ForgottenPassword_InvalidEmailAddress");          
            validationMsg = (ValidationSummary) FindControl("ValidationMsg");
            
            // Next Button
            nextButton = FindButton("Next");
            nextButton.Text = ResourceManager.GetString("ForgottenPassword_NextButton");
            nextButton.Click += new EventHandler (Next_Click);
            
            sQuestion = FindText("SQuestion");

            sAnswer = (TextBox) FindControl("SAnswer");

            sAnswerValidator = (RequiredFieldValidator) FindControl("SAnswerValidator");
            sAnswerValidator.ErrorMessage = ResourceManager.GetString("ForgottenPassword_SecretAnswerRequired");          

            sAnswerRegexValidator = (RegularExpressionValidator) FindControl("SAnswerRegexValidator");
            sAnswerRegexValidator.ErrorMessage = ResourceManager.GetString("ForgottenPassword_InvalidSecretAnswer");          

            // Reset common validators
            emailValidator.IsValid = true;
            emailRegexValidator.IsValid = true;

            ToggleEmail(true);
            ToggleQA(false);

            if (recoveryMethod == CommunityServer.Components.PasswordRecovery.Reset || recoveryMethod == CommunityServer.Components.PasswordRecovery.SecureLink) {
                // Reset

                nextButton.Visible = false;
                sendPasswordButton.Visible = true;
            }
            else {
                nextButton.Visible = true;
                sendPasswordButton.Visible = false;
                
                // Reset few more validators
                sAnswerValidator.IsValid = true;
                sAnswerRegexValidator.IsValid = true;
            }
        }
        #endregion

        #region Events
        void Next_Click(Object sender, EventArgs e) {
            
            User user = ValidateUserOnStep(this.Step);

            // If null there was a validation error
            //
		    if (user == null)
		    {
		        ResultMessage(false);
		        return;
		    }



            // If PasswordQuestion is not set, then stop here 
            // and Reset user's password.
            //
            if (Globals.IsNullorEmpty(user.PasswordQuestion))
            {
               // Update user's password in datastore & display operation's status
                ResultMessage(user.ResetPassword());
                return;
            }

            // Go on to next step
            //
            this.Step = 2;   
            sQuestion.Text = user.PasswordQuestion;
 
            ToggleEmail(false);
            ToggleQA(true);   
   
            nextButton.Visible = false;
            sendPasswordButton.Visible = true;
        }

		void SendPassword_Click(Object sender, EventArgs e) {

			User user = null;

			// Validate on current step
			user = ValidateUserOnStep(this.Step);

			// If null there was a validation error
			if(user == null)
				return;

			// Don't do anything if it's the anonymous user
			if (user.IsAnonymous)
				ResultMessage(false);
			else if (recoveryMethod == PasswordRecovery.Reset)
				ResultMessage(user.ResetPassword());
			else if(recoveryMethod == PasswordRecovery.SecureLink)
				ResultMessage(user.SendChangePasswordUID());
			else
				ResultMessage(user.ResetPassword(sAnswer.Text));
		}
        #endregion
        
        #region Helper Methods & Properties
        public int Step {
            get {
				Object state = ViewState["RecoveryStep"];
                if (state != null)
                    return (int)state;
                else
                    return 1;
            }
            set {
                ViewState["RecoveryStep"] = value;
            }
        }

        private void ResultMessage(bool result)
		{
			IText title = FindText("MessageTitle");
			IText body = FindText("MessageBody");

			CommunityServer.Components.Message message;
			if (recoveryMethod == PasswordRecovery.Reset)
				message = ResourceManager.GetMessage(CSExceptionType.UserPasswordResetSuccess);
			else
				message = ResourceManager.GetMessage(CSExceptionType.UserPasswordLinkSentSuccess);
			
			title.Text = message.Title;
			body.Text = string.Format(message.Body, emailAddress.Text.Trim());

		}

        private User ValidateUserOnStep(int step) {
            
            // No mather what recovery method we use.
            // We check step no. instead.
            //
            User user = null;

            if (step == 1 || step == 2) {
                // Validate step 1 and 2
                //
                
                // Fire Validators
                emailValidator.Validate();
                emailRegexValidator.Validate();

                if (!emailValidator.IsValid || !emailRegexValidator.IsValid)
                    return null;

                // Look up the user
                user = Users.FindUserByEmail(emailAddress.Text);
            }

            if (step == 2) {
                // Validate step 2 only
                //
                
                // Fire Validators
                sAnswerValidator.Validate();
                sAnswerRegexValidator.Validate();

                if (!sAnswerValidator.IsValid || !sAnswerRegexValidator.IsValid)
                    return null;

            }

            return user;
        }
        #endregion

        /// <summary>
        /// Override this method to attach templated or external skin controls to local references.
        /// </summary>
        /// <remarks>
        /// This will only be called if the non-default skin is used.
        /// </remarks>
        
    }
}
