using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using IndianHealthService.BMXNet.WinForm;
using IndianHealthService.BMXNet.Services;
using IndianHealthService.BMXNet.WinForm.Configuration;

namespace IndianHealthService.BMXNet.Tools.SchemaBuilder
{
    public partial class SchemaBuilderWindow : Form
    {
        public SchemaBuilderWindow()
        {
            InitializeComponent();
        }

        private BMXSchemaDoc _document;

        public BMXSchemaDoc Document
        {
            get { return _document; }
            set { _document = value; }
        }

        private string _appName = "BMXSchemaBuilder";

        public string AppName
        {
            get { return _appName; }
            set { _appName = value; }
        }

        private bool m_bDragDropStart;

        #region Methods


        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (components != null)
                {
                    components.Dispose();
                }
            }
            base.Dispose(disposing);
        }



        private WinFramework _framework = null;

        public WinFramework Framework
        {
            get { return _framework; }
            set { _framework = value; }
        }

        private RemoteSession _remoteSession = null;

        public RemoteSession RemoteSession
        {
            get { return _remoteSession; }
            set { _remoteSession = value; }
        }



        private void frmMain_Load(object sender, System.EventArgs e)
        {
            this.Login(false);
        }

        protected void Login(bool isServerSwitch)
        {
            try
            {
                if (this.Framework == null)
                {
                    this.Framework = WinFramework.CreateWithNetworkBroker(true);
                    this.Framework.LoadConnectionSpecs(LocalPersistentStore.CreateDefaultStorage(true), "SchemaBuilder");

                    LoginProcess login = this.Framework.CreateLoginProcess();
                    login.IsSwitchServerModeEnabled = isServerSwitch;

                    if (login.HasDefaultConnectionWithUseWindowsAuth)
                    {
                        login.AttemptWindowsAuthLogin();
                    }

                    if (!login.WasLoginAttempted || !login.WasSuccessful)
                    {
                        login.AttemptUserInputLogin("Schema Builder Login", 3, true, this);
                    }

                    if (!login.WasSuccessful)
                    {
                        this.Close();
                        return;
                    }
                    LocalSession local = this.Framework.LocalSession;

                    if ((this.Framework.Context.User.Division == null) && !this.Framework.AttemptUserInputSetDivision("Set Initial Division", this))
                    {
                        this.Close();
                        return;
                    }

                    this.RemoteSession = this.Framework.PrimaryRemoteSession;


                    this.UpdateTitle();
                    this.SetGridStyle();
                    this.LoadFileTree();
                    this.LoadNewSchema();
                    this.FormatSchemaFieldsGrid();
                }
            }
            catch (Exception problem)
            {
                this.Framework.LocalSession.Notify(this.AppName, problem);
            }
        }

        private void UpdateTitle()
        {

        }

        private void LoadFileTree()
        {
            try
            {
                tvFile.BeginUpdate();
                tvFile.Nodes.Clear();

                DataTable dtFile = this.RemoteSession.TableFromCommand("BMX ADO SS^FILEMAN FILES^^B~A~ZZZ~5000");

                //DataView dvFile = new DataView(dtFile);

                this.AddSubFileNodes(tvFile.Nodes, dtFile);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                tvFile.EndUpdate();
            }
        }

        private DataTable GetSubfiles(string sFileNum)
        {
            return this.RemoteSession.TableFromCommand("BMX ADO SS^SUBFILES^^~~~~~SFIT~BMXADOS1~" + sFileNum + "~");
        }

        public void LoadNewSchema()
        {
            this.Document = new BMXSchemaDoc();
            this.Document.RemoteSession = this.RemoteSession;
            this.Document.NewSchema();
            this.ugrdSchemaFields.DataSource = this.Document.SchemaFields;
            this.Text = this.AppName + " - " + this.Document.SchemaName;
            string sGridText = "Schema File: ";
            this.ugrdSchemaFields.Text = sGridText;
        }


        #endregion Methods

        #region TreeNode

        private void AddSubFileNodes(TreeNodeCollection nodParentColl, DataTable dt)
        {
            string sFileName;
            string sExpand;
            string sFileNumber;
            DataView dvFile = new DataView(dt);
            DataRowView drv;
            TreeNode tn;
            for (int j = 0; j < dvFile.Count; j++)
            {
                drv = dvFile[j];
                sFileName = drv["NAME"].ToString();
                sFileNumber = drv["BMXIEN"].ToString();
                sExpand = drv["SUBFILES PRESENT?"].ToString();
                tn = new TreeNode(sFileName);
                tn.Text = sFileName;
                tn.Tag = sFileNumber;
                if (sExpand == "+")
                {
                    tn.Nodes.Add(".");
                }
                nodParentColl.Add(tn);
            }
        }

        private void tvFile_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e)
        {
            try
            {
                string sNode = e.Node.Text;
                string sFileNumber = e.Node.Tag.ToString();
                string sCmd = "BMX ADO SS^FIELDS^^~~~~~FLDIT~BMXADOS1~" + sFileNumber + "~";
                DataTable dtFields = this.RemoteSession.TableFromCommand(sCmd,new DataSet(),"FIELDS");

                this.grdFieldList.DataSource = dtFields;
            }
            catch (Exception ex)
            {
                this.Framework.LocalSession.Notify("Error in " + this.AppName, ex);
            }

        }

        private void tvFile_BeforeExpand(object sender, System.Windows.Forms.TreeViewCancelEventArgs e)
        {
            try
            {
                string sNode = e.Node.Text;
                string sFileNumber = e.Node.Tag.ToString();
                e.Node.Nodes.Clear();
                DataTable dtSubFiles = this.GetSubfiles(sFileNumber);
                AddSubFileNodes(e.Node.Nodes, dtSubFiles);
            }
            catch (Exception ex)
            {
                this.Framework.LocalSession.Notify("Error in " + this.AppName, ex);
            }
        }


        #endregion TreeNode

        #region MouseHandlers

        private void grdFieldList_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            m_bDragDropStart = false;
       }

        private void grdFieldList_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            if (!m_bDragDropStart)
            {
                m_bDragDropStart = true;
                string[] sData = new string[2];
                DataGridCell dCell = grdFieldList.CurrentCell;
                dCell.ColumnNumber = 0;
                sData[0] = grdFieldList[dCell].ToString();
                dCell.ColumnNumber = 1;
                sData[1] = grdFieldList[dCell].ToString();
                DragDropEffects effect = DoDragDrop(sData, DragDropEffects.Move);
            }
        }

        private void grdFieldList_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
        {
        }

        #endregion MouseHandlers



        #region UltraGrid

        private void SetGridStyle()
        {
            //Fileman Fields Grid
            DataGridTableStyle tsFields = new DataGridTableStyle();
            tsFields.MappingName = "FIELDS";
            tsFields.ReadOnly = true;
            tsFields.RowHeadersVisible = false;

            // Add FIELD NUMBER column style.
            DataGridColumnStyle colFieldNumber = new DataGridTextBoxColumn();
            colFieldNumber.MappingName = "BMXIEN";
            colFieldNumber.HeaderText = "Field Number";
            colFieldNumber.Width = 100;
            tsFields.GridColumnStyles.Add(colFieldNumber);
            // Add FIELD NAME column style.
            DataGridColumnStyle colFieldName = new DataGridTextBoxColumn();
            colFieldName.MappingName = "NAME";
            colFieldName.HeaderText = "Field Name";
            colFieldName.Width = 290;
            tsFields.GridColumnStyles.Add(colFieldName);

            this.grdFieldList.TableStyles.Add(tsFields);
        }

        private void FormatSchemaFieldsGrid()
        {
            Infragistics.Win.ValueListsCollection vlSchemaFields;
            Infragistics.Win.UltraWinGrid.UltraGridBand bndSchemaFields;

            vlSchemaFields = ugrdSchemaFields.DisplayLayout.ValueLists;
            vlSchemaFields.Add("YesNo");
            vlSchemaFields["YesNo"].ValueListItems.Add("YES");
            vlSchemaFields["YesNo"].ValueListItems.Add("NO");
            vlSchemaFields.Add("DataType");
            vlSchemaFields["DataType"].ValueListItems.Add("TEXT");
            vlSchemaFields["DataType"].ValueListItems.Add("DATE");
            vlSchemaFields["DataType"].ValueListItems.Add("INTEGER");
            vlSchemaFields["DataType"].ValueListItems.Add("NUMBER");

            bndSchemaFields = ugrdSchemaFields.DisplayLayout.Bands[0];
            bndSchemaFields.Columns["READ ONLY"].ValueList = vlSchemaFields["YesNo"];
            bndSchemaFields.Columns["KEY FIELD"].ValueList = vlSchemaFields["YesNo"];
            bndSchemaFields.Columns["NULL ALLOWED"].ValueList = vlSchemaFields["YesNo"];
            bndSchemaFields.Columns["IEN AUTOMATICALLY INCLUDED"].ValueList = vlSchemaFields["YesNo"];
            bndSchemaFields.Columns["DATA TYPE"].ValueList = vlSchemaFields["DataType"];

            bndSchemaFields.Columns["BMXIEN"].Hidden = true;
            bndSchemaFields.Columns["BMXIEN1"].Hidden = true;

        }

        private void ugrdSchemaFields_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
        {
            try
            {
                m_bDragDropStart = false;
         
                string[] sData = (string[])e.Data.GetData(typeof(string[]));
                DataTable dt = (DataTable)ugrdSchemaFields.DataSource;
                DataRow dr = dt.NewRow();
                double nField = Convert.ToDouble(sData[0]);
                string sField = nField.ToString(".#####");
                dr["FIELD NUMBER"] = sField;
                dr["COLUMN HEADER"] = sData[1];
                dt.Rows.Add(dr);
                Document.SchemaFields = dt;
                ugrdSchemaFields.DataSource = Document.SchemaFields;
                ugrdSchemaFields.Refresh();
            }
            catch (Exception ex)
            {
                this.Framework.LocalSession.Notify("Error in " + this.AppName, ex);
            }
        }

        private void ugrdSchemaFields_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)
        {

            if (e.Data.GetDataPresent(typeof(string[])))
            {
                string[] sData = (string[])e.Data.GetData(typeof(string[]));
                DataTable dt = (DataTable)ugrdSchemaFields.DataSource;
                double nField = Convert.ToDouble(sData[0]);
                string sField = nField.ToString(".#####");
                string header = sData[1];
                //check if present
                


                if ((e.KeyState & 8) == 8) //CTRL key
                {
                    e.Effect = DragDropEffects.Copy;
                }
                else
                {
                    e.Effect = DragDropEffects.Move;
                }
            }
            else
            {
                e.Effect = DragDropEffects.None;
            }


        }

        private void ugrdSchemaFields_InitializeLayout(object sender, Infragistics.Win.UltraWinGrid.InitializeLayoutEventArgs e)
        {
            e.Layout.Override.HeaderClickAction = Infragistics.Win.UltraWinGrid.HeaderClickAction.SortMulti;
        }
        #endregion UltraGrid

        #region MenuHandlers

        private void mnuHelpAbout_Click(object sender, System.EventArgs e)
        {
            new AboutDialog().ShowDialog(this);
        }

        private void mnuViewFiles_Click(object sender, System.EventArgs e)
        {
            mnuViewFiles.Checked = !(mnuViewFiles.Checked);
            pnlFileField.Visible = mnuViewFiles.Checked;
        }

        private void mnuViewStatusBar_Click(object sender, System.EventArgs e)
        {
            mnuViewStatusBar.Checked = !(mnuViewStatusBar.Checked);
            this.statusBar1.Visible = mnuViewStatusBar.Checked;
        }

        private void mnuFileNewSchema_Click(object sender, System.EventArgs e)
        {
            this.LoadNewSchema();
        }

        private void mnuFileSave_Click(object sender, System.EventArgs e)
        {
            try
            {
                if (Document.SchemaIEN == 0)
                {
                    //prompt for a name
                    DSaveSchema dSave = new DSaveSchema();
                    if (dSave.ShowDialog() == DialogResult.Cancel)
                        return;
                    this.Document.SaveSchema(dSave.SchemaName);
                    this.Text = this.AppName + " - " + Document.SchemaName;

                }
                else
                {
                    this.Document.SaveSchema();
                }
            }
            catch (Exception ex)
            {
                this.Framework.LocalSession.Notify("Error in " + this.AppName, ex);
            }
        }

        private void mnuFileOpenSchema_Click(object sender, System.EventArgs e)
        {
            //Display a dialog to select from existing schemas
            DSelectSchema dss = new DSelectSchema();
            dss.InitializePage(this.RemoteSession);
            if (dss.ShowDialog() == DialogResult.Cancel)
                return;

            Document.OpenSchema(dss.SchemaIEN, dss.SchemaName, dss.FileNumber);
            ugrdSchemaFields.DataSource = Document.SchemaFields;
            ugrdSchemaFields.Refresh();

            string sGridText = "Schema File: " + Document.SchemaFileName + " (Number " + Document.SchemaFileNumber.ToString() + ")";
            if (Document.SchemaReadOnlyDataset == true)
                sGridText += " [Dataset is ReadOnly]";
            this.ugrdSchemaFields.Text = sGridText;
            this.Text = this.AppName + " - " + Document.SchemaName;
        }

        private void mnuSetSchemaFile_Click(object sender, System.EventArgs e)
        {
            Document.SchemaFileName = this.tvFile.SelectedNode.Text;
            Document.SchemaFileNumber = Convert.ToDouble(this.tvFile.SelectedNode.Tag);
            ugrdSchemaFields.Text = "Schema File:  " + Document.SchemaFileName;
            ugrdSchemaFields.Text += " (Number " + Document.SchemaFileNumber.ToString() + ")";
        }


        #endregion MenuHandlers

        private void mnuFileExit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void SchemaBuilderWindow_FormClosed(object sender, FormClosedEventArgs e)
        {
            this.Framework.Close();
        }

        private void changeRpmsLogin_Click(object sender, EventArgs e)
        {
            this.tvFile.Nodes.Clear();
            this.ugrdSchemaFields.DisplayLayout.ValueLists.Clear();
            this.grdFieldList.DataSource = null;
            this.ugrdSchemaFields.DataSource = null;
            this.ugrdSchemaFields.Text = "";
            this.grdFieldList.TableStyles.Clear();

            this.Framework.Close();
            this.Framework = null;
            this.Login(true);
       
        }



    }
}
