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

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

namespace CommunityServer.Controls
{
	/// <summary>
	/// Summary description for PollItemEditor.
	/// </summary>
	public class PollEditor : TemplatedWebControl
	{
		#region Child Controls
		
		protected HtmlGenericControl ContentContainer;
		protected TextBox NewAnswer;
		protected IButton AddButton;
		protected CallbackInputHidden AnswerInformation;
		protected Repeater PollAnswerRepeater;
		protected TextBox PollTitle, ExpireAfterDays;
		protected Editor PollDescription;
		protected PlaceHolder Content;
		protected CustomValidator AnswerValidator, PollTitleValidator, ExpireAfterDaysValidator;

		#endregion
		
		#region Skin

		protected override void AttachChildControls() 
		{
			ContentContainer = (HtmlGenericControl) FindControl("ContentContainer");
			NewAnswer = (TextBox) FindControl("NewAnswer");
			AddButton = FindButton("AddButton");
			AnswerInformation = (CallbackInputHidden) FindControl("AnswerInformation");
			PollAnswerRepeater = (Repeater) FindControl("PollAnswerRepeater");
			PollTitle = (TextBox) FindControl("PollTitle");
			PollDescription = (Editor) FindControl("PollDescription");
			ExpireAfterDays = (TextBox) FindControl("ExpireAfterDays");
			Content = (PlaceHolder) FindControl("Content");
			AnswerValidator = (CustomValidator) FindControl("AnswerValidator");
			PollTitleValidator = (CustomValidator) FindControl("PollTitleValidator");
			ExpireAfterDaysValidator = (CustomValidator) FindControl("ExpireAfterDaysValidator");

			PollAnswerRepeater.ItemDataBound += new RepeaterItemEventHandler(PollAnswerRepeater_ItemDataBound);
			AddButton.CausesValidation = false;
			AddButton.Attributes.Add("onclick", "AddPollItem(); return false;");
			AddButton.Text = ResourceManager.GetString("Add");
		}

		#endregion

		#region Properties

		Post _post = null;
		public Post Post
		{
			get
			{
				return _post;
			}
			set
			{
				_post = value;
			}
		}

		#endregion

		#region Control Event Handlers

		protected override void OnLoad(EventArgs e)
		{
			base.OnLoad(e);
			AjaxManager.Register(this, "PollEditorAjax");

			EnsureChildControls();
		}

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

			string javascript = @"<script language=""JavaScript"">
			var pollIsProcessing = false;
			function RefreshPollContent(result)
			{{
				if (result.error)
					alert(result.error);
				else
					document.getElementById('{0}').innerHTML = result.value;
				
				document.getElementById('{0}').style.cursor = 'auto';
				pollIsProcessing = false;
			}}
			function DeletePollItem(id) {{ if (CanProcess()) {{ if (window.confirm('{3}')) {{ PollEditorAjax.UpdatePollAnswers('{2}', 'Delete:' + id, RefreshPollContent); }} else {{ pollIsProcessing = false ; }} }} }}
			function AddPollItem() {{ if (document.getElementById('{1}').value != '' && CanProcess()) {{ PollEditorAjax.UpdatePollAnswers('{2}', 'Add:', RefreshPollContent); document.getElementById('{1}').value = ''; }} }}
			function MovePollItemUp(id)	{{ if (CanProcess()) {{ PollEditorAjax.UpdatePollAnswers('{2}', 'MoveUp:' + id, RefreshPollContent); }} }}
			function MovePollItemDown(id) {{ if (CanProcess()) {{ PollEditorAjax.UpdatePollAnswers('{2}', 'MoveDown:' + id, RefreshPollContent); }} }}
			function CanProcess() {{ if (pollIsProcessing) {{ return false; }} document.getElementById('{0}').style.cursor = 'progress'; pollIsProcessing = true; return true; }}
			</script>";

			if (!Page.IsClientScriptBlockRegistered(this.GetType().FullName))
				Page.RegisterClientScriptBlock(this.GetType().FullName, String.Format(javascript, this.ContentContainer.ClientID, this.NewAnswer.ClientID, this.ClientID, ResourceManager.GetString("PollEditor_DeleteAnswerConfirmation")));
		}

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

			if (Post != null && !Page.IsPostBack)
			{
				if (PollTitle != null)
					PollTitle.Text = Page.Server.HtmlDecode(Post.PollTitle);

				if (PollDescription != null)
					PollDescription.Text = Post.PollDescription;

				if (ExpireAfterDays != null && Post.PollExpirationDate != DateTime.MinValue)
				{
					if (Post.PollExpirationDate > DateTime.Today)
						ExpireAfterDays.Text = Post.PollExpirationDate.Subtract(DateTime.Today).Days.ToString();
					else
						ExpireAfterDays.Text = "0";
				}
			}				

		    ArrayList items = GetPollItems();
			if (items.Count > 0)
			{
				PollAnswerRepeater.DataSource = items;
				PollAnswerRepeater.DataBind();
			}
			else if (!AjaxManager.IsCallBack)
			{
				Content.Controls.Add(new LiteralControl(ResourceManager.GetString("PollEditor_NoAnswers")));
			}
		}

		private void PollAnswerRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
		{
			PollItemContainer item = e.Item.DataItem as PollItemContainer;
			switch( e.Item.ItemType ) 
			{
				case ListItemType.Item:
				case ListItemType.AlternatingItem:

					if (e.Item.ItemIndex == 0)
						AnswerInformation.Value = "";
					
					CallbackInputText answer = (CallbackInputText) e.Item.FindControl("Answer");
					HtmlControl moveUp = (HtmlControl) e.Item.FindControl("MoveUpButton");
					HtmlControl moveDown = (HtmlControl) e.Item.FindControl("MoveDownButton");
					HtmlControl delete = (HtmlControl) e.Item.FindControl("DeleteButton");

					answer.Value = Page.Server.HtmlDecode(item.PollItem.Answer);
	
					moveUp.Attributes.Add("onclick", "MovePollItemUp('" + answer.UniqueID + "'); return false;");
					moveDown.Attributes.Add("onclick", "MovePollItemDown('" + answer.UniqueID + "'); return false;");
					delete.Attributes.Add("onclick", "DeletePollItem('" + answer.UniqueID + "'); return false;");				
					
					if (AnswerInformation.Value.Length > 0)
						AnswerInformation.Value += ",";

					AnswerInformation.Value += item.PollItem.AnswerID + ":" + answer.UniqueID;

					break;
			}
		}

		#endregion

		#region Ajax Methods

		[AjaxMethod(IncludeControlValuesWithCallBack=true)]
		public string UpdatePollAnswers(string parameter)
		{
			EnsureChildControls();

			string[] message = parameter.Split(new char[] {':'}, 2);
			ArrayList items = GetPollItems();
			switch (message[0])
			{
				case "Add":
					
					items.Add(new PollItemContainer(new PollItem(Page.Server.HtmlEncode(NewAnswer.Text)), String.Empty));

					break;

				case "MoveUp":

					for (int i = 0; i < items.Count; i++)
					{
						if (((PollItemContainer) items[i]).ClientID == message[1])
						{
							if (i > 0)
							{
								Object temp = items[i - 1];
								items[i - 1] = items[i];
								items[i] = temp;
								break;
							}
						}
					}

					break;

				case "MoveDown":

					for (int i = 0; i < items.Count; i++)
					{
						if (((PollItemContainer) items[i]).ClientID == message[1])
						{
							if (i < items.Count - 1)
							{
								Object temp = items[i + 1];
								items[i + 1] = items[i];
								items[i] = temp;
								break;
							}
						}
					}

					break;

				case "Delete":

					ArrayList newItems = new ArrayList();
					foreach (PollItemContainer pi in items)
					{
						if (pi.ClientID != message[1])
							newItems.Add(pi);
					}

					items = newItems;

					break;
			}

			if (items.Count > 0)
			{
				AnswerInformation.Value = "";
				PollAnswerRepeater.DataSource = items;
				PollAnswerRepeater.DataBind();
			
			    StringWriter stringWriter = new StringWriter();
				HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter);
				Content.RenderControl(htmlWriter);

				return stringWriter.ToString();
			}
			else
			{
				return ResourceManager.GetString("PollEditor_NoAnswers");
			}
		}

		#endregion

		#region Helper Methods

		protected ArrayList GetPollItems()
		{
			ArrayList items = new ArrayList();

			if (Page.IsPostBack)
			{
				string answerInformation = Page.Request.Form[AnswerInformation.UniqueID];
				if (answerInformation != null && answerInformation != String.Empty)
				{
					string[] ids = answerInformation.Split(',');
					foreach (string id in ids)
					{
						string[] idValues = id.Split(new char[] {':'}, 2);
						items.Add(new PollItemContainer(new PollItem(idValues[0], Page.Server.HtmlEncode(Page.Request.Form[idValues[1]]), 0), idValues[1]));
					}
				}
			}
			else if (Post != null && Post.HasPoll)
			{
				foreach(PollItem item in Post.GetPollItems())
				{
					items.Add(new PollItemContainer(item, String.Empty));
				}
			}

			return items;
		}

		class PollItemContainer
		{
			public PollItem PollItem;
			public string ClientID;

			public PollItemContainer(PollItem item, string clientID)
			{
				PollItem = item;
				ClientID = clientID;
			}
		}

		private bool IsValidExpireAfterDays(string value)
		{
			int days;
			try
			{
				days = int.Parse(value);
			}
			catch
			{
				return false;
			}

			return days >= 0;
		}

		#endregion

		#region Public Methods

		public bool IsValid
		{
			get
			{
				EnsureChildControls();

				if (GetPollItems().Count == 0 && AnswerValidator != null)
				{
					AnswerValidator.IsValid = false;
					return false;
				}
				else if (PollTitleValidator != null && PollTitle != null && PollTitle.Text.Trim() == String.Empty)
				{
					PollTitleValidator.IsValid = false;
					return false;
				}
				else if (ExpireAfterDaysValidator != null && ExpireAfterDays != null && ExpireAfterDays.Text.Trim() != String.Empty && !IsValidExpireAfterDays(ExpireAfterDays.Text))
				{
					ExpireAfterDaysValidator.IsValid = false;
					return false;
				}
				else
					return Page.IsValid;
			}
		}

		public void SavePollItemsToPost()
		{
			if (PollTitle != null)
				Post.PollTitle = Page.Server.HtmlEncode(PollTitle.Text);

			if (PollDescription != null)
				Post.PollDescription = PollDescription.Text;

			if (ExpireAfterDays != null && ExpireAfterDays.Text.Trim() != String.Empty)
				Post.PollExpirationDate = DateTime.Today.AddDays(int.Parse(ExpireAfterDays.Text));
			else
				Post.PollExpirationDate = DateTime.MinValue;

			ArrayList existingItems = Post.GetPollItems();
			int i = 0;
			foreach (PollItemContainer pic in GetPollItems())
			{
				pic.PollItem.OrderNumber = i;
				i++;

				if (pic.PollItem.AnswerID == String.Empty)
					Post.AddPollItem(pic.PollItem);
				else
				{
					Post.UpdatePollItem(pic.PollItem);

					for (int j = 0; j < existingItems.Count; j++)
					{
						if (((PollItem) existingItems[j]).AnswerID == pic.PollItem.AnswerID)
						{
							existingItems.RemoveAt(j);
							break;
						}
					}
				}
			}

			foreach (PollItem item in existingItems)
			{
				Post.RemovePollItem(item);
			}
		}

		#endregion
	}
}
