using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using Orciid.PageTemplate;
using Orciid.UserControls;
using Orciid.Core;
using System.Web.Mail;

namespace Orciid
{

	public class UserAccountsControl : OrciidUserControl
	{
		protected System.Web.UI.WebControls.LinkButton btnAddNew;
		protected System.Web.UI.WebControls.DataGrid usergrid;

		private const int login_column = 0;
		private const int name_column = 1;
		private const int email_column = 2;
		private const int admin_column = 3;
		private const int edit_column = 4;
		private const int delete_column = 5;
		private const int resetpw_column = 6;
		protected System.Web.UI.WebControls.Repeater FirstLetterRepeater;

		private int resetpasswordindex = -1;
		private int[] ids;
		private bool newuser;

		private Orciid.Core.User[] currentusers = null;

		protected override void LoadViewState(object savedState) 
		{
			if (savedState != null)
			{
				base.LoadViewState(savedState);
				if (ViewState["ids"] is Int32[])
					ids = (int[])ViewState["ids"];
				if (ViewState["newuser"] is bool)
					newuser = (bool)ViewState["newuser"];
			}
		}

		protected override object SaveViewState()
		{
			ViewState["ids"] = ids;
			ViewState["newuser"] = newuser;
			return base.SaveViewState();
		}

		private DataGridItem GetDataGridItem(Control control)
		{
			while (!(control is DataGridItem) && control.Parent != null)
				control = control.Parent;
			return control as DataGridItem;
		}

		private string GeneratePassword()
		{
			const string characters = "BCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz23456789-!$@%&*";
			const int pwdlength = 8;
			string result = "";
			Random r = new Random();
			for (int i = 0; i < pwdlength; i++)
				result += characters.Substring(r.Next(characters.Length), 1);
			return result;
		}

		private void QueryUserPatterns(bool queryusers)
		{
			string[] patterns = Orciid.Core.User.GetLoginPatterns(1);
			FirstLetterRepeater.DataSource = patterns;
			FirstLetterRepeater.DataBind();
			if (queryusers && patterns != null && patterns.Length > 0)
				QueryUsers(patterns[0]);
		}

		private void QueryUsers(string filter)
		{
			Orciid.Core.User[] users = Orciid.Core.User.GetByLoginPattern(filter);
			ids = new int[users.Length];
			for (int i = 0; i < users.Length; i++)
				ids[i] = users[i].ID;
			currentusers = new Orciid.Core.User[Math.Min(usergrid.PageSize, users.Length)];
			for (int i = 0; i < currentusers.Length; i++)
				currentusers[i] = users[i];
			usergrid.CurrentPageIndex = 0;
		}

		private void BindGrid()
		{
			Orciid.Core.User user = Orciid.Core.User.CurrentUser();
			Orciid.Core.User[] users;
			if (newuser)
			{
				users = new Orciid.Core.User[1] { new Orciid.Core.User() };
				usergrid.Columns[delete_column].Visible = false;
				usergrid.AllowPaging = false;
				usergrid.CurrentPageIndex = 0;
				usergrid.VirtualItemCount = 1;
			}
			else 
			{
				usergrid.AllowPaging = (ids.Length > usergrid.PageSize);
				if (!usergrid.AllowPaging)
					usergrid.CurrentPageIndex = 0;
				usergrid.VirtualItemCount = ids.Length;
				usergrid.Columns[delete_column].Visible = 
					Orciid.Core.User.HasPrivilege(Privilege.ManageUsers, user);
				if (currentusers != null)
				{
					users = currentusers;
				}
				else
				{
					int count; // number of records on current page
					if (usergrid.CurrentPageIndex < usergrid.PageCount - 1)
						count = usergrid.PageSize;
					else
						count = ids.Length - (usergrid.PageCount - 1) * usergrid.PageSize;
					int[] a = new int[count];
					int baseindex = usergrid.PageSize * usergrid.CurrentPageIndex;
					for (int i = 0; i < count; i++)
						a[i] = ids[i + baseindex];
					users = Orciid.Core.User.GetByID(a);
				}
			 }
			if (users.Length == 0)
				usergrid.Visible = false;
			else
			{
				usergrid.Visible = true;
				usergrid.Columns[edit_column].Visible = 
					Orciid.Core.User.HasPrivilege(Privilege.ManageUsers, user);
				usergrid.Columns[resetpw_column].Visible =
					Orciid.Core.User.HasPrivilege(Privilege.ResetPassword, user);
				usergrid.DataSource = users;
				usergrid.DataBind();
			}
			btnAddNew.Visible = 
				Orciid.Core.User.HasPrivilege(Privilege.ManageUsers, user);
		}

		private void Page_Load(object sender, System.EventArgs e)
		{			
			if (!IsPostBack)
			{
				QueryUserPatterns(true);
				BindGrid();
			}
		}

		public void Reset()
		{
			newuser = false;
			usergrid.EditItemIndex = -1;
			QueryUserPatterns(true);
			BindGrid();
		}

		#region Web Form Designer generated code
		override protected void OnInit(EventArgs e)
		{
			//
			// CODEGEN: This call is required by the ASP.NET Web Form Designer.
			//
			InitializeComponent();
			base.OnInit(e);
		}
		
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{    
			this.FirstLetterRepeater.ItemCommand += new System.Web.UI.WebControls.RepeaterCommandEventHandler(this.FirstLetterRepeater_ItemCommand);
			this.btnAddNew.Click += new System.EventHandler(this.btnAddNew_Click);
			this.usergrid.ItemCreated += new System.Web.UI.WebControls.DataGridItemEventHandler(this.usergrid_ItemCreated);
			this.usergrid.PageIndexChanged += new System.Web.UI.WebControls.DataGridPageChangedEventHandler(this.usergrid_PageIndexChanged);
			this.usergrid.CancelCommand += new System.Web.UI.WebControls.DataGridCommandEventHandler(this.usergrid_CancelCommand);
			this.usergrid.EditCommand += new System.Web.UI.WebControls.DataGridCommandEventHandler(this.usergrid_EditCommand);
			this.usergrid.UpdateCommand += new System.Web.UI.WebControls.DataGridCommandEventHandler(this.usergrid_UpdateCommand);
			this.usergrid.DeleteCommand += new System.Web.UI.WebControls.DataGridCommandEventHandler(this.usergrid_DeleteCommand);
			this.usergrid.ItemDataBound += new System.Web.UI.WebControls.DataGridItemEventHandler(this.usergrid_ItemDataBound);
			this.Load += new System.EventHandler(this.Page_Load);
			this.Init += new System.EventHandler(this.test_Init);

		}
		#endregion

		private void usergrid_DeleteCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
		{
			usergrid.EditItemIndex = -1;
			int baseindex = usergrid.PageSize * usergrid.CurrentPageIndex;
			int id = ids[baseindex + e.Item.ItemIndex];
			Orciid.Core.User user = Orciid.Core.User.GetByID(id);
			if (user != null)
			{
				try
				{
					user.Delete();
					QueryUsers(user.Login.Substring(0, 1));
					BindGrid();
				}
				catch (CoreException)
				{
					ShowError("UserDeletionFailed", "User deletion failed.");
				}
			}
		}

		private void usergrid_UpdateCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
		{
			string login = ((TextBox)e.Item.Cells[login_column].FindControl("LoginTextBox")).Text;
			string lastname = ((TextBox)e.Item.Cells[name_column].FindControl("LastNameTextBox")).Text;
			string firstname = ((TextBox)e.Item.Cells[name_column].FindControl("FirstNameTextBox")).Text;
			string email = ((TextBox)e.Item.Cells[email_column].FindControl("EmailTextBox")).Text;
			bool admin = ((CheckBox)e.Item.Cells[admin_column].FindControl("AdminCheckBox")).Checked;
//			CheckBoxList grouplist = ((CheckBoxList)e.Item.Cells[groups_column].FindControl("GroupCheckBoxList"));
			Orciid.Core.User currentuser = Orciid.Core.User.CurrentUser();
			if (newuser)
			{
				try
				{
					Orciid.Core.User user = new Orciid.Core.User();
					user.Login = login;
					user.LastName = lastname;
					user.FirstName = firstname;
					user.Email = email;
					if (currentuser.Administrator)
						user.Administrator = admin;
					user.Update();
/*					foreach (ListItem item in grouplist.Items)
						if (item.Selected)
						{
							MemberUserGroup group = UserGroup.GetByID(Int32.Parse(item.Value)) as MemberUserGroup;
							if (group != null)
								group.Add(user);
						}
*/				}
				catch (CoreException)
				{
				}
				newuser = false;
				QueryUserPatterns(false);
				QueryUsers(login.Substring(0, 1));
			}
			else
			{
				int baseindex = usergrid.PageSize * usergrid.CurrentPageIndex;
				Orciid.Core.User user = Orciid.Core.User.GetByID(ids[baseindex + usergrid.EditItemIndex]);
				try
				{
					user.Login = login;
					user.LastName = lastname;
					user.FirstName = firstname;
					user.Email = email;
					if (currentuser.Administrator)
						user.Administrator = admin;
					user.Update();
/*					foreach (ListItem item in grouplist.Items)
					{
						MemberUserGroup group = UserGroup.GetByID(Int32.Parse(item.Value)) as MemberUserGroup;
						if (group != null)
						{
							if (item.Selected)
								group.Add(user);
							else
								group.Remove(user);
						}
					}
*/				}
				catch (CoreException)
				{
				}
			}
			usergrid.EditItemIndex = -1;
			BindGrid();
		}

		private void usergrid_EditCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
		{
			usergrid.EditItemIndex = e.Item.ItemIndex;
			BindGrid();
		}

		private void usergrid_CancelCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
		{
			newuser = false;
			usergrid.EditItemIndex = -1;
			BindGrid();
		}

		private void usergrid_ItemDataBound(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
		{
		}

		private void usergrid_ItemCreated(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
		{
		}

		static string yesmessage = null;
		static string nomessage = null;

		protected void DataBindAdminLiteral(object sender, System.EventArgs e)
		{
			Literal control = sender as Literal;
			DataGridItem item = GetDataGridItem(control);
			Orciid.Core.User user = item.DataItem as Orciid.Core.User;
			if (yesmessage == null)
				yesmessage = this.GetLocalString("Yes", "Yes");
			if (nomessage == null)
				nomessage = this.GetLocalString("No", "No");
			control.Text = (user.Administrator ? yesmessage : nomessage);
		}

		protected void DataBindAdminCheckBox(object sender, System.EventArgs e)
		{
			CheckBox control = sender as CheckBox;
			DataGridItem item = GetDataGridItem(control);
			Orciid.Core.User user = item.DataItem as Orciid.Core.User;
			control.Checked = user.Administrator;
			Orciid.Core.User currentuser = Orciid.Core.User.CurrentUser();
			control.Enabled = (currentuser != null && currentuser.Administrator);
		}
/*
		protected void DataBindGroupRepeater(object sender, System.EventArgs e)
		{
			Repeater repeater = sender as Repeater;
			DataGridItem item = GetDataGridItem(repeater);
			Orciid.Core.User user = item.DataItem as Orciid.Core.User;
			int[] groupids = UserGroup.FindUser(user);
			if (groupids != null)
				repeater.DataSource = UserGroup.GetByID(groupids);
			else
				repeater.DataSource = null;
		}

		protected void DataBindGroupCheckBoxList(object sender, System.EventArgs e)
		{
			CheckBoxList checkboxlist = sender as CheckBoxList;
			DataGridItem item = GetDataGridItem(checkboxlist);
			Orciid.Core.User user = item.DataItem as Orciid.Core.User;
			checkboxlist.Items.Clear();
			foreach (UserGroup group in UserGroup.GetUserGroups())
			{
				if (group is MemberUserGroup)
				{
					ListItem listitem = new ListItem(group.Title, group.ID.ToString());
					listitem.Selected = group.HasMember(user);
					checkboxlist.Items.Add(listitem);
				}
			}
		}	
*/	
		protected void DataBindResetPasswordLinkButton(object sender, System.EventArgs e)
		{
			LinkButton button = sender as LinkButton;
			DataGridItem item = GetDataGridItem(button);
			if (item.ItemIndex == resetpasswordindex)
				button.Visible = false;
		}

		protected void DataBindResetPasswordPanel(object sender, System.EventArgs e)
		{
			Panel panel = sender as Panel;
			DataGridItem item = GetDataGridItem(panel);
			if (item.ItemIndex == resetpasswordindex)
				panel.Visible = true;
		}

		static string confirmdeletemessage = null;

		protected void DataBindDeleteButton(object sender, System.EventArgs e)
		{
			LinkButton control = sender as LinkButton;
			if (confirmdeletemessage == null)
				confirmdeletemessage = this.GetLocalString("ConfirmDelete",
				"Are you sure you want to delete this user?");
			control.Attributes["onclick"] = "return confirm('" + 
				confirmdeletemessage.Replace(@"\", @"\\").Replace("'", @"\'") + "');";
		}

		protected void UpdatePasswordButtonClick(object sender, System.EventArgs e)
		{
			Button button = sender as Button;
			DataGridItem item = GetDataGridItem(button);
			CheckBox sendemail = button.Parent.FindControl("EmailPasswordCheckBox") as CheckBox;
			RadioButton AutogeneratePasswordRadioButton = button.Parent.FindControl("AutogeneratePasswordRadioButton") as RadioButton;
			RadioButton SetPasswordRadioButton = button.Parent.FindControl("SetPasswordRadioButton") as RadioButton;
			RadioButton RemovePasswordRadioButton = button.Parent.FindControl("RemovePasswordRadioButton") as RadioButton;
			TextBox SetPasswordTextBox = button.Parent.FindControl("SetPasswordTextBox") as TextBox;
			string newpassword = null;
			if (AutogeneratePasswordRadioButton.Checked)
			{
				newpassword = GeneratePassword();
			}
			else if (SetPasswordRadioButton.Checked)
			{
				newpassword = SetPasswordTextBox.Text;
			}
			else if (RemovePasswordRadioButton.Checked)
			{
				newpassword = "";
			}
			if (newpassword != null)
			{
				int baseindex = usergrid.PageSize * usergrid.CurrentPageIndex;
				int userid = ids[baseindex + item.ItemIndex];
				Orciid.Core.User user = Orciid.Core.User.GetByID(userid);
				Orciid.Core.User current = Orciid.Core.User.CurrentUser();
				if (user != null)
				{
					try
					{
						user.SetPassword(newpassword);
						if (sendemail.Checked && user.Email != null && user.Email.Length > 0)
						{
							MailMessage msg = new MailMessage();
							string from;
							string subject;
							string body;
							EmailTemplate.GetEmail("passwordnotification", 
								out from, out subject, out body,
								newpassword, user.FullName, user.Email, current.FullName, current.Email);
							msg.From = from;
							msg.To = user.Email;
							msg.Subject = subject;
							msg.BodyFormat = MailFormat.Text;
							msg.Body = body;
							SmtpMail.Send(msg);
						}
					}
					catch (CoreException)
					{
						ShowError("PasswordUpdateFailed", "Password update failed.");
					}
				}
			}
			BindGrid();
		}

		protected void ResetPasswordLinkButtonClick(object sender, System.EventArgs e)
		{
			usergrid.EditItemIndex = -1;
			LinkButton button = sender as LinkButton;
			DataGridItem item = GetDataGridItem(button);
			resetpasswordindex = item.ItemIndex;
			BindGrid();
		}

		private void btnAddNew_Click(object sender, System.EventArgs e)
		{
			newuser = true;
			usergrid.EditItemIndex = 0;
			BindGrid();
		}

		private void test_Init(object sender, System.EventArgs e)
		{
		}

		private void usergrid_PageIndexChanged(object source, System.Web.UI.WebControls.DataGridPageChangedEventArgs e)
		{
			usergrid.CurrentPageIndex = e.NewPageIndex;
			BindGrid();
		}

		private void FirstLetterRepeater_ItemCommand(object source, System.Web.UI.WebControls.RepeaterCommandEventArgs e)
		{
			newuser = false;
			usergrid.EditItemIndex = -1;
			QueryUsers((string)e.CommandArgument);
			BindGrid();
		}

/*		public override string GetHighlightedMenuItem()
		{
			return "SystemTools_ManageUsers";
		}

		protected override bool CheckUserPrivileges(Orciid.Core.User user)
		{
			return Orciid.Core.User.HasPrivilege(Privilege.CreateUser, user) ||
				Orciid.Core.User.HasPrivilege(Privilege.ModifyUser, user) ||
				Orciid.Core.User.HasPrivilege(Privilege.RemoveUser, user) ||
				Orciid.Core.User.HasPrivilege(Privilege.ResetPassword, user);
		}
*/

	}
}
