using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Configuration.Provider;
using System.Data;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;

using Bitrix;
using Bitrix.Modules;
using Bitrix.Security;
using Bitrix.Services;
using Bitrix.UI;
using Bitrix.DataLayer;
using Bitrix.Services.Text;
using Bitrix.IO;
using Bitrix.Services.User;
using Bitrix.Configuration;
using Bitrix.Services.Image;
using System.IO;
//using Bitrix.Main;

public partial class bitrix_admin_AuthUsersEdit : BXAdminPage
{
	int userId = -1;
	protected BXUser user;
	bool currentUserCanModifyUser = false;
	bool currentUserCanCreateUser = false;
	bool currentUserCanModifySelfUser = false;
	bool currentUserCanDeleteUser = false;
	bool missingProvider = false;
	List<BXUserProfileAdminFacade> profileEditors;


	private Control WalkThrowControlsSearch(Control cntrl, string name)
	{
		foreach (Control subCntrl in cntrl.Controls)
		{
			if (!String.IsNullOrEmpty(subCntrl.ID) && subCntrl.ID.Equals(name, StringComparison.InvariantCultureIgnoreCase))
				return subCntrl;

			Control cntrl1 = WalkThrowControlsSearch(subCntrl, name);
			if (cntrl1 != null)
				return cntrl1;
		}

		return null;
	}

	private void LoadData()
	{
		ddlSite.Items.Clear();

		BXSiteCollection siteColl = BXSite.GetList(null, null, null, null, BXTextEncoder.EmptyTextEncoder);
		foreach (BXSite site in siteColl)
			ddlSite.Items.Add(new ListItem("[" + site.Id + "] " + site.Name, site.Id));

		if (user == null)
		{
			ddProviderName.Visible = true;
			lbProviderName.Visible = false;
			rfvProviderName.Visible = true;
			rfvProviderName.Enabled = true;
			tbUserName.Visible = true;
			lbUserName.Visible = false;
			rfvUserName.Enabled = true;

			rfvNewPassword.Enabled = true;
			rfvNewPassword.Visible = true;
			rfvNewPasswordConf.Enabled = true;
			rfvNewPasswordConf.Visible = true;

			cvPassword.Enabled = false;

			trLastActivityDate.Visible = false;
			trLastLoginDate.Visible = false;
			trCreationDate.Visible = false;
			trLastLockoutDate.Visible = false;
			trIsLockedOut.Visible = false;
			trLastPasswordChangedDate.Visible = false;
			trPassword.Visible = false;

			cbIsApproved.Checked = true;

			ddProviderName.Attributes["onchange"] = "CheckQuestionAndAnswer(this)";
			foreach (ProviderBase pr in Membership.Providers)
				ddProviderName.Items.Add(new ListItem(("BXSqlMembershipProvider".Equals(pr.Name, StringComparison.InvariantCultureIgnoreCase) ? GetMessageRaw("String.InnerProvider") : pr.Name), pr.Name));
			ddProviderName.SelectedValue = BXUserManager.Provider.Name;

			trPasswordQuestion.Style["display"] = (BXUserManager.Provider.RequiresQuestionAndAnswer ? "block" : "none");
			trPasswordAnswer.Style["display"] = (BXUserManager.Provider.RequiresQuestionAndAnswer ? "block" : "none");
		}
		else
		{
			Page.Title = string.Format(GetMessage("PageTitle.ModificationOfUser"), userId);
			((BXAdminMasterPage)Page.Master).Title = Page.Title;

			ddProviderName.Visible = false;
			lbProviderName.Visible = true;
			rfvProviderName.Enabled = false;
			rfvProviderName.Visible = false;
			tbUserName.Visible = false;
			lbUserName.Visible = true;
			rfvUserName.Enabled = false;

			rfvNewPassword.Enabled = false;
			rfvNewPassword.Visible = false;
			rfvNewPasswordConf.Enabled = false;
			rfvNewPasswordConf.Visible = false;

			cvPassword.Enabled = true;

			trLastActivityDate.Visible = true;
			trLastLoginDate.Visible = true;
			trCreationDate.Visible = true;
			trIsLockedOut.Visible = true;
			trLastPasswordChangedDate.Visible = true;
			trPassword.Visible = true;

			tbEmail.Text = user.Email;
			lbProviderName.Text = HttpUtility.HtmlEncode(("BXSqlMembershipProvider".Equals(user.ProviderName, StringComparison.InvariantCultureIgnoreCase) ? GetMessageRaw("String.InnerProvider") : user.ProviderName));
			lbUserName.Text = HttpUtility.HtmlEncode(user.UserName);
			tbPasswordQuestion.Text = user.PasswordQuestion;
			tbAnswer.Text = "";

			lbCreationDate.Text = user.CreationDate.ToString();
			lbLastLoginDate.Text = user.LastLoginDate.ToString();
			lbLastActivityDate.Text = user.LastActivityDate.ToString();
			lbLastLockoutDate.Text = user.LastLockoutDate.ToString();
			lbLastPasswordChangedDate.Text = user.LastPasswordChangedDate.ToString();

			cbIsApproved.Checked = user.IsApproved;
			cbIsLockedOut.Checked = user.IsLockedOut;
			cbIsLockedOut.Enabled = user.IsLockedOut;
			hfIsLockedOut.Value = (user.IsLockedOut ? "Y" : "N");

			tbComment.Text = user.Comment;

			tbDisplayName.Text = user.DisplayName;
			tbFirstName.Text = user.FirstName;
			tbSecondName.Text = user.SecondName;
			tbLastName.Text = user.LastName;
			tbBirthdayDate.Text = user.BirthdayDate != DateTime.MinValue ? user.BirthdayDate.ToString("d") : String.Empty;
			ddlSite.SelectedValue = user.SiteId;
			aifImage.ImageFile = user.Image;
			ddlGender.SelectedValue = user.Gender.ToString();

			BXRoleWorkCollection roleWorksTmp = BXRoleManager.GetAllRolesForUser(user.UserId);
			foreach (BXRoleWork roleWorkTmp in roleWorksTmp)
			{
				Control cntrl = WalkThrowControlsSearch(Form, String.Format("tbCheck_{0}", roleWorkTmp.RoleName));
				(cntrl as CheckBox).Checked = true;

				cntrl = WalkThrowControlsSearch(Form, String.Format("tbCheck_{0}_old", roleWorkTmp.RoleName));
				(cntrl as HiddenField).Value = "Y";

				cntrl = WalkThrowControlsSearch(Form, String.Format("tbActiveFrom_{0}", roleWorkTmp.RoleName));
				(cntrl as TextBox).Text = roleWorkTmp.WorkActiveFrom;

				cntrl = WalkThrowControlsSearch(Form, String.Format("tbActiveFrom_{0}_old", roleWorkTmp.RoleName));
				(cntrl as HiddenField).Value = roleWorkTmp.WorkActiveFrom;

				cntrl = WalkThrowControlsSearch(Form, String.Format("tbActiveTo_{0}", roleWorkTmp.RoleName));
				(cntrl as TextBox).Text = roleWorkTmp.WorkActiveTo;

				cntrl = WalkThrowControlsSearch(Form, String.Format("tbActiveTo_{0}_old", roleWorkTmp.RoleName));
				(cntrl as HiddenField).Value = roleWorkTmp.WorkActiveTo;
			}

			trLastLockoutDate.Visible = cbIsLockedOut.Checked;

			if (!missingProvider)
			{
				trPasswordQuestion.Style["display"] = (Membership.Providers[user.ProviderName].RequiresQuestionAndAnswer ? "block" : "none");
				trPasswordAnswer.Style["display"] = (Membership.Providers[user.ProviderName].RequiresQuestionAndAnswer ? "block" : "none");
			}
			else
			{
				trPasswordQuestion.Style["display"] = "none";
				trPasswordAnswer.Style["display"] = "none";
				trPassword.Style["display"] = "none";
				trNewPassword.Style["display"] = "none";
				trNewPasswordConf.Style["display"] = "none";
			}
		}

		foreach (BXUserProfileAdminFacade p in profileEditors)
			p.Load(user);

		lbPasswordHint.Text = "<br/>" + string.Format(GetMessage("FormattedPasswordHintText"), BXUserManager.Provider.MinRequiredPasswordLength, BXUserManager.Provider.MinRequiredNonAlphanumericCharacters);
	}

	protected void Page_Init(object sender, EventArgs e)
	{
		userId = base.GetRequestInt("id");
		if (userId > 0)
			hfUserId.Value = userId.ToString();
		Int32.TryParse(hfUserId.Value, out userId);
		if (userId > 0)
		{
			user = Bitrix.Security.BXUser.GetById(userId, BXTextEncoder.EmptyTextEncoder);
			if (user == null)
			{
				userId = 0;
				hfUserId.Value = userId.ToString();
			}
		}

		if (userId > 0)
		{
			if (Membership.Providers[user.ProviderName] == null)
				missingProvider = true;
		}

		if (!this.BXUser.IsCanOperate(BXRoleOperation.Operations.UserView))
			BXAuthentication.AuthenticationRequired();

		currentUserCanCreateUser = this.BXUser.IsCanOperate(BXRoleOperation.Operations.UserCreate);
		currentUserCanModifyUser = this.BXUser.IsCanOperate(BXRoleOperation.Operations.UserModify);
		currentUserCanModifySelfUser = (((this.BXUser.Identity as BXIdentity).Id == userId) && this.BXUser.IsCanOperate(BXRoleOperation.Operations.UserModifySelf));
		currentUserCanDeleteUser = this.BXUser.IsCanOperate(BXRoleOperation.Operations.UserDelete);

		IBXCustomFieldList fl = CustomFieldList1 as IBXCustomFieldList;
		fl.Load(BXCustomEntityManager.GetProperties(Bitrix.Security.BXUser.GetCustomFieldsKey(), userId));

		#region Load Profile Extensions
		profileEditors = new List<BXUserProfileAdminFacade>();
		int index = BXTabControl1.Tabs.IndexOf(NotesTab);
		foreach (BXUserProfileExtensionProvider provider in Bitrix.Security.BXUser.GetProfileExtensionProviders())
		{
			BXUserProfileAdminFacade facade = provider.CreateAdminFacade();
			if (facade == null)
				return;

			profileEditors.Add(facade);
		
			ExtensionTab.Visible = true;
			if (facade.EditorControl != null)
				ExtensionTab.Controls.Add(facade.EditorControl);
		
			facade.SetValidationGroup(BXTabControl1.ValidationGroup);
		}
		#endregion

		PrepareForInsertScript();
	}

	protected void Page_Load(object sender, EventArgs e)
	{
		((BXAdminMasterPage)Page.Master).Title = Page.Title;

		//if (missingProvider)
		//{
		//    BXTabControl1.ButtonsMode = BXTabControl.ButtonsModeType.Disabled;
		//    userValidationSummary.AddErrorMessage(String.Format(GetMessageRaw("Message.AuthorizationProviderNotFound"), user.ProviderName));
		//}

		if (userId > 0)
			BXRoleManager.SynchronizeProviderUserRoles(user.UserName, user.ProviderName);

		BXRoleCollection rolesTmp = BXRoleManager.GetList(
			new BXFormFilter(
				new BXFormFilterItem("Active", true, BXSqlFilterOperators.Equal)
			),
			new BXOrderBy_old("RoleName", "Asc")
		);

		foreach (BXRole roleTmp in rolesTmp)
		{
			HtmlTableRow r1 = new HtmlTableRow();
			r1.VAlign = "top";

			HtmlTableCell c1 = new HtmlTableCell();
			CheckBox cb = new CheckBox();
			cb.ID = String.Format("tbCheck_{0}", roleTmp.RoleName);
			cb.Checked = false;
			c1.Controls.Add(cb);
			HiddenField hf = new HiddenField();
			hf.ID = String.Format("tbCheck_{0}_old", roleTmp.RoleName);
			hf.Value = "N";
			c1.Controls.Add(hf);
			r1.Cells.Add(c1);

			c1 = new HtmlTableCell();
			c1.InnerHtml = String.Format("<a href=\"AuthRolesEdit.aspx?name={0}\">{1}</a>", Server.UrlEncode(roleTmp.RoleName), Server.HtmlEncode(roleTmp.Title));
			r1.Cells.Add(c1);

			c1 = new HtmlTableCell();
			c1.Align = "center";
			c1.Style["padding-right"] = "10px";
			c1.Style["padding-left"] = "10px";
			TextBox tb1 = new TextBox();
			tb1.ID = String.Format("tbActiveFrom_{0}", roleTmp.RoleName);
			c1.InnerHtml = "c&nbsp;";
			c1.Controls.Add(tb1);
			hf = new HiddenField();
			hf.ID = String.Format("tbActiveFrom_{0}_old", roleTmp.RoleName);
			hf.Value = "";
			c1.Controls.Add(hf);
			r1.Cells.Add(c1);

			c1 = new HtmlTableCell();
			c1.Align = "center";
			tb1 = new TextBox();
			tb1.ID = String.Format("tbActiveTo_{0}", roleTmp.RoleName);
			c1.InnerHtml = string.Format("{0}&nbsp;", GetMessage("TabCellInnerHtml.To"));
			c1.Controls.Add(tb1);
			hf = new HiddenField();
			hf.ID = String.Format("tbActiveTo_{0}_old", roleTmp.RoleName);
			hf.Value = "";
			c1.Controls.Add(hf);
			r1.Cells.Add(c1);

			tblRoles.Rows.Add(r1);
		}

		if (!Page.IsPostBack)
			LoadData();

		if (userId > 0)
		{
			if (!missingProvider)
			{
				trPasswordQuestion.Style["display"] = (Membership.Providers[user.ProviderName].RequiresQuestionAndAnswer ? "block" : "none");
				trPasswordAnswer.Style["display"] = (Membership.Providers[user.ProviderName].RequiresQuestionAndAnswer ? "block" : "none");
			}
			else
			{
				trPasswordQuestion.Style["display"] = "none";
				trPasswordAnswer.Style["display"] = "none";
				trPassword.Style["display"] = "none";
				trNewPassword.Style["display"] = "none";
				trNewPasswordConf.Style["display"] = "none";
			}
		}
		else
		{
			if (!String.IsNullOrEmpty(ddProviderName.SelectedValue))
			{
				trPasswordQuestion.Style["display"] = (Membership.Providers[(ddProviderName.SelectedValue.Equals(GetMessageRaw("String.InnerProvider"), StringComparison.InvariantCultureIgnoreCase) ? "BXSqlMembershipProvider" : ddProviderName.SelectedValue)].RequiresQuestionAndAnswer ? "block" : "none");
				trPasswordAnswer.Style["display"] = (Membership.Providers[(ddProviderName.SelectedValue.Equals(GetMessageRaw("String.InnerProvider"), StringComparison.InvariantCultureIgnoreCase) ? "BXSqlMembershipProvider" : ddProviderName.SelectedValue)].RequiresQuestionAndAnswer ? "block" : "none");
			}
			else
			{
				trPasswordQuestion.Style["display"] = (Membership.Provider.RequiresQuestionAndAnswer ? "block" : "none");
				trPasswordAnswer.Style["display"] = (Membership.Provider.RequiresQuestionAndAnswer ? "block" : "none");
			}
		}
		DeleteUserSeparator.Visible = DeleteUserButton.Visible = userId > 0 && currentUserCanDeleteUser;
		AddUserSeparator.Visible = AddUserButton.Visible = userId > 0 && currentUserCanCreateUser;
		BXTabControl1.ShowSaveButton = BXTabControl1.ShowApplyButton = (userId <= 0 && currentUserCanCreateUser) || (userId > 0 && (currentUserCanModifyUser || currentUserCanModifySelfUser));
	}

	void PrepareForInsertScript()
	{
		if (!ClientScript.IsClientScriptBlockRegistered(GetType(), "InsertScript"))
		{
			StringBuilder sscript = new StringBuilder();
			sscript.AppendLine("var arMembershipProviders = {");
			bool fl = false;
			foreach (ProviderBase pr in Membership.Providers)
			{
				sscript.AppendLine(
					string.Format(
						"{0}\"{1}\":\"{2}\"",
						(fl ? ", " : ""),
						pr.Name,
						((pr as MembershipProvider).RequiresQuestionAndAnswer ? "Y" : "N")
					)
				);
				fl = true;
			}
			sscript.AppendLine("};");

			sscript.AppendLine("function CheckQuestionAndAnswer(sbox)");
			sscript.AppendLine("{");
			sscript.AppendLine("	if (sbox.selectedIndex < 0) return;");
			sscript.AppendLine(string.Format("	document.getElementById(\"{0}\").style[\"display\"] = ((arMembershipProviders[sbox[sbox.selectedIndex].value] == 'Y') ? \"block\" : \"none\");", trPasswordQuestion.ClientID));
			sscript.AppendLine(string.Format("	document.getElementById(\"{0}\").style[\"display\"] = ((arMembershipProviders[sbox[sbox.selectedIndex].value] == 'Y') ? \"block\" : \"none\");", trPasswordAnswer.ClientID));
			sscript.AppendLine("}");

			sscript.AppendLine("function CheckProviderName(oSrc, args)");
			sscript.AppendLine("{");
			sscript.AppendLine("	args.IsValid = (arMembershipProviders[args.Value] != null);");
			sscript.AppendLine("}");

			sscript.AppendLine("function CheckNewPasswordConf(oSrc, args)");
			sscript.AppendLine("{");
			sscript.AppendLine(
				string.Format(
					"	args.IsValid = ((document.{0}.{1}.value.length > 0) && (document.{0}.{2}.value.length > 0) || (document.{0}.{1}.value.length <= 0) && (document.{0}.{2}.value.length <= 0));",
					Form.ClientID,
					tbNewPassword.ClientID,
					tbNewPasswordConf.ClientID
				)
			);
			sscript.AppendLine("}");

			sscript.AppendLine("function CheckPassword(oSrc, args)");
			sscript.AppendLine("{");
			sscript.AppendLine(
				string.Format(
					"	args.IsValid = ((document.{0}.{1}.value.length <= 0) && (document.{0}.{2}.value.length <= 0) || (document.{0}.{3}.value.length > 0));",
					Form.ClientID,
					tbNewPassword.ClientID,
					tbAnswer.ClientID,
					tbPassword.ClientID
				)
			);
			sscript.AppendLine("}");

			ClientScript.RegisterClientScriptBlock(GetType(), "InsertScript", sscript.ToString(), true);
		}

		/*
		if (!ClientScript.IsStartupScriptRegistered(GetType(), "StartupScript"))
		{
			StringBuilder sscript1 = new StringBuilder();
			sscript1.AppendLine(String.Format("CheckQuestionAndAnswer(document.{0}.{1});", Form.ClientID, ddProviderName.ClientID));
			ClientScript.RegisterStartupScript(GetType(), "StartupScript", sscript1.ToString(), true);
		}
		*/

		ddProviderName.Attributes["onchange"] = "CheckQuestionAndAnswer(this)";
	}

	private string GetErrorMessage(MembershipCreateStatus status)
	{
		switch (status)
		{
			case MembershipCreateStatus.DuplicateUserName:
				return GetMessageRaw("Message.DuplicateUserName");

			case MembershipCreateStatus.DuplicateEmail:
				return GetMessageRaw("Message.DuplicateEmail");

			case MembershipCreateStatus.InvalidPassword:
				return string.Format(
					GetMessageRaw("Message.InsecurePassword"),
					string.Format(
						GetMessageRaw("FormattedPasswordHintText"),
						BXUserManager.Provider.MinRequiredPasswordLength,
						BXUserManager.Provider.MinRequiredNonAlphanumericCharacters
					)
				);
			case MembershipCreateStatus.InvalidEmail:
				return GetMessageRaw("Message.InvalidEmail");

			case MembershipCreateStatus.InvalidAnswer:
				return GetMessageRaw("Message.InvalidAnswer");

			case MembershipCreateStatus.InvalidQuestion:
				return GetMessageRaw("Message.InvalidQuestion");

			case MembershipCreateStatus.InvalidUserName:
				return GetMessageRaw("Message.InvalidUserName");

			case MembershipCreateStatus.ProviderError:
				return GetMessageRaw("Message.ProviderError");

			case MembershipCreateStatus.UserRejected:
				return GetMessageRaw("Message.UserRejected");

			default:
				return GetMessageRaw("Message.Default");
		}
	}

	private bool SaveUser()
	{
		if (!Page.IsValid)
			return false;

		if (!(userId > 0 ? UpdateUser() : CreateUser()))
			return false;
		try
		{
			foreach (BXUserProfileAdminFacade p in profileEditors)
				p.Save(user, null);
		}
		catch (BXEventException e)
		{
			foreach (string s in e.Messages)
				userValidationSummary.AddErrorMessage(s);
			return false;
		}
		catch (Exception e)
		{
			userValidationSummary.AddErrorMessage(Encode(e.Message));
			return false;
		}
		return true;
	}

	private bool CreateUser()
	{
		try
		{
			if (!currentUserCanCreateUser)
				throw new Exception(GetMessageRaw("ExceptionText.YouDontHaveRightsToCreateNewUser"));

			DateTime birthdayDate;
			DateTime.TryParse(tbBirthdayDate.Text, out birthdayDate);

			string providerNameTmp = ddProviderName.SelectedValue;

			user = new BXUser(BXTextEncoder.EmptyTextEncoder);
			user.UserName = tbUserName.Text;
			user.ProviderName = providerNameTmp;
			user.Password = tbNewPassword.Text;
			user.Email = tbEmail.Text;
			if (Membership.Providers[providerNameTmp].RequiresQuestionAndAnswer)
			{
				user.PasswordQuestion = tbPasswordQuestion.Text;
				user.PasswordAnswer = tbAnswer.Text;
			}
			user.IsApproved = cbIsApproved.Checked;
			user.DisplayName = tbDisplayName.Text;
			user.FirstName = tbFirstName.Text;
			user.SecondName = tbSecondName.Text;
			user.LastName = tbLastName.Text;
			user.SiteId = ddlSite.SelectedValue;
			user.BirthdayDate = birthdayDate;
			user.Comment = tbComment.Text;

			user.Gender =  Enum.IsDefined(typeof(BXUserGender), ddlGender.SelectedValue) ? (BXUserGender)Enum.Parse(typeof(BXUserGender), ddlGender.SelectedValue) : BXUserGender.Unknown;

			BXFile f = SaveFile();
			if (f != null)
				user.ImageId = f.Id;


			try
			{
				try
				{
					user.Create();
				}
				catch (MembershipCreateUserException ex)
				{
					throw new Exception(GetErrorMessage(ex.StatusCode), ex);
				}

			}
			catch
			{
				user = null;
				if (f != null)
					f.Delete();
				throw;
			}



			userId = user.UserId;
			hfUserId.Value = userId.ToString();

			string[] rolesTmp = BXRoleManager.GetAllRoles();
			foreach (string roleTmp in rolesTmp)
			{
				Control cntrl = WalkThrowControlsSearch(Form, String.Format("tbCheck_{0}", roleTmp));
				bool cb = (cntrl as CheckBox).Checked;

				cntrl = WalkThrowControlsSearch(Form, String.Format("tbCheck_{0}_old", roleTmp));
				bool cbOld = ((cntrl as HiddenField).Value == "Y");

				cntrl = WalkThrowControlsSearch(Form, String.Format("tbActiveFrom_{0}", roleTmp));
				string from = (cntrl as TextBox).Text;

				cntrl = WalkThrowControlsSearch(Form, String.Format("tbActiveFrom_{0}_old", roleTmp));
				string fromOld = (cntrl as HiddenField).Value;

				cntrl = WalkThrowControlsSearch(Form, String.Format("tbActiveTo_{0}", roleTmp));
				string to = (cntrl as TextBox).Text;

				cntrl = WalkThrowControlsSearch(Form, String.Format("tbActiveTo_{0}_old", roleTmp));
				string toOld = (cntrl as HiddenField).Value;

				if (cb && (!cbOld || !from.Equals(fromOld, StringComparison.InvariantCultureIgnoreCase) || !to.Equals(toOld, StringComparison.InvariantCultureIgnoreCase)))
				{
					if (cbOld)
						user.RemoveFromRole(roleTmp);
					user.AddToRole(roleTmp, from, to);
				}
				else
				{
					if (!cb && cbOld)
						user.RemoveFromRole(roleTmp);
				}
			}

			BXCustomEntityManager.SaveEntity(Bitrix.Security.BXUser.GetCustomFieldsKey(), user.UserId, CustomFieldList1.Save());

			return true;
		}
		catch (BXEventException e)
		{
			foreach (string s in e.Messages)
				userValidationSummary.AddErrorMessage(s/*, "vgInnerForm", "tbUserName"*/);
		}
		catch (Exception e)
		{
			userValidationSummary.AddErrorMessage(e.Message/*, "vgInnerForm", "tbUserName"*/);
		}

		return false;
	}

	private bool UpdateUser()
	{
		try
		{
			if (!currentUserCanModifyUser && !currentUserCanModifySelfUser)
				throw new Exception(GetMessageRaw("ExceptionText.YouDontHaveRightsToModifyUser"));

			user.Email = tbEmail.Text;
			user.Comment = tbComment.Text;
			user.IsApproved = cbIsApproved.Checked;
			user.DisplayName = tbDisplayName.Text;
			user.FirstName = tbFirstName.Text;
			user.SecondName = tbSecondName.Text;
			user.LastName = tbLastName.Text;
			user.SiteId = ddlSite.SelectedValue;

			DateTime birthdayDate;
			DateTime.TryParse(tbBirthdayDate.Text, out birthdayDate);
			user.BirthdayDate = birthdayDate;

			user.Gender = Enum.IsDefined(typeof(BXUserGender), ddlGender.SelectedValue) ? (BXUserGender)Enum.Parse(typeof(BXUserGender), ddlGender.SelectedValue) : BXUserGender.Unknown;

			if (aifImage.DeleteFile)
				user.ImageId = 0;
			BXFile f = SaveFile();
			if (f != null)
				user.ImageId = f.Id;

			try
			{
				user.Update();
			}
			catch
			{
				if (f != null)
					f.Delete();
				throw;
			}

			if (!String.IsNullOrEmpty(tbNewPassword.Text))
			{
				if (!user.ChangePassword(tbPassword.Text, tbNewPassword.Text))
					throw new ArgumentException(GetMessageRaw("ExceptionText.ChangeOfPasswordFailed"));
			}

			MembershipProvider provider = BXUserManager.GetProvider(user.ProviderName);
			if (provider != null)
			{
				if (provider.RequiresQuestionAndAnswer)
				{
					if (!String.IsNullOrEmpty(tbAnswer.Text))
					{
						bool res = user.ChangePasswordQuestionAndAnswer(
							(!String.IsNullOrEmpty(tbNewPassword.Text) ? tbNewPassword.Text : tbPassword.Text),
							tbPasswordQuestion.Text,
							tbAnswer.Text
						);
						if (!res)
							throw new ArgumentException(GetMessageRaw("ExceptionText.ChangeOfSecretQuestionAndAnswerFailed"));
					}
				}
			}

			if (hfIsLockedOut.Value == "Y" && !cbIsLockedOut.Checked)
				if (!user.UnlockUser())
					throw new ArgumentException(GetMessageRaw("ExceptionText.DeblockingOfUserFailed"));

			if (currentUserCanModifyUser)
			{
				string[] rolesTmp = BXRoleManager.GetAllRoles();
				foreach (string roleTmp in rolesTmp)
				{
					Control cntrl = WalkThrowControlsSearch(Form, String.Format("tbCheck_{0}", roleTmp));
					bool cb = (cntrl as CheckBox).Checked;

					cntrl = WalkThrowControlsSearch(Form, String.Format("tbCheck_{0}_old", roleTmp));
					bool cbOld = ((cntrl as HiddenField).Value == "Y");

					cntrl = WalkThrowControlsSearch(Form, String.Format("tbActiveFrom_{0}", roleTmp));
					string from = (cntrl as TextBox).Text;

					cntrl = WalkThrowControlsSearch(Form, String.Format("tbActiveFrom_{0}_old", roleTmp));
					string fromOld = (cntrl as HiddenField).Value;

					cntrl = WalkThrowControlsSearch(Form, String.Format("tbActiveTo_{0}", roleTmp));
					string to = (cntrl as TextBox).Text;

					cntrl = WalkThrowControlsSearch(Form, String.Format("tbActiveTo_{0}_old", roleTmp));
					string toOld = (cntrl as HiddenField).Value;

					if (cb && (!cbOld || !from.Equals(fromOld, StringComparison.InvariantCultureIgnoreCase) || !to.Equals(toOld, StringComparison.InvariantCultureIgnoreCase)))
					{
						if (cbOld)
							user.RemoveFromRole(roleTmp);
						user.AddToRole(roleTmp, from, to);
					}
					else
					{
						if (!cb && cbOld)
							user.RemoveFromRole(roleTmp);
					}
				}
			}

			BXCustomEntityManager.SaveEntity("user", user.UserId, CustomFieldList1.Save());

			return true;
		}
		catch (BXEventException e)
		{
			foreach (string s in e.Messages)
				userValidationSummary.AddErrorMessage(s/*, "vgInnerForm", "tbUserName"*/);
		}
		catch (Exception e)
		{
			userValidationSummary.AddErrorMessage(e.Message/*, "vgInnerForm", "tbUserName"*/);
		}
		return false;
	}

	protected BXFile SaveFile()
	{
		FileUpload fu = aifImage.Upload;

		if (!fu.HasFile)
			return null;

        HttpPostedFile postedFile = fu.PostedFile;
        BXFileValidationResult result = BXFile.ValidateAsImage(
            postedFile.FileName, 
            postedFile.ContentType, 
            postedFile.InputStream, 
            BXConfigurationUtility.Options.User.AvatarMaxSizeKB * 1024, 
            BXConfigurationUtility.Options.User.AvatarMaxWidth, 
            BXConfigurationUtility.Options.User.AvatarMaxHeight
            );

        if (result == BXFileValidationResult.Valid)
        {
            BXFile f = new BXFile(fu.PostedFile, "user", "main", null);
            BXSecureIO.DemandUpload(f.FileVirtualPath);
            f.Save();
            return f;
        }

        if ((result & BXFileValidationResult.InvalidContentType) == 0
            && (result & BXFileValidationResult.InvalidExtension) == 0
            && (result & BXFileValidationResult.InvalidImage) == 0
            && ((result & BXFileValidationResult.InvalidWidth) != 0 || (result & BXFileValidationResult.InvalidHeight) != 0)
            )
        {
            using (MemoryStream destinationStream = new MemoryStream())
            {
                BXImageUtility.Resize(postedFile.InputStream, destinationStream, BXConfigurationUtility.Options.User.AvatarMaxWidth, BXConfigurationUtility.Options.User.AvatarMaxHeight);
                BXFile f = new BXFile(null, destinationStream, postedFile.FileName, "user", "main", null, postedFile.ContentType);
                if ((result & BXFileValidationResult.InvalidSize) != 0 && f.FileSize <= BXConfigurationUtility.Options.User.AvatarMaxSizeKB * 1024)
                    result &= ~BXFileValidationResult.InvalidSize;
                if ((result & BXFileValidationResult.InvalidWidth) != 0 && f.Width <= BXConfigurationUtility.Options.User.AvatarMaxWidth)
                    result &= ~BXFileValidationResult.InvalidWidth;
                if ((result & BXFileValidationResult.InvalidHeight) != 0 && f.Height <= BXConfigurationUtility.Options.User.AvatarMaxHeight)
                    result &= ~BXFileValidationResult.InvalidHeight;

                if (result == BXFileValidationResult.Valid)
                {
                    BXSecureIO.DemandUpload(f.FileVirtualPath);
                    f.Save();
                    return f;
                }
            }
        }
        
		StringBuilder fError = new StringBuilder();
		if ((result & BXFileValidationResult.InvalidContentType) == BXFileValidationResult.InvalidContentType)
			fError.Append(GetMessageRaw("InvalidType"));
		
		if ((result & BXFileValidationResult.InvalidExtension) == BXFileValidationResult.InvalidExtension)
		{
			if (fError.Length != 0)
				fError.Append(", ");
			fError.Append(GetMessageRaw("InvalidExtension"));
		}
		
		if ((result & BXFileValidationResult.InvalidImage) == BXFileValidationResult.InvalidImage)
		{
			if (fError.Length != 0)
				fError.Append(", ");
			fError.Append(GetMessageRaw("InvalidImage"));
		}

		if ((result & BXFileValidationResult.InvalidSize) != 0)
		{
			if (fError.Length != 0)
				fError.Append(", ");
			fError.AppendFormat(GetMessageRaw("InvalidSize"), BXStringUtility.BytesToString(BXConfigurationUtility.Options.User.AvatarMaxSizeKB * 1024));
		}

		if ((result & BXFileValidationResult.InvalidWidth) != 0)
		{
			if (fError.Length != 0)
				fError.Append(", ");
			fError.AppendFormat(GetMessageRaw("InvalidWidth"), BXConfigurationUtility.Options.User.AvatarMaxWidth);
		}

		if ((result & BXFileValidationResult.InvalidHeight) != 0)
		{
			if (fError.Length != 0)
				fError.Append(", ");
			fError.AppendFormat(GetMessageRaw("InvalidHeight"), BXConfigurationUtility.Options.User.AvatarMaxHeight);
		}

		throw new Exception(string.Format(GetMessageRaw("Error.InvalidImage"), fError.ToString()));
	}

	protected void BXTabControl1_Command(object sender, Bitrix.UI.BXTabControlCommandEventArgs e)
	{
		bool successAction = true;
		if (e.CommandName == "save")
		{
			if (!SaveUser())
				successAction = false;

		}
		else if (e.CommandName == "apply")
		{
			if (!SaveUser())
				successAction = false;
			else
				Response.Redirect("AuthUsersEdit.aspx?id=" + user.UserId);
		}

		if (successAction)
			Page.Response.Redirect("AuthUsersList.aspx");
	}

	protected void cvProviderName_ServerValidate(object source, ServerValidateEventArgs args)
	{
		args.IsValid = (Membership.Providers[ddProviderName.SelectedValue] != null);
	}

	protected void cfNewPasswordConf_ServerValidate(object source, ServerValidateEventArgs args)
	{
		args.IsValid = (!String.IsNullOrEmpty(tbNewPassword.Text) && !String.IsNullOrEmpty(tbNewPasswordConf.Text)
			|| String.IsNullOrEmpty(tbNewPassword.Text) && String.IsNullOrEmpty(tbNewPasswordConf.Text));
	}

	protected void cvPassword_ServerValidate(object source, ServerValidateEventArgs args)
	{
		args.IsValid = (String.IsNullOrEmpty(tbNewPassword.Text)
			&& String.IsNullOrEmpty(tbAnswer.Text)
			|| !String.IsNullOrEmpty(tbPassword.Text));
	}

	protected void BXContextMenuToolbar1_CommandClick(object sender, CommandEventArgs e)
	{
		switch (e.CommandName.ToLower())
		{
			case "deleteuser":
				try
				{
					if (!this.BXUser.IsCanOperate(BXRoleOperation.Operations.UserDelete))
						throw new Exception(GetMessageRaw("ExceptionText.YouDontHaveRightsToDeleteUser"));

					if (user != null)
					{
						if (BXUserManager.Delete(userId))
						{
							if (!user.ProviderName.Equals(BXUserManager.Provider.Name, StringComparison.InvariantCultureIgnoreCase))
							{
								if (!Membership.Providers[user.ProviderName].DeleteUser(user.UserName, true))
									throw new Exception(GetMessageRaw("ExceptionText.DeletionOfUserFailed"));
							}
						}
						else
						{
							throw new Exception(GetMessageRaw("ExceptionText.DeletionOfUserFailed"));
						}
					}
					else
					{
						throw new Exception(GetMessageRaw("ExceptionText.UserIsNotFound"));
					}
					Response.Redirect("AuthUsersList.aspx");
				}
				catch (BXEventException ex)
				{
					foreach (string s in ex.Messages)
						userValidationSummary.AddErrorMessage(s);
				}
				catch (Exception ex)
				{
					userValidationSummary.AddErrorMessage(ex.Message);
				}

				break;

			default:
				break;
		}
	}
}
