using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Web.UI;
using System.Web.UI.WebControls;
using DebriefingSoftware.Common;
using DebriefingSoftware.Common.Business.Filtering;
using Telerik.Web.UI;

namespace B4Restore.Common.Control
{
	[ToolboxData("<{0}:FilterHolder runat=server></{0}:FilterHolder>")]
	public class FilterHolder : PlaceHolder
	{
		public FilterHolder()
		{
			this.Group = string.Empty;
			this.OperationGroup = string.Empty;
			this.BinaryOperationGroup = string.Empty;
			this.FieldName = string.Empty;
		}

		[PersistenceMode(PersistenceMode.Attribute)]
		public CaseSensitivity CaseSensitive { get; set; }

		[PersistenceMode(PersistenceMode.Attribute)]
		public SqlOperationType OperationType { get; set; }

		[PersistenceMode(PersistenceMode.Attribute)]
		public SqlDataType DataType { get; set; }

		private string _group;

		[PersistenceMode(PersistenceMode.Attribute)]
		public string Group { get { return _group; } set { _group = value.ToLower(); } }

		private string _operationGroup;

		[PersistenceMode(PersistenceMode.Attribute)]
		public string OperationGroup { get { return _operationGroup; } set { _operationGroup = value.ToLower(); } }

		private string _binaryOperationGroup;

		[PersistenceMode(PersistenceMode.Attribute)]
		public string BinaryOperationGroup { get { return _binaryOperationGroup; } set { _binaryOperationGroup = value.ToLower(); } }

		[PersistenceMode(PersistenceMode.Attribute)]
		public BinaryOperationDirection BinaryOperationArgument { get; set; }

		private string _fieldName;

		[PersistenceMode(PersistenceMode.Attribute)]
		public string FieldName { get { return _fieldName; } set { _fieldName = value.ToLower(); } }

		public string[] GetFilterValues()
		{
			var result = new List<string>();

			if (Controls.Count > 0)
			{
				var filterControl = Controls[0];

				if (filterControl is RadTimePicker)
				{
					var radTimePicker = filterControl as RadTimePicker;
					if (radTimePicker.SelectedDate.HasValue)
					{
						result.Add(radTimePicker.SelectedDate.Value.ToString("yyyy-MM-dd-HH.mm.ss.000000"));
					}
				}
				else if (filterControl is RadDateTimePicker)
				{
					var radDateTimePicker = filterControl as RadDateTimePicker;
					if (radDateTimePicker.SelectedDate.HasValue)
					{
						result.Add(radDateTimePicker.SelectedDate.Value.ToString("yyyy-MM-dd-HH.mm.ss.000000"));
					}
				}
				else if (filterControl is RadDatePicker)
				{
					var radDatePicker = filterControl as RadDatePicker;
					if (radDatePicker.SelectedDate.HasValue)
					{
						result.Add(radDatePicker.SelectedDate.Value.ToString("yyyy-MM-dd-HH.mm.ss.000000"));
					}
				}
				else if (filterControl is ListBox)
				{
					var listBox = filterControl as ListBox;
					result.AddRange(from ListItem listItem in listBox.Items where listItem.Selected && !string.IsNullOrEmpty(listItem.Value) select listItem.Value);
				}
				else if (filterControl is DropDownList)
				{
					var dropDownList = filterControl as DropDownList;
					if (!string.IsNullOrEmpty(dropDownList.SelectedValue))
					{
						result.Add(dropDownList.SelectedValue);
					}
				}
				else if (filterControl is CheckBox)
				{
					var checkBox = filterControl as CheckBox;
					result.Add(checkBox.Checked ? "1" : "0");
				}
				else if (filterControl is RadioButtonList)
				{
					var radioButtonList = filterControl as RadioButtonList;
					if (!string.IsNullOrEmpty(radioButtonList.SelectedValue))
					{
						result.Add(radioButtonList.SelectedValue);
					}
				}
				else if (filterControl is TextBox)
				{
					var textBox = filterControl as TextBox;
					if (!string.IsNullOrEmpty(textBox.Text))
					{
						result.Add(textBox.Text);
					}
				}
				else
				{
					throw new ApplicationException("Unsupported control in filter holder!");
				}
			}

			return result.ToArray();
		}

		public void SetFilterValues(string[] values)
		{
			if (Controls.Count > 0 && values.Length > 0)
			{
				var filterControl = Controls[0];

				if (filterControl is RadTimePicker)
				{
					var radTimePicker = filterControl as RadTimePicker;
					var value = values[0];
					var parsedValue = Parser.ParseNullableDateTime(value);
					if (parsedValue != null)
					{
						radTimePicker.SelectedDate = parsedValue;
					}
				}
				else if (filterControl is RadDateTimePicker)
				{
					var radDateTimePicker = filterControl as RadDateTimePicker;
					var value = values[0];
					var parsedValue = Parser.ParseNullableDateTime(value);
					if (parsedValue != null)
					{
						radDateTimePicker.SelectedDate = parsedValue;
					}
				}
				else if (filterControl is RadDatePicker)
				{
					var radDatePicker = filterControl as RadDatePicker;
					var value = values[0];
					var parsedValue = Parser.ParseNullableDateTime(value);
					if (parsedValue != null)
					{
						radDatePicker.SelectedDate = parsedValue;
					}
				}
				else if (filterControl is ListBox)
				{
					var listBox = filterControl as ListBox;
					foreach (var value in values)
					{
						var selectedItem = listBox.Items.FindByValue(value);
						if (selectedItem != null)
						{
							selectedItem.Selected = true;
						}
					}
				}
				else if (filterControl is DropDownList)
				{
					var dropDownList = filterControl as DropDownList;
					var value = values[0];
					var selectedItem = dropDownList.Items.FindByValue(value);
					if (selectedItem != null)
					{
						selectedItem.Selected = true;
					}
				}
				else if (filterControl is CheckBox)
				{
					var checkBox = filterControl as CheckBox;
					var value = values[0];
					var parsedValue = Parser.ParseNullableBool(value);
					if (parsedValue != null)
					{
						checkBox.Checked = parsedValue.Value;
					}
				}
				else if (filterControl is RadioButtonList)
				{
					var radioButtonList = filterControl as RadioButtonList;
					var value = values[0];
					var selectedItem = radioButtonList.Items.FindByValue(value);
					if (selectedItem != null)
					{
						selectedItem.Selected = true;
					}
				}
				else if (filterControl is TextBox)
				{
					var textBox = filterControl as TextBox;
					var value = values[0];
					textBox.Text = value;
				}
				else
				{
					throw new ApplicationException("Unsupported control in filter holder!");
				}
			}
		}

		protected override void OnPreRender(EventArgs e)
		{
			base.OnPreRender(e);
			var filterParameter = GetFilterParameter();

			var scriptKey = "jsFilterParameters";
			var scriptBlock = new StringBuilder("var filterParameters = [];");

			Page.ClientScript.RegisterClientScriptBlock(GetType(), scriptKey, scriptBlock.ToString(), true);
			// Every filterHolder web control has corresponding javascript filter parameter object, that contains field names, field values, data type, control type, etc...
			// javascript filter parameter object is 1:1 FilterParameter server object (see Common Business -> Filtering -> FilterParameter)
			scriptKey = "jsFilterHolder" + UniqueID;
			scriptBlock.AppendLine("filterParameters['" + UniqueID + @"'] = " + filterParameter.GetJsonString() + @";");

			Page.ClientScript.RegisterClientScriptBlock(GetType(), scriptKey, scriptBlock.ToString(), true);
		}

		//FilterHolder contains visual presentation of Filter Parameter. When we want to get json, query string of current filters - we work with FilterParameters and need to 
		// obtain them from FilterHolders.
		// [FilterHolder ...filter parameter attributes...]Web Control[/FilterHolder] => FilterParameter
		public FilterParameter GetFilterParameter()
		{
			var result = new FilterParameter();

			if (this.Controls.Count == 0)
			{
				throw new ApplicationException("Filter control required!");
			}
			result.CaseSensitive = this.CaseSensitive;
			result.OperationType = this.OperationType;
			result.DataType = this.DataType;
			result.Group = this.Group;
			result.OperationGroup = this.OperationGroup;
			result.BinaryOperationGroup = this.BinaryOperationGroup;
			result.BinaryOperationArgument = this.BinaryOperationArgument;
			result.FieldName = this.FieldName;
			result.FieldValues = this.GetFilterValues();
			result.ControlType = (FilterControlType)Enum.Parse(typeof(FilterControlType), this.Controls[0].GetType().Name);
			result.ControlClientID = this.Controls[0].ClientID;

			return result;
		}
	}
}
