using System;
using System.Data;
using System.Windows.Forms;
using System.Diagnostics;
using IndianHealthService.BMXNet;

namespace IndianHealthService.BMXNet.Tools.SchemaBuilder
{
	/// <summary>
	/// Represents a BMX ADO SCHEMA entry
	/// </summary>
	[Serializable]
	public class BMXSchemaDoc: System.Object
	{
		#region Fields

		private string		m_sFileName;
		private double		m_nFileNumber;
		private DataTable	m_dtSchemaFields;
		private DataTable	m_dtSchemas;
		private DataTable	m_dtCurrentSchema; //the one we're editing
		private double		m_nSchemaIEN;
		private string		m_sSchemaName;
		private bool		m_bReadOnlyDataset = true;

		#endregion Fields

		#region Methods

		public BMXSchemaDoc()
		{

		}

        private RemoteSession _remoteSession = null;

        public RemoteSession RemoteSession
        {
            get { return _remoteSession; }
            set { _remoteSession = value; }
        }


		public void OpenSchema(double SchemaIEN, string SchemaName, double FileNumber)
		{
			try
			{
				m_nSchemaIEN = SchemaIEN;
				m_sSchemaName = SchemaName;
				m_nFileNumber = FileNumber;
				string sRpc = "BMX ADO SS^FILEMAN FILEINFO^^~~~~~FNIT~BMXADOS1~" + m_nFileNumber.ToString() + "~";
                DataTable dtFileName = this.RemoteSession.TableFromCommand(sRpc);
				Debug.Assert(dtFileName.Rows.Count == 1);
				DataRow dr = dtFileName.Rows[0];
				m_sFileName = dr["NAME"].ToString();
			
				sRpc = "BMX ADO SS^SCHEMAS^^~" + m_nSchemaIEN.ToString() + "~" + m_nSchemaIEN.ToString();
                m_dtCurrentSchema = this.RemoteSession.TableFromCommand(sRpc);
				Debug.Assert(m_dtCurrentSchema.Rows.Count == 1);
				dr = m_dtCurrentSchema.Rows[0];
				string sReadOnly = dr["DATASET IS READ ONLY"].ToString();
				m_bReadOnlyDataset = (sReadOnly == "YES")?true:false;

				sRpc = "BMX ADO SS^SCHEMA DEFINITION^";
				sRpc += m_nSchemaIEN.ToString();
				sRpc += ",^~~~";
                m_dtSchemaFields = this.RemoteSession.TableFromCommand(sRpc);
				m_dtSchemaFields.TableName="SCHEMA FIELDS";
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message, "BMX Schema Builder");
			}		
		}

		public void NewSchema()
		{
			//This code executes at app startup
			m_sSchemaName = "NewSchema";
			m_nSchemaIEN = 0;
			m_sFileName = "";
			m_nFileNumber = 0;

			m_dtSchemaFields = this.RemoteSession.TableFromCommand("BMX ADO SS^SCHEMA DEFINITION^0,^~~~");
			m_dtSchemaFields.TableName="SCHEMA FIELDS";
			m_dtSchemaFields.Columns.Add("BMXIEN1", typeof(System.Int16));

            m_dtSchemas = this.RemoteSession.TableFromCommand("BMX ADO SS^SCHEMAS^^B~~~");
			m_dtSchemas.TableName="SCHEMAS";

            m_dtCurrentSchema = this.RemoteSession.TableFromCommand("BMX ADO SS^SCHEMAS^^~-1~");
		}

		public void SaveSchema()
		{
			SaveSchema(this.m_sSchemaName);
		}

		public void SaveSchema(string SchemaName)
		{
			//If m_nSchemaIEN == 0 then save a new schema
			//Otherwise, save existing schema at m_nSchemaIEN

			string sRpc;
			this.m_sSchemaName = SchemaName;

			if (m_dtCurrentSchema.Rows.Count == 0)
			{
				//Adding a new SCHEMA entry

				Debug.Assert(m_nSchemaIEN == 0);
				//Build a new row in the current schema record and
				//add it to the SCHEMA file
				DataRow dr = m_dtCurrentSchema.NewRow();
				dr["SCHEMA"] = m_sSchemaName;
				dr["DATASET IS READ ONLY"] = m_bReadOnlyDataset ?"YES":"NO";
				dr["FILE OR SUBFILE NUMBER"] = this.m_nFileNumber;//.ToString("###############.##############");
				m_dtCurrentSchema.Rows.Add(dr);

				//add it to the SCHEMA file
                this.RemoteSession.SaveChanges(m_dtCurrentSchema);

				//Re-load the m_dtCurrentSchema table to get the IEN of the newly added SCHEMA entry
				sRpc = "BMX ADO SS^SCHEMAS^^B~" + m_sSchemaName + "~" + m_sSchemaName;
				m_dtCurrentSchema = this.RemoteSession.TableFromCommand(sRpc);
				Debug.Assert(m_dtCurrentSchema.Rows.Count > 0);
				dr = m_dtCurrentSchema.Rows[0];
				m_nSchemaIEN = Convert.ToDouble(dr["BMXIEN"]);
				Debug.Assert(m_nSchemaIEN > 0);

				//Insert SCHEMA ien into schema fields multiple at BMXIEN1
				for (int j=0; j < m_dtSchemaFields.Rows.Count; j++)
				{
					dr = m_dtSchemaFields.Rows[j];
					dr["BMXIEN1"] = m_nSchemaIEN;
				}

				//Add the FIELDS to the SCHEMA entry
                this.RemoteSession.SaveChanges(m_dtSchemaFields);
            }
			else
			{
				Debug.Assert(m_nSchemaIEN > 0);
				Debug.Assert(m_dtCurrentSchema.Rows.Count == 1);
				//Build a new row in the current schema record and
				//add it to the SCHEMA file
				DataRow dr = m_dtCurrentSchema.Rows[0];
				dr["SCHEMA"] = this.SchemaName;
				dr["DATASET IS READ ONLY"] = this.SchemaReadOnlyDataset?"YES":"NO";
                dr["FILE OR SUBFILE NUMBER"] = this.SchemaFileNumber; //.ToString("###############.##############");

				//update the SCHEMA file
				this.RemoteSession.SaveChanges(m_dtCurrentSchema);

				//Insert SCHEMA ien into schema fields multiple at BMXIEN1
				//to ensure that added fields have the correct BMXIEN1
				for (int j=0; j < m_dtSchemaFields.Rows.Count; j++)
				{
					if (m_dtSchemaFields.Rows[j].RowState != DataRowState.Deleted)
					{
						dr = m_dtSchemaFields.Rows[j];
						if (dr["BMXIEN1"].GetType() == typeof(System.DBNull))
							dr["BMXIEN1"] = m_nSchemaIEN;
					}
				}

				//Add the FIELDS to the SCHEMA entry
				this.RemoteSession.SaveChanges(m_dtSchemaFields);
			}
			
		}

		#endregion Methods

		#region Properties

	
        public DataTable SchemaFields
		{
			get
			{
				return this.m_dtSchemaFields;
			}
			set
			{
				this.m_dtSchemaFields = value;
			}
		}

		public double SchemaIEN
		{
			get
			{
				return m_nSchemaIEN;
			}
			set
			{
				m_nSchemaIEN = value;
			}
		}

		public string SchemaName
		{
			get
			{
				return m_sSchemaName;
			}
			set
			{
				m_sSchemaName = value;
			}
		}

		public string SchemaFileName
		{
			get
			{
				return m_sFileName;
			}
			set
			{
				m_sFileName = value;
			}
		}

		public bool SchemaReadOnlyDataset
		{
			get
			{
				return m_bReadOnlyDataset;
			}
			set
			{
				m_bReadOnlyDataset = value;
			}
		}
		public double SchemaFileNumber
		{
			get
			{
				return m_nFileNumber;
			}
			set
			{
				m_nFileNumber = value;
			}
		}

		#endregion Properties
	}
}
