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

using System;
using System.Collections;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using CommunityServer.Components;
using CommunityServer.ControlPanel.Controls;
using CommunityServer.ControlPanel.UI;
using CommunityServer.Controls;
using CommunityServer.Discussions.Components;
using CommunityServer.Discussions.Controls;
using CommunityServer.Mail.Common.Components;
using TWC = Telligent.Web.UI;
using Telligent.Registration;
using ResourceControl = CommunityServer.ControlPanel.Controls.ResourceControl;
using StatusMessage = CommunityServer.ControlPanel.Controls.StatusMessage;
using ResourceManager = CommunityServer.ControlPanel.Components.ResourceManager;

namespace CommunityServer.ControlPanel.Forums
{
	/// <summary>
	/// Summary description for ForumsHome.
	/// </summary>
	public class SectionEditControl : BaseForumControl
	{
		CSContext csContext = CSContext.Current;

		#region Child Controls

		protected TWC.TabbedPanes TabStrip;
		protected ResourceControl AddSectionHelpResource;

		protected Literal GroupValue;
		protected Hyperlink ParentForumName;
		protected TextBox Name;
		protected TextBox Url;
		protected RequiredFieldValidator NameRequired;
		protected TextBox Description;
		protected CustomValidator DescriptionRequired;
		protected YesNoRadioButtonList IsActive;
		protected YesNoRadioButtonList IsSearchable;
		protected YesNoRadioButtonList IsModerated;
		protected YesNoRadioButtonList EnablePostStatistics;
		protected YesNoRadioButtonList EnablePostPoints;
		protected YesNoRadioButtonList EnableAutoDelete;
		protected TextBox AutoDeleteThreshold;
		protected RequiredFieldValidator AutoDeleteThresholdValidator;
		protected YesNoRadioButtonList EnableAnonymousPosting;
		protected YesNoRadioButtonList EnableAnonymousPostingForUsers;
		protected YesNoRadioButtonList EnableThreadStatusTracking;
		protected StatusDropDownList DefaultThreadStatusValue;
		protected DropDownList AdminGroupList;
		protected DropDownList ForumList;

		protected HtmlTableRow EnableAnonymousPostingRow;
		protected HtmlTableRow EnableAnonymousPostingForUsersRow;
		protected HtmlTableRow EnableThreadStatusTrackingRow;
		protected HtmlTableRow EnableThreadStatusDefaultValueRow;
		protected HtmlTableRow ParentForumRow;

		protected SectionPermissionListControl SectionPermissionListControl1;
		protected SectionPermissionListAdminControl SectionPermissionListAdminControl1;
		protected Control LicenseMaxed;
		protected YesNoRadioButtonList LEEnableMailingList;
		protected TextBox LEListName;
		protected TextBox LEEmailAddress;
		protected TextBox LEFooterMessage;
		protected CustomValidator LEEmailValidator;
		protected YesNoRadioButtonList LEPassiveMode;
		protected TextBox LEPassiveModeAddress;
		protected Literal LEEmailDomain;

		protected FilterLanguageDropDownList DefaultLanguage;

		protected StatusMessage Status;

		#endregion

		#region Public Properties

		private int sectionID = -1;
		public int SectionID
		{
			get { return sectionID; }
			set { sectionID = value;}
		}

		private int parentSectionID = -1;
		public int ParentSectionID
		{
			get { return parentSectionID; }
			set { parentSectionID = value;}
		}
		
		private int groupID = -1;
		public int GroupID
		{
			get { return groupID; }
			set { groupID = value;}
		}

		private Forum section;
		public Forum Section
		{
			get {return section;}
			set {section = value;}
		}

		private bool allowDelete = true;
		public bool AllowDelete
		{
			get {return allowDelete;}
			set {allowDelete = value;}
		}

		#endregion

		private bool isNewForum
		{
			get{return SectionID == -1;}
		}


		override protected void OnInit(EventArgs e)
		{
			this.AdminGroupList.SelectedIndexChanged +=new EventHandler(AdminGroupList_SelectedIndexChanged);
			this.Load += new EventHandler(this.Page_Load);

			DefaultThreadStatusValue.DataBind();
			DefaultThreadStatusValue.AutoPostBack = false;
			DefaultThreadStatusValue.Visible = true;

			foreach(TWC.TabbedPane tab in TabStrip.Panes)
				if(tab.ID == "MailingList")
					tab.Visible = csContext.SiteSettings.EnableMailGateway;

			base.OnInit(e);
		}


		private void Page_Load(object sender, EventArgs e)
		{
			if ( !Page.IsPostBack ) 
			{
				this.Bind();
			}
		}

		
		protected void Bind()
		{
			Status.Visible = false;
			AddSectionHelpResource.Visible = false;

			if (this.isNewForum)
			{
				AllowDelete = false;
			}
			else
			{
				SectionPermissionListControl1.SectionID = SectionID;
				SectionPermissionListAdminControl1.SectionID = SectionID;
			}
		
			this.LoadForum(this.Section);

		}

		private void BindGroupList()
		{
			ArrayList groups = ForumGroups.GetForumGroups(true, true, true);
			foreach(Group group in groups)
			{
				AdminGroupList.Items.Add(new ListItem(group.Name, group.GroupID.ToString()));
			}
		}
		
		private void BindForumList()
		{
			this.GroupID = int.Parse(AdminGroupList.SelectedValue);
			ForumList.Items.Clear();
			ForumList.Items.Add(new ListItem("----", "0"));
			foreach(Forum f in GetForums())
			{
				ForumList.Items.Add(new ListItem(f.Name, f.SectionID.ToString()));
			}
		}

		protected virtual void LoadForum( Forum forum ) 
		{
			if ( forum != null ) 
			{
				// Retrieve ParentID
				if (forum.ParentID > 0)
					ParentSectionID = forum.ParentID;


				if (csContext.User.ControlPanelManageView == ControlPanelManageView.Grid)
				{

					// Do not allow move of special forum types
					if ((forum.ForumType == ForumType.Deleted) || (forum.ForumType == ForumType.Reporting)) 
					{
						GroupValue.Text = forum.GroupName;
						GroupValue.Visible = true;
						AdminGroupList.Visible = false;
						ForumList.Visible = false;
						ParentForumRow.Visible = false;
					}
					else
					{

						BindGroupList();
						GroupValue.Visible = false;
						AdminGroupList.Visible = true;

						if (!this.isNewForum)
							AdminGroupList.SelectedIndex = AdminGroupList.Items.IndexOf(AdminGroupList.Items.FindByValue(this.GroupID.ToString()));
					
						BindForumList();
						ParentForumRow.Visible = true;
						ForumList.Visible = true;
						ParentForumName.Visible = false;

						if (!this.isNewForum)
							ForumList.SelectedIndex = ForumList.Items.IndexOf(ForumList.Items.FindByValue(this.ParentSectionID.ToString()));
					}

				}
				else
				{
					GroupValue.Text = forum.GroupName;
					GroupValue.Visible = true;
					AdminGroupList.Visible = false;
					ForumList.Visible = false;
			
					if (ParentSectionID > 0)
					{
						Forum parentForum = Discussions.Components.Forums.GetForum( ParentSectionID, false, true );
						ParentForumName.Text = parentForum.Name;
						ParentForumName.NavigateUrl = String.Format("IFrameHost.aspx?GroupID={0}&SectionID={1}", forum.GroupID, ParentSectionID);
						ParentForumRow.Visible = true;
					}
					else
					{
						ParentForumRow.Visible = false;
					}
				}

				IsActive.Items.FindByValue( forum.IsActive.ToString() ).Selected = true;
				Name.Text = forum.Name.ToString();
				Url.Text = forum.NavigateUrl;
				Description.Text = forum.Description.ToString();
				IsModerated.Items.FindByValue( forum.IsModerated.ToString()	).Selected = true;
				EnablePostStatistics.Items.FindByValue( forum.EnablePostStatistics.ToString() ).Selected = true;
				EnablePostPoints.Items.FindByValue( forum.EnablePostPoints.ToString() ).Selected = true;
				EnableAutoDelete.Items.FindByValue( forum.EnableAutoDelete.ToString() ).Selected = true;
				EnableAnonymousPosting.Items.FindByValue( forum.EnableAnonymousPosting.ToString() ).Selected = true;
				AutoDeleteThreshold.Text = forum.AutoDeleteThreshold.ToString();
				IsSearchable.Items.FindByValue( forum.IsSearchable.ToString() ).Selected = true;
				EnableAnonymousPostingForUsers.Items.FindByValue( forum.EnableAnonymousPostingForUsers.ToString() ).Selected = true;
				EnableThreadStatusTracking.Items.FindByValue( forum.EnableThreadStatus.ToString() ).Selected = true;
				DefaultThreadStatusValue.SelectedValue = forum.DefaultThreadStatusValue;
				DefaultLanguage.SelectedValue = forum.DefaultLanguage;

				EnableAnonymousPostingRow.Visible = csContext.SiteSettings.EnableAnonymousUserPosting;
				ForumConfiguration config = ForumConfiguration.Instance();
				EnableAnonymousPostingForUsersRow.Visible = config.EnableUserPostingAsAnonymous;
				EnableThreadStatusTrackingRow.Visible = config.EnableThreadStatus;
				EnableThreadStatusDefaultValueRow.Visible = config.EnableThreadStatus;
				

				if ((forum.ForumType == ForumType.Deleted) || (forum.ForumType == ForumType.Reporting)) 
					AllowDelete = false;

				if (csContext.SiteSettings.EnableMailGateway)
				{
					MailingList list = MailingLists.GetMailingList(forum.SectionID);
					if(MailingLists.GetMailingLists().Count < MailGateway.NumberOfLists || (list != null && list.IsMailingList))
					{
						if(list != null)
						{
							LEEmailAddress.Text = list.EmailAddress;
							LEEnableMailingList.Items.FindByValue( list.IsMailingList.ToString() ).Selected = true;
						}
						else
							LEEnableMailingList.SelectedValue = false;
					}
					else
					{
						LEEnableMailingList.Enabled = false;
						LicenseMaxed.Visible = true;
					}

					LEListName.Text = forum.GetExtendedAttribute("ListName");
					LEFooterMessage.Text = forum.GetExtendedAttribute("FooterMessage");

					bool passiveMode = false;
					string b = forum.GetExtendedAttribute("PassiveMode");
					if(!Globals.IsNullorEmpty(b))
					{
						try { passiveMode = bool.Parse(b); }
						catch { }
					}
					LEPassiveMode.SelectedValue = passiveMode;
					LEPassiveModeAddress.Text = forum.GetExtendedAttribute("PassiveModeAddress");
					LEEmailDomain.Text = CSMConfiguration.Instance().DefaultEmailDomain;
				}
			}

		}

	
		protected virtual void UpdateForum( Forum forum ) 
		{
			forum.IsActive = IsActive.SelectedValue;
			forum.Name = Name.Text;
			forum.NavigateUrl = Url.Text;
			forum.Description = Description.Text;
			forum.IsModerated = IsModerated.SelectedValue;
			forum.EnablePostStatistics = EnablePostStatistics.SelectedValue;
			forum.EnablePostPoints = EnablePostPoints.SelectedValue;
			forum.EnableAutoDelete = EnableAutoDelete.SelectedValue;
			forum.EnableAnonymousPosting = EnableAnonymousPosting.SelectedValue;
			forum.IsSearchable = IsSearchable.SelectedValue;
			forum.EnableAnonymousPostingForUsers = EnableAnonymousPostingForUsers.SelectedValue;
			forum.EnableThreadStatus = EnableThreadStatusTracking.SelectedValue;
			forum.DefaultThreadStatusValue = DefaultThreadStatusValue.SelectedValue;
			forum.DefaultLanguage = DefaultLanguage.SelectedValue;

			if (csContext.User.ControlPanelManageView == ControlPanelManageView.Grid)
			{
				forum.GroupID = this.GroupID;
				forum.ParentID = this.ParentSectionID;
			}

			try { forum.AutoDeleteThreshold = Int32.Parse( AutoDeleteThreshold.Text ); }
			catch { AutoDeleteThresholdValidator.IsValid = false; }

			// If we have a URL set the forum type
			if (!Globals.IsNullorEmpty(forum.NavigateUrl))
			{
				// ensure the forum link starts with http
				if (!forum.NavigateUrl.StartsWith("http://"))
					forum.NavigateUrl = "http://" + forum.NavigateUrl;

				forum.ForumType = ForumType.Link;
			}
			else
			{
				// If a link is removed, revert back to normal
				if (forum.ForumType == ForumType.Link)
					forum.ForumType = ForumType.Normal;
			}

			if (Description.Text.Length > 1000)
			{
				DescriptionRequired.IsValid = false;
			}
		}

		protected virtual void PreUpdateMailingList( Forum forum ) 
		{
			if (csContext.SiteSettings.EnableMailGateway)
			{
				// Set the extended attributes
				forum.SetExtendedAttribute("ListName", LEListName.Text);
				forum.SetExtendedAttribute("FooterMessage", LEFooterMessage.Text);
				forum.SetExtendedAttribute("PassiveMode", LEPassiveMode.SelectedValue.ToString());
				forum.SetExtendedAttribute("PassiveModeAddress", LEPassiveModeAddress.Text);
			}
		}

		protected virtual void PostUpdateMailingList( Forum forum ) 
		{
			if (csContext.SiteSettings.EnableMailGateway)
			{
				MailingList origList = MailingLists.GetMailingList(forum.SectionID);
				if(MailingLists.GetMailingLists().Count < MailGateway.NumberOfLists || (origList != null && origList.IsMailingList))
				{
					// Check that if the list is enabled, it has an email address
					if((LEEnableMailingList.SelectedValue == true) && (LEEmailAddress.Text.Trim() == string.Empty))
						LEEmailValidator.IsValid = false;

					// Check that the email address is not a duplicate
					MailingList checkList = MailingLists.GetMailingList(LEEmailAddress.Text.Trim());
					if(checkList != null)
						if(checkList.SectionID != forum.SectionID)
							LEEmailValidator.IsValid = false;

					// Set the core mailing list settings
					MailingList list = new MailingList();
					list.SectionID = forum.SectionID;
					list.EmailAddress = LEEmailAddress.Text.Trim();
					list.IsMailingList = LEEnableMailingList.SelectedValue;

					// Make sure the page is valid before saving.
					if(Page.IsValid)
						MailingLists.UpdateMailingList(list);
				}
			}
		}

		
		protected ArrayList GetForums()
		{
			ArrayList unfiltered = Discussions.Components.Forums.GetForums(false, false, false, true);

			if(GroupID < 0)
			{
				return unfiltered;
			}
			else
			{
				ArrayList filtered = new ArrayList();
				foreach(Forum f in unfiltered)
					if(f.GroupID == GroupID)
						filtered.Add(f);

				return filtered;
			}
		}


		public bool Save()
		{
			Status.Success = false;
			Status.Visible = true;
			Status.ResourceName = "CP_Forums_SectionEdit_StatusFailed";

			if( !csContext.User.IsForumAdministrator ) 
				throw new CSException( CSExceptionType.AdministrationAccessDenied );

			if(Page.IsValid)
			{

				if (AdminGroupList.Visible)
					this.GroupID = int.Parse(AdminGroupList.SelectedValue);

				if (ForumList.Visible)
					this.ParentSectionID = int.Parse(ForumList.SelectedValue);

				if (this.isNewForum)
				{
					Forum forum = this.Section;
					forum.ApplicationType = ApplicationType.Forum;
					forum.ForumType = ForumType.Normal;
					forum.SettingsID = csContext.SiteSettings.SettingsID;

					if (GroupID > 0)
						forum.GroupID = GroupID;

					// Add the GroupID onto the appKey
					string rawKey = String.Format("{0}-{1}", Name.Text, GroupID);
					forum.ApplicationKey = GenerateUniqueApplicationKey(rawKey);

					// Check if this is a subforum
					if (ParentSectionID > 0)
						forum.ParentID = ParentSectionID;

					// Update values from form fields
					UpdateForum(forum);
					PreUpdateMailingList(forum);

					this.SectionID = Discussions.Components.Forums.Add(forum);
					csContext.SectionID = this.SectionID;

					// Save Permissions once we have the new SectionID
					SectionPermissionListControl1.SectionID = SectionID;
					SectionPermissionListControl1.Save();
					SectionPermissionListAdminControl1.SectionID = SectionID;
					SectionPermissionListAdminControl1.Save();
					
					Status.ResourceName = "CP_Forums_SectionEdit_StatusAddSuccess";
					Status.Success = true;

					// Update the main mailing list settings
					PostUpdateMailingList(forum);
				}
				else
				{
					UpdateForum(this.Section);
					PreUpdateMailingList(Section);
					Discussions.Components.Forums.Update(Section);
					PostUpdateMailingList(Section);

					SectionPermissionListControl1.SectionID = SectionID;
					SectionPermissionListControl1.Save();
					SectionPermissionListAdminControl1.SectionID = SectionID;
					SectionPermissionListAdminControl1.Save();

					Status.ResourceName = "CP_Forums_SectionEdit_StatusEditSuccess";
					Status.Success = true;
				}

			}

			return Status.Success;
		}


		public void Delete() 
		{
			Sections.DeleteSection(this.Section);
		}

		private void AdminGroupList_SelectedIndexChanged(object sender, EventArgs e)
		{
			BindForumList();
		}

		private string GenerateUniqueApplicationKey(string rawKey)
		{
			string candidateKey = string.Empty;
			Globals.ValidateApplicationKey(rawKey, out candidateKey);

			while (!IsUniqueApplicationKey(candidateKey))
			{
				candidateKey = candidateKey + new Random().Next(1, 9).ToString();
			}

			return candidateKey;
		}

		private bool IsUniqueApplicationKey(string key)
		{
			foreach(Forum f in GetForums())
				if(f.ApplicationKey == key)
					return false;

			return true;
		}

	}
}
