namespace Orciid.UserControls
{
	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 System.Collections;
	using System.Text.RegularExpressions;
	using Orciid.Core;

	[Serializable]
	public struct CollectionSelectionEntry
	{
		public int CollectionID;
		public bool Selected;
	}

	public class CollectionSelection : System.Web.UI.UserControl
	{

		private CollectionSelectionEntry[] datasource = null;
		private bool autopostback = false;

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

		protected override void CreateChildControls()
		{
			base.CreateChildControls();
			CreateControls();
		}

		#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.Load += new System.EventHandler(this.Page_Load);
		}
		#endregion

		private class CollectionComparer: IComparer
		{
			public int Compare(object x, object y)
			{
				return String.CompareOrdinal(x as string, y as string);
			}
		}
		
		private void CreateControls()
		{
			Controls.Clear();
			if (datasource == null)
				return;

			Control page = this.Parent;
			while (page != null && !(page is Page))
				page = page.Parent;
			if (page == null)
				return;

			if (!((Page)page).IsClientScriptBlockRegistered("CollectionSelection"))
				((Page)page).RegisterClientScriptBlock("CollectionSelection", 
				"<script language='JavaScript' type='text/javascript' src='" +
				page.ResolveUrl("UserControls/CollectionSelection.js") + "'></script>");

			Orciid.Core.User user = Orciid.Core.User.CurrentUser();
			Properties props = Properties.GetProperties(user);
			string[] hidecollections = (props != null ? 
				props.Get("uihidecolls", "").Split(new char[] {','}) :
				new string[0]);
			
			SortedList entries = new SortedList(new CollectionComparer());
			foreach (CollectionSelectionEntry e in datasource)
			{
				string cid = e.CollectionID.ToString();
				foreach (string s in hidecollections)
					if (s == cid)
						goto NextEntry;
						
				Collection coll = Collection.GetByID(e.CollectionID);
				string grouptitle = "";
				if (coll.Group != 0)
				{
					CollectionGroup group = CollectionGroup.GetByID(coll.Group);
					if (group != null)
					{
						grouptitle = group.Title + '\0';
						if (!entries.ContainsKey(grouptitle))
							entries.Add(grouptitle, group.ID);
					}
				}
				string title = grouptitle + coll.Title;
				if (entries.ContainsKey(title)) // in case two collections have the same title
					entries.Add(String.Format("{0} [{1}]", title, coll.ID), coll.ID);
				else
					entries.Add(title, coll.ID);
				
			NextEntry: ;
			}

			int currentgroup = 0;
			int lastgroup = 0;
			foreach (string entry in entries.Keys)
			{
				int nc = entry.IndexOf("\0");
				string group = (nc > -1 ? entry.Substring(0, nc) : "");
				string collection = (nc > -1 ? entry.Substring(nc + 1) : entry);
				System.Web.UI.WebControls.Image image = new System.Web.UI.WebControls.Image();
				image.Height = 9;
				image.Width = 9;
				image.ImageAlign = ImageAlign.Baseline;
				CheckBox checkbox = new CheckBox();
				checkbox.Text = (collection.Length == 0 ? group : collection);				
				if (collection.Length == 0)
				{
					currentgroup = (int)entries[entry];
					image.ImageUrl = page.ResolveUrl("images/treenodeminus.gif");
					image.Style.Add("cursor", "pointer");
					image.Attributes.Add("onclick", "CollectionSelection_ToggleTree(this);");
					image.ID = "I" + currentgroup.ToString();
					checkbox.Style.Add("font-style", "italic");
					checkbox.ID = "G" + currentgroup.ToString();
					checkbox.Attributes["onclick"] = "CollectionSelection_ToggleGroup(this);" +
						(autopostback ?	((Page)page).GetPostBackEventReference(this) : "");
				}
				else
				{
					checkbox.CheckedChanged += new EventHandler(CheckBox_CheckedChanged);
					int collid = (int)entries[entry];
					foreach (CollectionSelectionEntry e in datasource)
						if (e.CollectionID == collid)
						{
							checkbox.Checked = e.Selected;
							break;
						}
					image.ImageUrl = page.ResolveUrl("images/spacer.gif");
					if (group.Length > 0)
					{
						image.Width = 35;
						checkbox.Attributes["onclick"] = "CollectionSelection_ToggleCollection(this);" +
							(autopostback ?	((Page)page).GetPostBackEventReference(this) : "");
					}
					else
					{
						currentgroup = 0;
						if (autopostback)
							checkbox.Attributes["onclick"] = ((Page)page).GetPostBackEventReference(this);
					}
					checkbox.ID = "G" + currentgroup.ToString() + "C" + entries[entry].ToString();
				}
				if (currentgroup != lastgroup)
				{
					if (lastgroup != 0)
						Controls.Add(new LiteralControl("</span>"));
					lastgroup = currentgroup;
				}
				Controls.Add(image);
				Controls.Add(checkbox);
				Controls.Add(new LiteralControl("<br />\n"));
				if (collection.Length == 0)
					Controls.Add(new LiteralControl("<span id='" + checkbox.ClientID + "__cs_span'>"));
			}
			if (lastgroup != 0)
				Controls.Add(new LiteralControl("</span>"));
			HtmlInputHidden hidden = new HtmlInputHidden();
			hidden.ID = "keepopen";
			Controls.Add(hidden);
			Controls.Add(new LiteralControl("<script language='JavaScript' type='text/javascript'>CollectionSelection_Initialize();</script>"));
		}

		public CollectionSelectionEntry[] DataSource
		{
			set
			{
				datasource = value;
			}
			get
			{
				return datasource;
			}
		}

		public bool AutoPostBack
		{
			get
			{
				return autopostback;
			}
			set
			{
				autopostback = value;
			}
		}

		public override void DataBind()
		{
			CreateControls();
		}

		public int[] GetSelection()
		{
			ArrayList a = new ArrayList();
			Regex regex = new Regex(@"G\d+C(\d+)$");
			foreach (Control c in Controls)
				if (c is CheckBox && ((CheckBox)c).Checked && regex.IsMatch(c.ID))
					a.Add(Int32.Parse(c.ID.Substring(c.ID.LastIndexOf("C") + 1)));
			return (a.Count > 0 ? (int[])a.ToArray(typeof(int)) : null);
		}

		protected override void LoadViewState(object savedState)
		{
			base.LoadViewState(savedState);
			datasource = ViewState["datasource"] as CollectionSelectionEntry[];
		}

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

		public event System.EventHandler OnSelectionChange;

		private void CheckBox_CheckedChanged(object sender, System.EventArgs e)
		{
			if (OnSelectionChange != null)
			{
				OnSelectionChange(this, null);
			}
		}
	}
}
