using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using Infragistics.Win.Misc;
using Infragistics.Win.UltraWinGrid;
using Medivators.BusinessObjects;
using Medivators.Common;
using Medivators.Common.Enums;
using Medivators.Data;
using Medivators.Data.Queries;

namespace Medivators.Reporting
{
	public partial class frmLogs : frmBase
	{
		private bool _loading = true;
		private bool _gridHasData = false;

		private Dictionary<string, string>  _filterCriteria = null;
		private string[]					_gridColumnWidths = null;

		private delegate void UpdateDisplay();
		private delegate void ClearCursor();
		
		private SelectLogRecordsByFilterList _query = null;
		private List<IBusinessObject> _pendingData = null;
		private List<LogDisplayRecord> _displayData = null;

		#region construct/dispose/load

		public frmLogs()
		{
			InitializeComponent();
			_query = new SelectLogRecordsByFilterList();
			_query.SelectComplete += new SelectCompleteEventHandler(query_SelectComplete);
			_query.DataException  += new DataExceptionEventHandler(query_DataException);

			//	no sense in allowing the button that opens
			//	this form to be used
			btnLogs.BackColor = Color.Black;
			btnLogs.BackColorLight = Color.Green;
			btnLogs.Enabled = false;
			textLogs.Enabled = false;
		}
		public override void Dispose()
		{
			if (_query != null)
			{
				_query.DataException -= this.query_DataException;
				_query.SelectComplete -= this.query_SelectComplete;
				_query.Dispose();
			}
			if (_pendingData != null)
				_pendingData.Clear();
			base.Dispose();
		}
		private void frmLogs_Load(object sender, EventArgs e)
		{
			_loading = true;
			this.filterSelector.SelectorsLoad();
			_loading = false;
		}

		#endregion

		public override Enums.Forms FormType
		{
			get { return Enums.Forms.Logs; }
		}

		#region getting data

		private void query_SelectComplete(object sender, SelectCompleteEventArgs e)
		{
			this.Invoke(new ClearCursor(this.StopWaiting));
			List<IBusinessObject> list = DataMapCaster.Cast(e.Data);
			if (_pendingData != null)
				_pendingData.Clear();

			_pendingData = list;
			grid.Invoke(new UpdateDisplay(this.DisplayData));

		}
		private void query_DataException(object sender, DataExceptionEventArgs e)
		{
			this.Invoke(new ClearCursor(this.StopWaiting));
			ErrorHandler.GetInstance().LogException("UI query error SQL=" + e.SQL, e.Ex);
			App.ShowError("Error reported retrieving database data", 
						  string.Format("SQL={0}\r\nEx={1}",e.SQL,e.Ex.ToString()));
		}

		private void DisplayData()
		{
			lock (_pendingData)
			{
				if (_displayData != null )
					_displayData.Clear();
				_displayData = new List<LogDisplayRecord>();
				foreach (IBusinessObject obj in _pendingData)
				{
					LogDisplayRecord rec = new LogDisplayRecord(obj);
					_displayData.Add(rec);
				}
				_pendingData = null;
			}
			grid.DataSource = _displayData;
			// format grid if any data now displayed
			if (_displayData.Count > 0)
			{
				//	by default, grid suppresses Time portion of timestamp
				this.grid.DisplayLayout.Bands[0].Columns["Timestamp"].Format = "MM-dd-yyyy HH:mm";
				//	apply any persisted column widths
				SetColumnWidths();
			}
		}
		private void StopWaiting()
		{
			this.Cursor = Cursors.Default;
		}

		private void filterSelector_FilterCriteriaChanged(object sender, ucSelector.FilterCriteriaChangedEventArgs e)
		{
			if (!_loading)
				if (e != null)
					if (e.FilterCriteria != null)
						if (e.FilterCriteria.Count > 0)
						{
							if (_filterCriteria != null)
								_filterCriteria.Clear();
							else
								_filterCriteria = new Dictionary<string, string>();
							foreach (KeyValuePair<string, string> item in e.FilterCriteria)
								_filterCriteria.Add(item.Key, item.Value);
							RefreshData();
						}
		}
		private void autoRefreshTimer_AutoRefreshTimerElapsed(object sender, EventArgs e)
		{
			RefreshData();
		}
		private void RefreshData()
		{
			if (_filterCriteria != null && _filterCriteria.Count > 0)
			{
				if (_query == null)
					_query = new SelectLogRecordsByFilterList();
				_query.Select(_filterCriteria);
			}
		}

		#endregion

		#region formatting grid display

		private void grid_InitializeRow(object sender, Infragistics.Win.UltraWinGrid.InitializeRowEventArgs e)
		{
			//	on first time through only - enable the feature buttons 
			//	that require data to be in the grid
			if (!_gridHasData)
			{
				_gridHasData = true;
				this.Invoke(new UpdateDisplay(EnableButtons));
			}
			if (((LogDisplayRecord)e.Row.ListObject).IsAlarm)
			{
				e.Row.Appearance.FontData.Bold = Infragistics.Win.DefaultableBoolean.True;
				e.Row.Appearance.ForeColor = Color.Red;
			}
			else
			{
				e.Row.Appearance.FontData.Bold = Infragistics.Win.DefaultableBoolean.False;
				e.Row.Appearance.ForeColor = SystemColors.ControlText;
			}
		}
		private void SetColumnWidths()
		{
			if (_gridColumnWidths != null)
			{
				for (int idx = 0; idx < grid.DisplayLayout.Bands[0].Columns.Count; idx++)
					if (_gridColumnWidths.Length > idx)
						grid.DisplayLayout.Bands[0].Columns[idx].Width = Convert.ToInt32(_gridColumnWidths[idx]);
			}
		}

		#endregion

		#region feature command buttons

		#region *	manual handling command button Focus and LostFocus
		private void Command_Focus(object sender, EventArgs e)
		{
			((UltraButton)sender).Appearance.FontData.Bold = Infragistics.Win.DefaultableBoolean.True;
		}

		private void Command_Unfocus(object sender, EventArgs e)
		{
			((UltraButton)sender).Appearance.FontData.Bold = Infragistics.Win.DefaultableBoolean.False;
		}
		#endregion

		private void btnShowSigma_Click(object sender, EventArgs e)
		{
			if (grid.DisplayLayout.Override.AllowRowSummaries == AllowRowSummaries.True)
			{
				grid.DisplayLayout.Override.AllowRowSummaries = AllowRowSummaries.False;
				btnShowSigma.Text = "Show &Summary";
			}
			else
			{
				grid.DisplayLayout.Override.AllowRowSummaries = AllowRowSummaries.True;
				btnShowSigma.Text = "Hide &Summary";
			}
		}
		private void btnShowGrouping_Click(object sender, EventArgs e)
		{
			if (!grid.DisplayLayout.GroupByBox.Hidden)
			{
				grid.DisplayLayout.GroupByBox.Hidden = true;
				btnShowGrouping.Text = "Show &Grouping";
			}
			else
			{
				grid.DisplayLayout.GroupByBox.Hidden = false;
				btnShowGrouping.Text = "Hide &Grouping";
			}
		}
		private void btnExport_Click(object sender, EventArgs e)
		{
			try
			{
				if (openExportFile.ShowDialog() == DialogResult.OK)
					gridExport.Export(grid, openExportFile.FileName);
			}
			catch (Exception ex)
			{
				App.ShowError("Error encountered while exporting file. Export was not sucessful", ex);
			}
		}
		private void btnPrint_Click(object sender, EventArgs e)
		{
			try
			{
				gridPrint.Print();
			}
			catch (Exception ex)
			{
				App.ShowError("Error printing report.", ex);
			}
		}
		private void btnPageSetup_Click(object sender, EventArgs e)
		{
			try
			{
				pageSetup.ShowDialog();
			}
			catch (Exception ex)
			{
				App.ShowError("Error encountered during page setup.", ex);
			}
		}
		private void btnPrintPreview_Click(object sender, EventArgs e)
		{
			try
			{
				using (dlgPrintPreview dlg = new dlgPrintPreview())
				{
					dlg.Document = gridPrint;
					dlg.ShowDialog();
				}
			}
			catch (Exception ex)
			{
				App.ShowError("Error encountered previewing report.", ex);
			}
		}
		private void EnableButtons()
		{
			this.btnExport.Enabled = true;
			this.btnPageSetup.Enabled = true;
			this.btnPrint.Enabled = true;
			this.btnPrintPreview.Enabled = true;
			this.btnShowGrouping.Enabled = true;
			this.btnShowSigma.Enabled = true;
		}

		#endregion

		#region persisted form settings 

		protected override void LoadState()
		{
			base.LoadState();

			// load page setup
			string wrk = string.Empty;

			wrk = TextSettings.GetInstance()[SettingTypes.User, this.Name, "Landscape"];
			if (!wrk.Equals(string.Empty))
				this.pageSetup.PageSettings.Landscape = Convert.ToBoolean(wrk);

			wrk = TextSettings.GetInstance()[SettingTypes.User, this.Name, "Margins.Left"];
			if (!wrk.Equals(string.Empty))
				this.pageSetup.PageSettings.Margins.Left = Convert.ToInt32(wrk);
			wrk = TextSettings.GetInstance()[SettingTypes.User, this.Name, "Margins.Right"];
			if (!wrk.Equals(string.Empty))
				this.pageSetup.PageSettings.Margins.Right = Convert.ToInt32(wrk);
			wrk = TextSettings.GetInstance()[SettingTypes.User, this.Name, "Margins.Top"];
			if (!wrk.Equals(string.Empty))
				this.pageSetup.PageSettings.Margins.Top = Convert.ToInt32(wrk);
			wrk = TextSettings.GetInstance()[SettingTypes.User, this.Name, "Margins.Bottom"];
			if (!wrk.Equals(string.Empty))
				this.pageSetup.PageSettings.Margins.Bottom = Convert.ToInt32(wrk);

			//	load export file dir
			wrk = TextSettings.GetInstance()[SettingTypes.User, this.Name, "InitialDirectory"];
			if (!wrk.Equals(string.Empty))
				this.openExportFile.InitialDirectory = wrk;

			//	autorefresh
			wrk = TextSettings.GetInstance()[SettingTypes.User, this.Name, "AutoRefresh"];
			if (!wrk.Equals(string.Empty))
				this.autoRefreshTimer.AutoRefreshEnabled = Convert.ToBoolean(wrk);

			// get and unparse column widths - but do not
			// apply them until later when binding data
			wrk = TextSettings.GetInstance()[SettingTypes.User, this.Name, "Columns"];
			if (!wrk.Equals(string.Empty))
			{
				this._gridColumnWidths = wrk.Split(Constants.ElementDelimiter.ToCharArray()[0]);
			}

		}
		protected override void SaveState()
		{
			base.SaveState();

			// save page setup
			TextSettings.GetInstance()[SettingTypes.User, this.Name, "Landscape"] = this.pageSetup.PageSettings.Landscape.ToString();
			TextSettings.GetInstance()[SettingTypes.User, this.Name, "Margins.Left"] = this.pageSetup.PageSettings.Margins.Left.ToString();
			TextSettings.GetInstance()[SettingTypes.User, this.Name, "Margins.Top"] = this.pageSetup.PageSettings.Margins.Top.ToString();
			TextSettings.GetInstance()[SettingTypes.User, this.Name, "Margins.Right"] = this.pageSetup.PageSettings.Margins.Right.ToString();
			TextSettings.GetInstance()[SettingTypes.User, this.Name, "Margins.Bottom"] = this.pageSetup.PageSettings.Margins.Bottom.ToString();

			// autorefresh
			TextSettings.GetInstance()[SettingTypes.User, this.Name, "AutoRefresh"] = this.autoRefreshTimer.AutoRefreshEnabled.ToString();

			// save export file path
			if ( openExportFile.FileName != null )
				if (openExportFile.FileName != string.Empty)
				{
					string path = System.IO.Path.GetDirectoryName(openExportFile.FileName);
					TextSettings.GetInstance()[SettingTypes.User, this.Name, "InitialDirectory"] = path;
				}
			
			// save grid column widths
			if (_gridHasData)
			{
				string setting = string.Empty;
				foreach (UltraGridColumn col in grid.DisplayLayout.Bands[0].Columns)
					setting += col.Width.ToString() + Constants.ElementDelimiter;
				if ( setting != string.Empty )
					TextSettings.GetInstance()[SettingTypes.User, this.Name, "Columns"] = setting;
			}
		}

		#endregion

	}
}