using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Xml;
using Orciid.Core;

namespace Orciid
{

	public class collectiondef : PageTemplate.OrciidPage
	{
		protected System.Web.UI.WebControls.Panel DetailPanel;
		protected System.Web.UI.WebControls.TextBox NameBox;
		protected System.Web.UI.WebControls.TextBox LabelBox;
		protected System.Web.UI.WebControls.Button SubmitButton;
		protected System.Web.UI.WebControls.ListBox FieldList;
		protected System.Web.UI.WebControls.Button ModifyButton;
		protected System.Web.UI.WebControls.Button RemoveButton;
		protected System.Web.UI.WebControls.Button CreateNewButton;
		protected System.Web.UI.WebControls.Button MoveButton;
		protected System.Web.UI.WebControls.DropDownList RepositionList;
		protected System.Web.UI.WebControls.DropDownList TypeList;
		protected System.Web.UI.WebControls.DropDownList ControlledListList;
		protected System.Web.UI.WebControls.CheckBox SearchableCheckBox;
		protected System.Web.UI.WebControls.CheckBox KeywordSearchableCheckBox;
		protected System.Web.UI.WebControls.CheckBox SortableCheckBox;
		protected System.Web.UI.WebControls.DropDownList LongViewList;
		protected System.Web.UI.WebControls.DropDownList MediumViewList;
		protected System.Web.UI.WebControls.DropDownList ShortViewList;
		protected System.Web.UI.WebControls.TextBox DCRefinementBox;
		protected System.Web.UI.WebControls.TextBox DCElementBox;
		protected System.Web.UI.WebControls.CheckBox BrowsableCheckBox;
		protected System.Web.UI.WebControls.Label TitleLabel;
		protected System.Web.UI.WebControls.HyperLink PropertiesHyperLink;
		protected System.Web.UI.WebControls.Panel ImportFieldsPanel;
		protected System.Web.UI.WebControls.RadioButton DublinCoreRadioButton;
		protected System.Web.UI.WebControls.RadioButton FromSchemaRadioButton;
		protected System.Web.UI.WebControls.RadioButton FromDataRadioButton;
		protected System.Web.UI.WebControls.RadioButton FromCollectionRadioButton;
		protected System.Web.UI.WebControls.Button GenerateFieldsButton;
		protected System.Web.UI.WebControls.DropDownList CollectionDropDownList;
		protected System.Web.UI.HtmlControls.HtmlInputFile SchemaFileField;
		protected System.Web.UI.HtmlControls.HtmlInputFile DataFileField;

		private int fieldid;
		protected System.Web.UI.HtmlControls.HtmlGenericControl Heading;
		protected System.Web.UI.HtmlControls.HtmlGenericControl AutogenerateFieldsHeading;
		protected System.Web.UI.HtmlControls.HtmlGenericControl FieldDefinitionsHeading;
		protected System.Web.UI.HtmlControls.HtmlGenericControl FieldLabelSpan;
		protected System.Web.UI.HtmlControls.HtmlGenericControl NameLabelSpan;
		protected System.Web.UI.HtmlControls.HtmlGenericControl LabelLabelSpan;
		protected System.Web.UI.HtmlControls.HtmlGenericControl DCElementLabelSpan;
		protected System.Web.UI.HtmlControls.HtmlGenericControl DCRefinementLabelSpan;
		protected System.Web.UI.HtmlControls.HtmlGenericControl TypeLabelSpan;
		protected System.Web.UI.HtmlControls.HtmlGenericControl ControlledListLabelSpan;
		protected System.Web.UI.HtmlControls.HtmlGenericControl ShortViewLabelSpan;
		protected System.Web.UI.HtmlControls.HtmlGenericControl MediumViewLabelSpan;
		protected System.Web.UI.HtmlControls.HtmlGenericControl LongViewLabelSpan;
		private Collection coll;

		private void Page_Load(object sender, System.EventArgs e)
		{
			Orciid.Core.User user = Session["CurrentUser"] as Orciid.Core.User;
			if (user != null)
				user.Activate(Request.UserHostAddress);

			if (!IsPostBack)
			{
				try
				{
					coll = Collection.GetByID(Int32.Parse(Request.QueryString["id"]));
				}
				catch
				{
					coll = null;
				}
				CheckAuthorization();
				TitleLabel.Text = coll.Title;
				PropertiesHyperLink.NavigateUrl = String.Format("collection.aspx?id={0}", coll.ID);
				FillFieldList();
				TypeList.Items.Add(new ListItem(GetLocalString(this, "TextTypeLabel", "Text"), ((int)FieldType.Text).ToString()));
				TypeList.Items.Add(new ListItem(GetLocalString(this, "ExactTextTypeLabel", "Exact Text"), ((int)FieldType.ExactText).ToString()));
				TypeList.Items.Add(new ListItem(GetLocalString(this, "DateTypeLabel", "Date"), ((int)FieldType.Date).ToString()));
				TypeList.Items.Add(new ListItem(GetLocalString(this, "ControlledListTypeLabel", "Controlled List"), ((int)FieldType.ControlledList).ToString()));
				int textentryindex = 
					TypeList.Items.IndexOf(TypeList.Items.FindByValue(((int)FieldType.Text).ToString()));
				int controlledlistentryindex = 
					TypeList.Items.IndexOf(TypeList.Items.FindByValue(((int)FieldType.ControlledList).ToString()));
				TypeList.Attributes["onchange"] = String.Format(
					"if (this.selectedIndex != {0}) ControlledListList.selectedIndex = 0;",
					controlledlistentryindex);
				ShortViewList.Items.Add(new ListItem(GetLocalString(this, "NoneViewLabel", "None"), ((int)DisplayMode.None).ToString()));
				ShortViewList.Items.Add(new ListItem(GetLocalString(this, "AllViewLabel", "All"), ((int)DisplayMode.All).ToString()));
//				ShortViewList.Items.Add(new ListItem("First 20 Characters", ((int)DisplayMode.First20Char).ToString()));
//				ShortViewList.Items.Add(new ListItem("First 50 Characters", ((int)DisplayMode.First50Char).ToString()));
//				ShortViewList.Items.Add(new ListItem("First Sentence", ((int)DisplayMode.FirstParagraph).ToString()));
//				ShortViewList.Items.Add(new ListItem("First Paragraph", ((int)DisplayMode.FirstSentence).ToString()));
				foreach (ListItem item in ShortViewList.Items)
				{
					MediumViewList.Items.Add(new ListItem(item.Text, item.Value));
					LongViewList.Items.Add(new ListItem(item.Text, item.Value));
				}
				ControlledListList.Items.Add(new ListItem("", "0"));
				foreach (ControlledList list in ControlledList.GetControlledLists(coll.ID))
					ControlledListList.Items.Add(new ListItem(list.Title, list.ID.ToString()));
				ControlledListList.Attributes["onchange"] = String.Format(
					"TypeList.selectedIndex = (this.selectedIndex > 0 ? {0} : {1});",
					controlledlistentryindex, textentryindex);
				foreach (Collection c in Collection.GetCollections(CollectionType.Internal))
				{
					Field[] fields = c.GetFields();
					if (c.ID != coll.ID && fields != null && fields.Length > 0)
						CollectionDropDownList.Items.Add(new ListItem(c.Title, c.ID.ToString()));
				}
			}
			RemoveButton.Attributes["onclick"] = "return confirm('Are you sure you want to remove this field?  Any data associated with this field will be lost.');";
		}

		private void CheckAuthorization()
		{
			Privilege[] privs = new Privilege[] { 
				Privilege.DeleteCollection, Privilege.ManageCollection,
				Privilege.ModifyACL, Privilege.ManageControlledLists,
				Privilege.ModifyImages };
			bool authorized = false;
			if (coll != null)
			{
				foreach (Privilege p in privs)
					if (Orciid.Core.User.HasPrivilege(p, coll))
					{
						authorized = true;
						break;
					}
			}
			if (!authorized)
				Response.Redirect("insufficientprivileges.aspx"); 
		}

		protected override void LoadViewState(object savedState) 
		{
			if (savedState != null)
			{
				base.LoadViewState(savedState);
				if (ViewState["EditingFieldID"] is Int32)
					fieldid = (int)ViewState["EditingFieldID"];
				if (ViewState["CollectionID"] is Int32)
					coll = Collection.GetByID((int)ViewState["CollectionID"]);
				CheckAuthorization();
			}
		}

		protected override object SaveViewState()
		{
			ViewState["EditingFieldID"] = fieldid;
			if (coll != null)
				ViewState["CollectionID"] = coll.ID;
			return base.SaveViewState();
		}

		private void FillFieldList()
		{
			FieldList.Items.Clear();
			RepositionList.Items.Clear();
			foreach (Field field in coll.GetFields())
			{
				FieldList.Items.Add(new ListItem(field.Name, field.ID.ToString()));
				RepositionList.Items.Add(new ListItem(GetLocalString(this, "BeforeLabel", "before") + " " + field.Name, field.ID.ToString()));
			}
			RepositionList.Items.Add(new ListItem(GetLocalString(this, "LastFieldLabel", "as last field"), "0"));
			DetailPanel.Visible = false;
		}

		#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.GenerateFieldsButton.Click += new System.EventHandler(this.GenerateFieldsButton_Click);
			this.ModifyButton.Click += new System.EventHandler(this.ModifyButton_Click);
			this.RemoveButton.Click += new System.EventHandler(this.RemoveButton_Click);
			this.CreateNewButton.Click += new System.EventHandler(this.CreateNewButton_Click);
			this.MoveButton.Click += new System.EventHandler(this.MoveButton_Click);
			this.SubmitButton.Click += new System.EventHandler(this.SubmitButton_Click);
			this.Load += new System.EventHandler(this.Page_Load);
			this.PreRender += new System.EventHandler(this.collectiondef_PreRender);

		}
		#endregion

//		private void CollectionList_SelectedIndexChanged(object sender, System.EventArgs e)
//		{
//			FillFieldList();
//		}

		private void SubmitButton_Click(object sender, System.EventArgs e)
		{
			if (!IsValid)
				return;
			Field field;
			if (fieldid == 0)
			{
				field = new Field();
			}
			else
			{
				field = coll.GetField(fieldid);
			}
			field.Name = NameBox.Text;
			field.Label = LabelBox.Text;
			field.DCElement = DCElementBox.Text;
			field.DCRefinement = DCRefinementBox.Text;
			field.Type = (FieldType)Int32.Parse(TypeList.SelectedItem.Value);
			field.ControlledListID = Int32.Parse(ControlledListList.SelectedItem.Value);
			field.Searchable = SearchableCheckBox.Checked;
			field.KeywordSearchable = KeywordSearchableCheckBox.Checked;
			field.Sortable = SortableCheckBox.Checked;
			field.Browsable = BrowsableCheckBox.Checked;
			field.ShortView = (DisplayMode)Int32.Parse(ShortViewList.SelectedItem.Value);
			field.MediumView = (DisplayMode)Int32.Parse(MediumViewList.SelectedItem.Value);
			field.LongView = (DisplayMode)Int32.Parse(LongViewList.SelectedItem.Value);
			if (fieldid == 0)
			{
				coll.AddField(field);
				coll.Update();
			}
			else
			{
				field.Update();
			}
			FillFieldList();
		}

		private void ModifyButton_Click(object sender, System.EventArgs e)
		{
			if (FieldList.SelectedItem != null)
			{
				DetailPanel.Visible = true;
				fieldid = Int32.Parse(FieldList.SelectedItem.Value);
				Field field = coll.GetField(fieldid);
				NameBox.Text = field.Name;
				LabelBox.Text = field.Label;
				DCElementBox.Text = field.DCElement;
				DCRefinementBox.Text = field.DCRefinement;
				TypeList.SelectedIndex = TypeList.Items.IndexOf(TypeList.Items.FindByValue(((int)field.Type).ToString()));
				ControlledListList.SelectedIndex = ControlledListList.Items.IndexOf(ControlledListList.Items.FindByValue(field.ControlledListID.ToString()));
				SearchableCheckBox.Checked = field.Searchable;
				KeywordSearchableCheckBox.Checked = field.KeywordSearchable;
				SortableCheckBox.Checked = field.Sortable;
				BrowsableCheckBox.Checked = field.Browsable;
				ShortViewList.SelectedIndex = ShortViewList.Items.IndexOf(ShortViewList.Items.FindByValue(((int)field.ShortView).ToString()));
				MediumViewList.SelectedIndex = MediumViewList.Items.IndexOf(MediumViewList.Items.FindByValue(((int)field.MediumView).ToString()));
				LongViewList.SelectedIndex = LongViewList.Items.IndexOf(LongViewList.Items.FindByValue(((int)field.LongView).ToString()));
			}
		}

		private void RemoveButton_Click(object sender, System.EventArgs e)
		{
			if (FieldList.SelectedItem != null)
			{
				Field field = coll.GetField(Int32.Parse(FieldList.SelectedItem.Value));
				coll.RemoveField(field);
				FillFieldList();
			}
		}

		private void CreateNewButton_Click(object sender, System.EventArgs e)
		{
			DetailPanel.Visible = true;
			fieldid = 0;
			NameBox.Text = "";
			LabelBox.Text = "";
			DCElementBox.Text = "";
			DCRefinementBox.Text = "";
			TypeList.SelectedIndex = 0;
			ControlledListList.SelectedIndex = 0;
			SearchableCheckBox.Checked = true;
			KeywordSearchableCheckBox.Checked = true;
			SortableCheckBox.Checked = true;
			BrowsableCheckBox.Checked = true;
			ShortViewList.SelectedIndex = 1;
			MediumViewList.SelectedIndex = 1;
			LongViewList.SelectedIndex = 1;
		}

		private void MoveButton_Click(object sender, System.EventArgs e)
		{
			if (FieldList.SelectedItem != null)
			{
				Field field = coll.GetField(Int32.Parse(FieldList.SelectedItem.Value));
				int beforeid = Int32.Parse(RepositionList.SelectedItem.Value);
				if (beforeid != field.ID)
				{
					Field before = (beforeid == 0 ? null : coll.GetField(beforeid));
					coll.MoveField(field, before);
					coll.Update();
					FillFieldList();
				}
			}
		}

		public override string GetHighlightedMenuItem()
		{
			return "Collection_Manage";
		}

		protected override bool CheckUserPrivileges(Orciid.Core.User user)
		{
			return Orciid.Core.User.HasPrivilege(Privilege.CreateCollection, user) ||
				Orciid.Core.User.HasPrivilegeOnAny('C', user, 
				Privilege.ManageCollection, Privilege.DeleteCollection);
		}

		private void collectiondef_PreRender(object sender, System.EventArgs e)
		{
			ImportFieldsPanel.Visible = (FieldList.Items.Count == 0);
		}

		private void GenerateFieldsButton_Click(object sender, System.EventArgs e)
		{
			if (DublinCoreRadioButton.Checked)
			{
				coll.CreateDublinCoreFields();
			}
			else if (FromSchemaRadioButton.Checked)
			{
				if (SchemaFileField.PostedFile != null &&
					SchemaFileField.PostedFile.InputStream != null &&
					SchemaFileField.PostedFile.InputStream.Length > 0)
				{
					Field[] fields = DataExchange.GetFieldsFromSchema(
						new XmlTextReader(SchemaFileField.PostedFile.InputStream));
					if (fields != null)
					{
						foreach (Field f in fields)
							coll.AddField(f);
					}
					else
					{
						ShowError("Could not read fields from schema file.");
					}
				}
			}
			else if (FromDataRadioButton.Checked)
			{
				if (DataFileField.PostedFile != null &&
					DataFileField.PostedFile.InputStream != null &&
					DataFileField.PostedFile.InputStream.Length > 0)
				{
					Field[] fields = DataExchange.GetFieldsFromData(
						new XmlTextReader(DataFileField.PostedFile.InputStream));
					if (fields != null)
					{
						foreach (Field f in fields)
							coll.AddField(f);
					}
					else
					{
						ShowError("Could not read fields from data file.");
					}
				}
			}
			else if (FromCollectionRadioButton.Checked)
			{
				try
				{
					CopyFieldsFromCollection(
						Collection.GetByID(Int32.Parse(CollectionDropDownList.SelectedValue)));
				}
				catch
				{
					ShowError("Could not copy fields from source collection.");
				}
			}
			FillFieldList();
		}

		private void CopyFieldsFromCollection(Collection sourcecoll)
		{
			// FogBugz case 552: copy controlled lists?
			foreach (Field f in sourcecoll.GetFields())
			{
				Field field = new Field();
				field.Browsable = f.Browsable;
				field.DCElement = f.DCElement;
				field.DCRefinement = f.DCRefinement;
				field.KeywordSearchable = f.KeywordSearchable;
				field.Label = f.Label;
				field.LongView = f.LongView;
				field.MediumView = f.MediumView;
				field.Name = f.Name;
				field.Searchable = f.Searchable;
				field.ShortView = f.ShortView;
				field.Sortable = f.Sortable;
				field.Type = (f.Type != FieldType.ControlledList ? f.Type : FieldType.Text);
				coll.AddField(field);
			}
		}
	}
}
