namespace Orciid
{
	using System;
	using System.Data;
	using System.Drawing;
	using System.Web;
	using System.Web.UI;
	using System.Web.UI.WebControls;
	using System.Web.UI.HtmlControls;
	using Orciid.PageTemplate;
	using Orciid.UserControls;
	using Orciid.Core;

	public class UserGroupsControl : OrciidUserControl
	{
		protected System.Web.UI.WebControls.Repeater FirstLetterRepeater;
		protected System.Web.UI.WebControls.DataGrid groupgrid;

		private const int title_column = 0;
		//private const int type_column = 1;
		//private const int edit_column = 2;
		private const int properties_column = 3;
		private const int delete_column = 4;

		private int[] ids;
		private char newgroup = '\0';
		protected System.Web.UI.WebControls.DropDownList AddNewDropDownList;
		protected System.Web.UI.WebControls.Button AddNewButton;
		protected System.Web.UI.WebControls.Panel UserGroupListPanel;
		protected System.Web.UI.WebControls.LinkButton BackButton;
		protected Orciid.UserControls.IPUserGroupProperties IPUserGroupPropertiesControl;
		protected Orciid.UserControls.MemberUserGroupProperties MemberUserGroupPropertiesControl;
		protected Orciid.UserControls.AttributeUserGroupProperties AttributeUserGroupPropertiesControl;
		protected System.Web.UI.WebControls.Label UserGroupTitle;
		protected System.Web.UI.WebControls.Panel PropertiesHeaderPanel;
		protected System.Web.UI.HtmlControls.HtmlGenericControl PropertiesHeading;
		private UserGroup[] currentgroups;

		private void Page_Load(object sender, System.EventArgs e)
		{
			if (!IsPostBack)
			{
				AddNewDropDownList.Items.Clear();
				AddNewDropDownList.Items.Add(new ListItem("", ""));
				AddNewDropDownList.Items.Add(new ListItem(GetLocalString("MembershipGroup", "Membership"), "M"));
				AddNewDropDownList.Items.Add(new ListItem(GetLocalString("IPBasedGroup", "IP based"), "I"));
				AddNewDropDownList.Items.Add(new ListItem(GetLocalString("AttributeBasedGroup", "Attribute based"), "P"));
				AddNewDropDownList.Items.Add(new ListItem(GetLocalString("AuthenticatedGroup", "Authenticated"), "A"));
				AddNewDropDownList.Items.Add(new ListItem(GetLocalString("EverybodyGroup", "Everybody"), "E"));
				QueryGroupPatterns(true);
				BindGrid();
			}
		}

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

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

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

		private void QueryGroupPatterns(bool querygroups)
		{
			string[] patterns = Orciid.Core.UserGroup.GetTitlePatterns(1);
			FirstLetterRepeater.DataSource = patterns;
			FirstLetterRepeater.DataBind();
			if (querygroups)
			{
				if (patterns != null && patterns.Length > 0)
					QueryGroups(patterns[0]);
				else 
					ids = new int[0];
			}
		}

		private void QueryGroups(string filter)
		{
			UserGroup[] groups = Orciid.Core.UserGroup.GetByTitlePattern(filter);
			ids = new int[groups.Length];
			for (int i = 0; i < groups.Length; i++)
				ids[i] = groups[i].ID;
			currentgroups = new Orciid.Core.UserGroup[Math.Min(groupgrid.PageSize, groups.Length)];
			for (int i = 0; i < currentgroups.Length; i++)
				currentgroups[i] = groups[i];
			groupgrid.CurrentPageIndex = 0;
		}

		private void BindGrid()
		{
			//Orciid.Core.User user = Orciid.Core.User.CurrentUser();
			Orciid.Core.UserGroup[] groups;
			if (newgroup != '\0')
			{
				groups = new Orciid.Core.UserGroup[1] { UserGroup.CreateUserGroupByType(newgroup) };
				groupgrid.Columns[delete_column].Visible = false;
				groupgrid.Columns[properties_column].Visible = false;
				groupgrid.AllowPaging = false;
				groupgrid.VirtualItemCount = 1;
			}
			else 
			{
				groupgrid.AllowPaging = (ids.Length > groupgrid.PageSize);
				groupgrid.VirtualItemCount = ids.Length;
				groupgrid.Columns[delete_column].Visible = true;
				groupgrid.Columns[properties_column].Visible = true;

				if (currentgroups != null)
				{
					groups = currentgroups;
				}
				else if (ids.Length == 0)
				{
					groups = new UserGroup[0];
				}
				else
				{
					int count; // number of records on current page
					if (groupgrid.CurrentPageIndex < groupgrid.PageCount - 1)
						count = groupgrid.PageSize;
					else
						count = ids.Length - (groupgrid.PageCount - 1) * groupgrid.PageSize;
					int[] a = new int[count];
					int baseindex = groupgrid.PageSize * groupgrid.CurrentPageIndex;
					for (int i = 0; i < count; i++)
						a[i] = ids[i + baseindex];
					groups = Orciid.Core.UserGroup.GetByID(a);
				}
			}
			if (groups.Length == 0)
				groupgrid.Visible = false;
			else
			{
				groupgrid.Visible = true;
				groupgrid.DataSource = groups;
				groupgrid.DataBind();
			}
		}

		public void Reset()
		{
			newgroup = '\0';
			groupgrid.EditItemIndex = -1;
			CloseAllPropertyPages();
			QueryGroupPatterns(true);
			BindGrid();
		}

		protected void DataBindTypeLabel(object sender, System.EventArgs e)
		{
			Label control = sender as Label;
			DataGridItem item = GetDataGridItem(control);
			UserGroup group = item.DataItem as UserGroup;
			control.Text = AddNewDropDownList.Items.FindByValue(group.GetGroupType().ToString()).Text;
		}

		protected void DataBindPropertiesButton(object sender, System.EventArgs e)
		{
			LinkButton control = sender as LinkButton;
			DataGridItem item = GetDataGridItem(control);
			UserGroup group = item.DataItem as UserGroup;
			control.Visible = group.HasProperties();
		}

		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 group?");
			control.Attributes["onclick"] = "return confirm('" + 
				confirmdeletemessage.Replace(@"\", @"\\").Replace("'", @"\'") + "');";
		}

		#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.AddNewButton.Click += new System.EventHandler(this.AddNewButton_Click);
			this.groupgrid.ItemCommand += new System.Web.UI.WebControls.DataGridCommandEventHandler(this.groupgrid_ItemCommand);
			this.groupgrid.PageIndexChanged += new System.Web.UI.WebControls.DataGridPageChangedEventHandler(this.groupgrid_PageIndexChanged);
			this.groupgrid.CancelCommand += new System.Web.UI.WebControls.DataGridCommandEventHandler(this.groupgrid_CancelCommand);
			this.groupgrid.EditCommand += new System.Web.UI.WebControls.DataGridCommandEventHandler(this.groupgrid_EditCommand);
			this.groupgrid.UpdateCommand += new System.Web.UI.WebControls.DataGridCommandEventHandler(this.groupgrid_UpdateCommand);
			this.groupgrid.DeleteCommand += new System.Web.UI.WebControls.DataGridCommandEventHandler(this.groupgrid_DeleteCommand);
			this.BackButton.Click += new System.EventHandler(this.BackButton_Click);
			this.Load += new System.EventHandler(this.Page_Load);

		}
		#endregion

		private void FirstLetterRepeater_ItemCommand(object source, System.Web.UI.WebControls.RepeaterCommandEventArgs e)
		{
			newgroup = '\0';
			groupgrid.EditItemIndex = -1;
			QueryGroups((string)e.CommandArgument);
			BindGrid();
		}

		private void AddNewButton_Click(object sender, System.EventArgs e)
		{
			string t = AddNewDropDownList.SelectedValue;
			if (t.Length == 1)
			{
				newgroup = t.ToCharArray()[0];
				groupgrid.EditItemIndex = 0;
				BindGrid();
			}
		}

		private void groupgrid_CancelCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
		{
			newgroup = '\0';
			groupgrid.EditItemIndex = -1;
			BindGrid();
		}

		private void groupgrid_DeleteCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
		{
			groupgrid.EditItemIndex = -1;
			int baseindex = groupgrid.PageSize * groupgrid.CurrentPageIndex;
			int id = ids[baseindex + e.Item.ItemIndex];
			UserGroup group = UserGroup.GetByID(id);
			if (group != null)
			{
				try
				{
					string t = group.Title.Substring(0, 1);
					group.Delete();
					QueryGroups(t);
					BindGrid();
				}
				catch (CoreException)
				{
					// FogBugz case 558: show error
				}
			}
		}

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

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

		private void groupgrid_UpdateCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
		{
			string title = ((TextBox)e.Item.Cells[title_column].FindControl("TitleTextBox")).Text;
			if (title != null && title.Length > 0)
			{
				if (newgroup != '\0')
				{
					try
					{
						UserGroup group = UserGroup.CreateUserGroupByType(newgroup);
						group.Title = title;
						group.Update();
					}
					catch (CoreException)
					{
						// FogBugz case 558: show error
					}
					newgroup = '\0';
					QueryGroupPatterns(false);
					QueryGroups(title.Substring(0, 1));
				}
				else
				{
					int baseindex = groupgrid.PageSize * groupgrid.CurrentPageIndex;
					UserGroup group = UserGroup.GetByID(ids[baseindex + groupgrid.EditItemIndex]);
					try
					{
						group.Title = title;
						group.Update();
					}
					catch (CoreException)
					{
						// FogBugz case 558: show error
					}
				}
			}
			groupgrid.EditItemIndex = -1;
			QueryGroupPatterns(true);
			BindGrid();
		}

		private void BackButton_Click(object sender, System.EventArgs e)
		{
			CloseAllPropertyPages();
		}

		private void CloseAllPropertyPages()
		{
			MemberUserGroupPropertiesControl.Visible = false;
			MemberUserGroupPropertiesControl.DataSource = null;
			MemberUserGroupPropertiesControl.DataBind();
			IPUserGroupPropertiesControl.Visible = false;
			IPUserGroupPropertiesControl.DataSource = null;
			IPUserGroupPropertiesControl.DataBind();
			AttributeUserGroupPropertiesControl.Visible = false;
			AttributeUserGroupPropertiesControl.DataSource = null;
			AttributeUserGroupPropertiesControl.DataBind();
			PropertiesHeaderPanel.Visible = false;
			UserGroupListPanel.Visible = true;
		}

		private void groupgrid_ItemCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
		{
			if (e.CommandName == "Properties")
			{
				int baseindex = groupgrid.PageSize * groupgrid.CurrentPageIndex;
				UserGroup group = UserGroup.GetByID(ids[baseindex + e.Item.ItemIndex]);
				UserGroupTitle.Text = group.Title;
				PropertiesHeaderPanel.Visible = true;
				UserGroupListPanel.Visible = false;
				if (group is IPBasedUserGroup)
				{
					IPUserGroupPropertiesControl.Visible = true;
					IPUserGroupPropertiesControl.DataSource = (IPBasedUserGroup)group;
					IPUserGroupPropertiesControl.DataBind();
				}
				else if (group is MemberUserGroup)
				{
					MemberUserGroupPropertiesControl.Visible = true;
					MemberUserGroupPropertiesControl.DataSource = (MemberUserGroup)group;
					MemberUserGroupPropertiesControl.DataBind();
				}
				else if (group is AttributeBasedUserGroup)
				{
					AttributeUserGroupPropertiesControl.Visible = true;
					AttributeUserGroupPropertiesControl.DataSource = (AttributeBasedUserGroup)group;
					AttributeUserGroupPropertiesControl.DataBind();
				}
			}
		}
	}
}
