using System;
using System.Data;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using Minntech.Common;
using Minntech.Common.Settings;

namespace Minntech.Common.Settings
{
	/// <summary>
	/// Summary description for Settings.
	/// </summary>
	public class dlgSettings : System.Windows.Forms.Form
	{
		private System.Windows.Forms.TreeView tvSettings;
		private System.Windows.Forms.Button commandAdd;
		private System.Windows.Forms.Button commandDelete;
		private System.Windows.Forms.Button commandEdit;

		private LocalHost		_host = null;
		private UserSettings	_user = null;
		private AppSettings		_app  = null;
	
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;

		#region construct/load/dispose

		public dlgSettings()
		{
			InitializeComponent();
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}


		private void dlgSettings_Load(object sender, System.EventArgs e)
		{
			this.Text = System.Reflection.Assembly.GetEntryAssembly().GetName().Name + " Settings";
			LoadAppSettings();
			LoadHostSettings();
			LoadUserSettings();
		}
		private void LoadAppSettings()
		{
			if ( this._app == null ) this._app = new AppSettings();
			AppSettings.ApplicationRow row = null;
			
			//	default rows if necessary
			if ( _app.Application.Rows.Count == 0 )
			{
				row = _app.Application.NewApplicationRow();
				row.CommitInterval = Constants.DefaultCommitInterval;
				row.DataSource = Constants.DefaultConnection;
				row.LocalHostSettingsPath = Constants.DefaultHostSettingsPath;				
				row.ParseInterval = Constants.DefaultParseInterval;
				_app.Application.AddApplicationRow(row);
			}
			row = (AppSettings.ApplicationRow)_app.Application.Rows[0];

			SettingsNode appNode = new SettingsNode("Application");

			foreach ( DataColumn col in _app.Application.Columns )
			{
				if ( row.IsNull(col) )
					appNode.AddSetting(new SettingsNode(col.ColumnName, string.Empty));
				else
					appNode.AddSetting(new SettingsNode(col.ColumnName, (string)row.ItemArray[col.Ordinal]));
			}

			this.tvSettings.Nodes.Add(appNode);
						
		}
		private void LoadHostSettings()
		{
			if ( this._host == null ) this._host = new LocalHost();

			LocalHost.CommPortSettingsRow newRow = null;

			//	default rows if necessary
			if ( _host.CommPortSettings.Rows.Count == 0 )
			{
				newRow = _host.CommPortSettings.NewCommPortSettingsRow();
				newRow.CommPort = Constants.DefaultCommPort;
				newRow.BaudRate = Constants.DefaultBaudRate;
				newRow.DataBit  = Constants.DefaultDataBit;
				newRow.Parity   = Constants.DefaultParity;
				newRow.StopBit  = Constants.DefaultStopBit;
				newRow.HandShake= Constants.DefaultHandShake;
				_host.CommPortSettings.AddCommPortSettingsRow(newRow);
			}
			SettingsNode hostNode = new SettingsNode("LocalHost");
			//	LocalHost allows users to add new CommPortSettings
			hostNode.AllowsAdd = true;

			foreach (LocalHost.CommPortSettingsRow row in _host.CommPortSettings.Rows )
			{
				SettingsNode node = new SettingsNode ( row.CommPort );
				//	CommPortSettings can be deleted
				node.AllowsDelete = true;

				foreach ( DataColumn col in _host.CommPortSettings.Columns )
				{
					if ( row.IsNull(col) )
						node.AddSetting(new SettingsNode(col.ColumnName, string.Empty));
					else
						node.AddSetting(new SettingsNode(col.ColumnName, (string)row.ItemArray[col.Ordinal]));
				}
				hostNode.AddSetting(node);
			}
			this.tvSettings.Nodes.Add(hostNode);
		}
		private void LoadUserSettings()
		{
			if ( this._user == null ) this._user = new UserSettings();

			//	default rows if necessary
			if ( _user.Users.Rows.Count == 0 )
			{
				UserSettings.UsersRow newRow = _user.Users.NewUsersRow();
				newRow.User = System.Environment.UserName;
				_user.Users.AddUsersRow(newRow);
			}	
			if ( _user.UserForms.Rows.Count == 0 )
			{
				UserSettings.UserFormsRow newRow = _user.UserForms.NewUserFormsRow();
				newRow.User   = System.Environment.UserName;
				newRow.Form   = this.Text;
				newRow.Top    = this.Top.ToString();
				newRow.Left	  = this.Left.ToString();
				newRow.Height = this.Height.ToString();
				newRow.Width  = this.Width.ToString();
				_user.UserForms.AddUserFormsRow(newRow);
			}

			SettingsNode usersNode = new SettingsNode ("Users");

			foreach ( UserSettings.UsersRow	uRow in _user.Users.Rows )
			{
				SettingsNode userNode = new SettingsNode ( uRow.User );
				// user nodes can be deleted
				userNode.AllowsDelete = true;

				foreach ( UserSettings.UserFormsRow	ufRow in _user.UserForms.Rows )
				{
					if ( ufRow.User.Equals(uRow.User) )
					{
						SettingsNode node = new SettingsNode (ufRow.Form);
						//	form locations settings can be deleted
						node.AllowsDelete = true;
						foreach ( DataColumn col in _user.UserForms.Columns )
						{
							if ( ! col.ColumnName.Equals ( _user.UserForms.UserColumn.ColumnName ) && 
								! col.ColumnName.Equals ( _user.UserForms.FormColumn.ColumnName ) )
							{
								if ( ufRow.IsNull(col) )
									node.AddSetting(new SettingsNode(col.ColumnName, string.Empty));
								else
									node.AddSetting(new SettingsNode(col.ColumnName, (string)ufRow.ItemArray[col.Ordinal]));
							}
						}
						userNode.AddSetting(node);
					}
				}
				usersNode.AddSetting(userNode);
			}

			this.tvSettings.Nodes.Add(usersNode);
		}


		#endregion

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.tvSettings = new System.Windows.Forms.TreeView();
			this.commandAdd = new System.Windows.Forms.Button();
			this.commandDelete = new System.Windows.Forms.Button();
			this.commandEdit = new System.Windows.Forms.Button();
			this.SuspendLayout();
			// 
			// tvSettings
			// 
			this.tvSettings.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
				| System.Windows.Forms.AnchorStyles.Left) 
				| System.Windows.Forms.AnchorStyles.Right)));
			this.tvSettings.ImageIndex = -1;
			this.tvSettings.Location = new System.Drawing.Point(8, 8);
			this.tvSettings.Name = "tvSettings";
			this.tvSettings.PathSeparator = "{|}";
			this.tvSettings.SelectedImageIndex = -1;
			this.tvSettings.Size = new System.Drawing.Size(272, 272);
			this.tvSettings.TabIndex = 0;
			this.tvSettings.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.tvSettings_AfterSelect);
			// 
			// commandAdd
			// 
			this.commandAdd.Location = new System.Drawing.Point(288, 8);
			this.commandAdd.Name = "commandAdd";
			this.commandAdd.Size = new System.Drawing.Size(64, 23);
			this.commandAdd.TabIndex = 1;
			this.commandAdd.Text = "Add";
			this.commandAdd.Click += new System.EventHandler(this.commandAdd_Click);
			// 
			// commandDelete
			// 
			this.commandDelete.Location = new System.Drawing.Point(288, 72);
			this.commandDelete.Name = "commandDelete";
			this.commandDelete.Size = new System.Drawing.Size(64, 23);
			this.commandDelete.TabIndex = 2;
			this.commandDelete.Text = "Delete";
			this.commandDelete.Click += new System.EventHandler(this.commandDelete_Click);
			// 
			// commandEdit
			// 
			this.commandEdit.Location = new System.Drawing.Point(288, 40);
			this.commandEdit.Name = "commandEdit";
			this.commandEdit.Size = new System.Drawing.Size(64, 23);
			this.commandEdit.TabIndex = 3;
			this.commandEdit.Text = "Edit";
			this.commandEdit.Click += new System.EventHandler(this.commandEdit_Click);
			// 
			// dlgSettings
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.ClientSize = new System.Drawing.Size(360, 285);
			this.Controls.Add(this.commandEdit);
			this.Controls.Add(this.commandDelete);
			this.Controls.Add(this.commandAdd);
			this.Controls.Add(this.tvSettings);
			this.Name = "dlgSettings";
			this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
			this.Text = "Settings";
			this.Load += new System.EventHandler(this.dlgSettings_Load);
			this.ResumeLayout(false);

		}
		#endregion

		private void commandEdit_Click(object sender, System.EventArgs e)
		{	
			if ( this.tvSettings.SelectedNode == null )
				ErrorHandler.GetInstance().LogException(true, "Please select a Setting first!");
			else
			{
				try
				{
					this.tvSettings.SuspendLayout();
					

					using ( dlgEditNode dlg = new dlgEditNode() )
					{
						dlg.SettingName.Text = ((SettingsNode)this.tvSettings.SelectedNode).Name;
						dlg.SettingName.Enabled = false;
						dlg.SettingValue.Text = ((SettingsNode)this.tvSettings.SelectedNode).Value;
						dlg.ShowDialog();

						if ( dlg.DialogResult != DialogResult.Cancel )
						{
							((SettingsNode)this.tvSettings.SelectedNode).Value = dlg.SettingValue.Text;
							this.tvSettings.Refresh();
						}
					}
				}
				catch ( InvalidOperationException dupeNode )
				{
					ErrorHandler.GetInstance().LogException(true, dupeNode.Message );
				}
				catch ( Exception otherEx )
				{
					ErrorHandler.GetInstance().LogException(true, "dlgSettings.commandAdd", otherEx );
				}
				finally
				{
					this.tvSettings.ResumeLayout();
				}
			}
		}
		private void commandAdd_Click(object sender, System.EventArgs e)
		{
			//	 so far, the only allowable Add is a new set of CommPortSettings
			dlgCommPortSettings dlg = new dlgCommPortSettings ();
			if ( dlg.ShowDialog() == DialogResult.OK )
			{
				if ( this._host == null )
					this._host = new LocalHost();
				LocalHost.CommPortSettingsRow row = _host.CommPortSettings.NewCommPortSettingsRow();
				row.BaudRate	= dlg.BaudRate.ToString();
				row.CommPort	= dlg.CommPort.ToString();
				row.DataBit		= dlg.DataBit.ToString();
				row.HandShake	= dlg.HandShake.ToString();
				row.Parity		= dlg.Parity.ToString();
				row.StopBit		= dlg.StopBit.ToString();					
				_host.CommPortSettings.AddCommPortSettingsRow(row);
				
				this.tvSettings.SelectedNode.Remove();
				this.LoadHostSettings();
			}
		}

		private void commandDelete_Click(object sender, System.EventArgs e)
		{
			if ( this.tvSettings.SelectedNode.Parent != null )
			{
				this.tvSettings.SelectedNode.Parent.Nodes.Remove(this.tvSettings.SelectedNode);
				this.tvSettings.Refresh();
			}
		}
		private void tvSettings_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e)
		{
			//	determine what buttons are appropriate for the current selection and enable them
			if ( this.tvSettings.SelectedNode == null )
			{
				this.commandAdd.Enabled = false;
				this.commandDelete.Enabled = false;
				this.commandEdit.Enabled = false;
			}
			else
			{
				this.commandAdd.Enabled = ((SettingsNode)this.tvSettings.SelectedNode).AllowsAdd;
				this.commandDelete.Enabled = ((SettingsNode)this.tvSettings.SelectedNode).AllowsDelete;
				this.commandEdit.Enabled = ((SettingsNode)this.tvSettings.SelectedNode).AllowsEdit;
			}

		}
	}
}
