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

using System;
using System.Collections;
using System.Web.UI.WebControls;
using CommunityServer.Components;

namespace CommunityServer.Controls
{
	public class UserSearch : TemplatedWebControl
	{
		public UserSearch()
		{
		}

		#region Child Controls

		protected System.Web.UI.WebControls.TextBox searchText;
		protected System.Web.UI.WebControls.DropDownList searchType;
		protected System.Web.UI.WebControls.DropDownList searchRole;
		protected System.Web.UI.WebControls.DropDownList joinedDateComparer;
		protected System.Web.UI.WebControls.DropDownList lastPostDateComparer;
		protected ComponentArt.Web.UI.Calendar joinedDate;
		protected ComponentArt.Web.UI.Calendar lastPostDate;
		protected ComponentArt.Web.UI.Calendar joinedDateCalendar;
		protected ComponentArt.Web.UI.Calendar lastPostDateCalendar;
		protected CommunityServer.Controls.AccountStatusDropDownList currentAccountStatus;
		protected CommunityServer.Controls.SortOrderDropDownList sortOrderDropDown;
		protected CommunityServer.Controls.MemberSortDropDownList memberSortDropDown;
		protected LinkButton searchButton;
		protected System.Web.UI.HtmlControls.HtmlTableRow AdminRow1;

		#endregion

		#region Public Properties

		public virtual string DestinationURL 
		{
			get 
			{
				Object state = ViewState["DestinationURL"];
				if ( state != null ) 
				{
					return (String)state;
				}
				return this.Page.Request.Path;
			}
			set 
			{
				ViewState["DestinationURL"] = value;
			}
		}

		public string SearchText
		{
			get{return this.searchText.Text;}
			set{this.searchText.Text = value;}
		}

		public string SearchType
		{
			get{return this.searchType.SelectedValue;}
			set {
				if (this.searchType.Items.FindByValue(value) != null)
					this.searchType.SelectedValue = value;
			}
		}

		public string SearchRole
		{
			get{return this.searchRole.SelectedValue;}
			set {
				if (this.searchRole.Items.FindByValue(value) != null)
					this.searchRole.SelectedValue = value;
			}
		}

		public string SearchJoinedDateComparer
		{
			get{return this.joinedDateComparer.SelectedValue;}
			set {
				if (this.joinedDateComparer.Items.FindByValue(value) != null)
					this.joinedDateComparer.SelectedValue = value;
			}
		}

		public string SearchLastPostDateComparer
		{
			get{return this.lastPostDateComparer.SelectedValue;}
			set {
				if (this.lastPostDateComparer.Items.FindByValue(value) != null)
					this.lastPostDateComparer.SelectedValue = value;
			}
		}

		public UserAccountStatus SearchAccountStatus
		{
			get{return this.currentAccountStatus.SelectedValue;}
			set
			{
				if (this.currentAccountStatus.Items.FindByValue(((int) value).ToString()) != null)
					this.currentAccountStatus.SelectedValue = value;
			}
		}

		public SortUsersBy SortByValue
		{
			get
			{
				return this.memberSortDropDown.SelectedSortOrder;
			}
			set
			{
				if (this.memberSortDropDown.Items.FindByValue(((int) value).ToString()) != null)
					this.memberSortDropDown.SelectedValue = ((int) value).ToString();
			}
		}

		public SortOrder SortOrderValue
		{
			get{return this.sortOrderDropDown.SelectedValue;}
			set
			{
				if (this.sortOrderDropDown.Items.FindByValue(((int) value).ToString()) != null)
					this.sortOrderDropDown.SelectedValue = value;
			}
		}
		
		public DateTime SearchJoinedDate
		{
			get{return this.joinedDate.SelectedDate;}
			set{this.joinedDate.SelectedDate = value;}
		}

		public DateTime SearchLastPostDate
		{
			get{return this.lastPostDate.SelectedDate;}
			set{this.lastPostDate.SelectedDate = value;}
		}


		#endregion

		private bool _isAdmin = false;

		protected override void OnInit(EventArgs e)
		{
			base.OnInit(e);

			CSContext csContext = CSContext.Current;
			if ((csContext.User.IsAdministrator) || (csContext.User.IsMembershipAdministrator))
				this._isAdmin = true;

			this.EnsureChildControls();

			if (!this.Page.IsPostBack)
			{
				DataBind();
			}

		}


		protected override void OnLoad(EventArgs e)
		{
			base.OnLoad(e);

			string clearDateScript = "<script language=\"javascript\">{0}.ClearSelectedDate(); document.forms[0].{1}Calendar_button.width = 0;</script>";
			if (this.lastPostDateComparer.SelectedIndex == 0)
				this.Page.RegisterStartupScript("clearLastPostDate", string.Format(clearDateScript, lastPostDate.ClientID, "lastPostDate"));
			if (this.joinedDateComparer.SelectedIndex == 0)
				this.Page.RegisterStartupScript("clearJoinedDate", string.Format(clearDateScript, joinedDate.ClientID, "joinedDate"));
		}


		protected override void AttachChildControls()
		{
			searchText = FindControl("searchText") as TextBox;
			searchType = FindControl("searchType") as DropDownList;
			searchRole = FindControl("searchRole") as DropDownList;
			joinedDateComparer = FindControl("joinedDateComparer") as DropDownList;
			lastPostDateComparer = FindControl("lastPostDateComparer") as DropDownList;
			joinedDate = FindControl("joinedDate") as ComponentArt.Web.UI.Calendar;
			lastPostDate = FindControl("lastPostDate") as ComponentArt.Web.UI.Calendar;
			joinedDateCalendar = FindControl("joinedDateCalendar") as ComponentArt.Web.UI.Calendar;
			lastPostDateCalendar = FindControl("lastPostDateCalendar") as ComponentArt.Web.UI.Calendar;
			currentAccountStatus = FindControl("currentAccountStatus") as AccountStatusDropDownList;
			sortOrderDropDown = FindControl("sortOrderDropDown") as SortOrderDropDownList;
			memberSortDropDown = FindControl("memberSortDropDown") as MemberSortDropDownList;
			searchButton = FindControl("searchButton") as LinkButton;
			AdminRow1 = FindControl("AdminRow1") as System.Web.UI.HtmlControls.HtmlTableRow;

			if (this.searchButton != null)
			{
				this.searchButton.Click += new System.EventHandler(this.SearchButton_Click);
				this.searchButton.Text = ResourceManager.GetString("Search");
			}

			joinedDateCalendar.NextImageUrl = SiteUrls.Instance().Locations["controlpanel"] + "images/caimages/cal_nextMonth.gif";
			joinedDateCalendar.PrevImageUrl = SiteUrls.Instance().Locations["controlpanel"] + "images/caimages/cal_prevMonth.gif";
			lastPostDateCalendar.NextImageUrl = SiteUrls.Instance().Locations["controlpanel"] + "images/caimages/cal_nextMonth.gif";
			lastPostDateCalendar.PrevImageUrl = SiteUrls.Instance().Locations["controlpanel"] + "images/caimages/cal_prevMonth.gif";

		}


		public override void DataBind()
		{
			base.DataBind();

			if(!Page.IsPostBack)
			{

				// Only make SearchType and AccountStatus controls visible for admins
				AdminRow1.Visible = this._isAdmin;

				string clearDateScript = "<script language=\"javascript\">{0}.ClearSelectedDate(); document.forms[0].{1}Calendar_button.width = 0;</script>";
				if (this.lastPostDateComparer.SelectedIndex == 0)
					this.Page.RegisterStartupScript("clearLastPostDate", string.Format(clearDateScript, lastPostDate.ClientID, "lastPostDate"));
				if (this.joinedDateComparer.SelectedIndex == 0)
					this.Page.RegisterStartupScript("clearJoinedDate", string.Format(clearDateScript, joinedDate.ClientID, "joinedDate"));

				if (this._isAdmin && this.currentAccountStatus != null)
					this.currentAccountStatus.DataBind();

				if (this.joinedDateComparer != null)
					joinedDateComparer.Attributes.Add("onChange", "disableJoinedDate(this);");

				if (this.lastPostDateComparer != null)
					lastPostDateComparer.Attributes.Add("onChange", "disableLastPostDate(this);");

				if (this.joinedDate != null)
					this.joinedDate.SelectedDate = DateTime.Now;

				if (this.lastPostDate != null)
					this.lastPostDate.SelectedDate = DateTime.Now;

				// Populate Roles DropDown
				if (this.searchRole != null)
				{
					ArrayList RoleList;

					if (this._isAdmin)
						RoleList = CommunityServer.Components.Roles.GetRoles();
					else
						RoleList = CommunityServer.Components.Roles.GetRoles(CSContext.Current.User.UserID, true);

					searchRole.Items.Add(new ListItem(" All ", ""));
					foreach (Role r in RoleList)
					{
						searchRole.Items.Add(new ListItem(r.Name, r.RoleID.ToString()));
					}
				}

				// Populate searchType DropDown
				if (this._isAdmin && this.searchType != null)
				{
					searchType.Items.Add(new ListItem(ResourceManager.GetString("UserSearchControl_UsernameEmail"), "all"));
					searchType.Items.Add(new ListItem(ResourceManager.GetString("UserSearchControl_Username"), "username"));
					searchType.Items.Add(new ListItem(ResourceManager.GetString("UserSearchControl_Email"), "email"));
				}

				// Populate joinedDateComparer DropDown
				if (this.joinedDateComparer != null)
				{
					joinedDateComparer.Items.Add(new ListItem(ResourceManager.GetString("UserSearchControl_BlankDate"), "--"));
					joinedDateComparer.Items.Add(new ListItem(ResourceManager.GetString("UserSearchControl_On"), "0"));
					joinedDateComparer.Items.Add(new ListItem(ResourceManager.GetString("UserSearchControl_After"), "1"));
					joinedDateComparer.Items.Add(new ListItem(ResourceManager.GetString("UserSearchControl_Before"), "-1"));
				}

				// Populate lastPostDateComparer DropDown
				if (this.lastPostDateComparer != null)
				{
					lastPostDateComparer.Items.Add(new ListItem(ResourceManager.GetString("UserSearchControl_BlankDate"), "--"));
					lastPostDateComparer.Items.Add(new ListItem(ResourceManager.GetString("UserSearchControl_On"), "0"));
					lastPostDateComparer.Items.Add(new ListItem(ResourceManager.GetString("UserSearchControl_After"), "1"));
					lastPostDateComparer.Items.Add(new ListItem(ResourceManager.GetString("UserSearchControl_Before"), "-1"));
				}
			
			}

		}


		#region Events
		private void SearchButton_Click(object sender, System.EventArgs e)
		{

			System.Text.StringBuilder url = new System.Text.StringBuilder();
			url.AppendFormat("{0}?search=1", this.DestinationURL);

			url.AppendFormat("&t={0}", Globals.UrlEncode(this.searchText.Text));

			// Tab (for use inside the Control Panel)
			string tab = CSContext.Current.QueryString["tab"];
			if (!Globals.IsNullorEmpty(tab))
                url.AppendFormat("&tab={0}", tab);

			if (this._isAdmin)
			{
				url.AppendFormat("&st={0}", this.searchType.SelectedValue);
			
				switch (this.searchType.SelectedValue)
				{
					case "all":
					{
						url.Append("&su=1&se=1");
						break;
					}
					case "username":
					{
						url.Append("&su=1&se=0");
						break;
					}
					case "email":
					{
						url.Append("&su=0&se=1");
						break;
					}
				}

				url.AppendFormat("&s={0}", Globals.UrlEncode(this.currentAccountStatus.SelectedValue.ToString()));
			}

			if (!Globals.IsNullorEmpty(this.searchRole.SelectedValue))
				url.AppendFormat("&r={0}", Globals.UrlEncode(this.searchRole.SelectedValue));

			if (this.joinedDateComparer.SelectedIndex != 0)
			{
				url.AppendFormat("&jc={0}", Globals.UrlEncode(this.joinedDateComparer.SelectedValue));
				url.AppendFormat("&jd={0}", Globals.UrlEncode(this.joinedDate.SelectedDate.ToShortDateString()));
			}

			if (this.lastPostDateComparer.SelectedIndex != 0)
			{
				url.AppendFormat("&pc={0}", Globals.UrlEncode(this.lastPostDateComparer.SelectedValue));
				url.AppendFormat("&pd={0}", Globals.UrlEncode(this.lastPostDate.SelectedDate.ToShortDateString()));
			}

			url.AppendFormat("&sb={0}", Globals.UrlEncode(((int)this.memberSortDropDown.SelectedSortOrder).ToString()));
			url.AppendFormat("&so={0}", Globals.UrlEncode(((int)this.sortOrderDropDown.SelectedValue).ToString()));

			this.Page.Response.Redirect(url.ToString());

		}

		#endregion

		public UserSet GetUsersAndBindControl(int pageIndex, int pageSize, string sortClauseOverride)
		{
			CSContext context = CSContext.Current;

			UserQuery query = new UserQuery();
			query.IncludeHiddenUsers = this._isAdmin;
			query.PageIndex = pageIndex;
			query.PageSize = pageSize;

			// Search Text
			string searchText = context.QueryString["t"];
			if (searchText != null)
			{
				query.SearchText = searchText;
				this.SearchText = searchText;
			}

			// Search Type
			query.SearchEmail = false;
			query.SearchUsername = true;
			if (this._isAdmin)
			{
				string searchType = context.QueryString["st"];
				if (searchType != null)
					this.SearchType = searchType;

				int su = context.GetIntFromQueryString("su", 0);
				int se = context.GetIntFromQueryString("se", 0);
				query.SearchUsername = (su == 1);
				query.SearchEmail = (se == 1);
			}
			
			// Account Status
			query.Status = UserAccountStatus.Approved;
			if (this._isAdmin)
			{
				string AccountStatusString = context.QueryString["s"];
				if (AccountStatusString != null)
				{
					try
					{
						UserAccountStatus AccountStatus = (UserAccountStatus)System.Enum.Parse(typeof(UserAccountStatus), AccountStatusString, true);
						query.Status = AccountStatus;
						this.SearchAccountStatus = AccountStatus;
					}
					catch {}
				}
			}

			// User Role
			Guid RoleID = context.GetGuidFromQueryString("r");
			if(RoleID != Guid.Empty)
			{
				query.RoleID = RoleID;
				this.SearchRole = RoleID.ToString();
			}

			// Joined Date
			string joinedDate = context.QueryString["jd"];
			int joinedDateComparer = context.GetIntFromQueryString("jc", 0);
			if (Globals.IsDate(joinedDate))
			{
				query.JoinedDate = DateTime.Parse(joinedDate);
				query.JoinedDateComparer = joinedDateComparer;
				this.SearchJoinedDate = DateTime.Parse(joinedDate);
				this.SearchJoinedDateComparer = joinedDateComparer.ToString();
			}

			// Last Post Date
			string lastPostDate = context.QueryString["pd"];
			int lastPostDateComparer = context.GetIntFromQueryString("pc", 0);
			if (Globals.IsDate(lastPostDate))
			{
				query.LastPostDate = DateTime.Parse(lastPostDate);
				query.LastPostDateComparer = lastPostDateComparer;
				this.SearchLastPostDate = DateTime.Parse(lastPostDate);
				this.SearchLastPostDateComparer = lastPostDateComparer.ToString();
			}

			if (!Globals.IsNullorEmpty(sortClauseOverride))
			{
				string[] sort = sortClauseOverride.Split(' ');
				if (sort.Length > 0)
				{
					switch (sort[0])
					{
						case "Username":
						{
							query.SortBy = SortUsersBy.Username;
							break;
						}
						case "Email":
						{
							query.SortBy = SortUsersBy.Email;
							break;
						}
						case "TotalPosts":
						{
							query.SortBy = SortUsersBy.Posts;
							break;
						}
						case "DateCreated":
						{
							query.SortBy = SortUsersBy.JoinedDate;
							break;
						}
						case "LastActivity":
						{
							query.SortBy = SortUsersBy.LastActiveDate;
							break;
						}
					}
				}

				if (sort.Length > 1 & sort[1] != null)
				{
					if (sort[1].Trim().ToLower() == "desc")
						query.Order = SortOrder.Descending;
				}

			}
			else
			{

				// Sort Users By		
				try
				{
					SortUsersBy sortBy = (SortUsersBy)System.Enum.Parse(typeof(SortUsersBy), context.GetIntFromQueryString("sb", 1).ToString(), true);
					query.SortBy = sortBy;
				}
				catch
				{
					query.SortBy = SortUsersBy.Username;
				}
				this.SortByValue = query.SortBy;

				// Sort Order
				try
				{
					SortOrder sortOrder = (SortOrder)System.Enum.Parse(typeof(SortOrder), context.GetIntFromQueryString("so", 0).ToString(), true);
					query.Order = sortOrder;
				}
				catch
				{
					query.Order = SortOrder.Ascending;
				}
				this.SortOrderValue = query.Order;
			}
			
			return Users.GetUsers(query, true);
		}


	}
}
