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.WinForm.Configuration;
using System.Reflection;
using System.IO;
using IndianHealthService.BMXNet.Model;
using IndianHealthService.BMXNet.WinForm.Model;
using IndianHealthService.BMXNet.Services;

namespace IndianHealthService.BMXNet.Example.CrossComponent.WindowsApp
{
    public partial class WindowsApplicationMainWindow : Form
    {
        public WindowsApplicationMainWindow()
        {
            InitializeComponent();
        }


        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 WindowsApplicationMainWindow_Load(object sender, EventArgs e)
        {
            bool usePrimarySession = this.Framework == null;

            if (this.Framework == null)
            {
                this.Framework = WinFramework.CreateWithNetworkBroker(true,new NullLog());

                this.Framework.LoadConnectionSpecs(LocalPersistentStore.CreateDefaultStorage(true), "MyApplication", "v5");

                if (this.Framework.ConnectionSettings.ConnectionSpecs.Count == 0)
                {
                    try
                    {
                        Assembly priorAssembly = Assembly.LoadFrom("PriorBmxForEvidence/BMXNet30.dll");
                        this.Framework.LoadConnectionSpecsAndMergeWithExistingBMXConfiguration(priorAssembly, LocalPersistentStore.CreateDefaultStorage(true), "MyApplication", "v5");
                    }
                    catch
                    {
                    }
                }


                LoginProcess login = this.Framework.CreateLoginProcess();

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

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

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

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

            this.RemoteSession =
                usePrimarySession
                ? this.Framework.Broker.PrimaryRemoteSession
                : this.Framework.Broker.RemoteSessionPool.OpenSession();

            this.AddControl();

            this.Framework.Context.Changed += new EventHandler<ContextChangedArgs>(Context_Changed);
            this.currentCheckBox.Checked = this.Framework.BootStrapSettings.GetBool("CurrentVisit", true);
            this.patientCombo.Focus();

            this.UpdateTitle();

           }

        private Context _managedContext = null;

        public Context ManagedContext
        {
            get { return _managedContext; }
            set { _managedContext = value; }
        }

        void Context_Changed(object sender, ContextChangedArgs e)
        {
            if (e.IsPatientChange)
            {
                if (e.IsPatientChange && e.AfterContext.Patient == null)
                {
                    this.patientCombo.Items.Clear();
                    this.patientCombo.Text = "";
                }
                this.UpdateVisits();
            }
        }

        private void AddControl()
        {
            UserInfoControl control = new UserInfoControl();
            (control as LocalConsumer).LocalSession = this.Framework.LocalSession;
            (control as RemoteSessionConsumer).RemoteSession = this.RemoteSession;

            control.Dock = DockStyle.Fill;

            this.controlPanel.Controls.Add(control);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            AboutDialog dialog = new AboutDialog();
            dialog.ShowDialog(this);
        }


        public Patient SelectedPatient
        {
            get { return (Patient)this.patientCombo.SelectedItem; }
        }

        private void patientCombo_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.Framework.Context.ChangePatient(this.SelectedPatient);
        }

        private void UpdateVisits()
        {
            this.visitComboBox.BeginUpdate();
            this.visitComboBox.Items.Clear();
            if (this.SelectedPatient != null)
            {
                List<Visit> visits = this.Framework.Visits(this.SelectedPatient, 20);
                this.visitComboBox.Items.AddRange(visits.ToArray());
                this.visitComboBox.SelectedIndex = (this.currentCheckBox.Checked ? Math.Min(visits.Count - 1, 0) : -1);
            }
            this.visitComboBox.EndUpdate();
        }

        private void findButton_Click(object sender, EventArgs e)
        {
            this.DoSearch();
        }

        protected void DoSearch()
        {

            List<Patient> found = this.Framework.FindPatients(this.patientCombo.Text, 20);

            this.patientCombo.BeginUpdate();
            this.patientCombo.Items.Clear();
            foreach (Patient each in found)
            {
                this.patientCombo.Items.Add(each);
            }

            if (found.Count == 1)
            {
                this.patientCombo.SelectedItem = found[0];
            }
            else if (found.Count == 0)
            {
                this.patientCombo.Text = "<No patients found>";
                this.patientCombo.Focus();
            }
            else
            {
                this.patientCombo.Text = found.Count.ToString() + " patients found...";
            }

            this.patientCombo.EndUpdate();
        }

        private void patientCombo_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                this.DoSearch();
            }
        }

        private void resetButton_Click(object sender, EventArgs e)
        {
            this.Framework.Context.ChangePatient(this.Framework.Context.Patient);
        }

        private void refreshButton_Click(object sender, EventArgs e)
        {
            this.Framework.TriggerLocalEvent("REFRESH", "UserSelected");
        }

        public Visit SelectedVisit
        {
            get { return (Visit)this.visitComboBox.SelectedItem; }
        }


        private void visitComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.Framework.Context.ChangeVisit(this.SelectedVisit);

        }

        private void divisionButton_Click(object sender, EventArgs e)
        {
            if (this.Framework.AttemptUserInputSetDivision("Change Divsion @ " + DateTime.Now.ToLongTimeString(), this))
            {
                this.patientCombo.Items.Clear();
                this.patientCombo.Text = null;
                this.patientCombo.Focus();
            }

        }

        private void keyEntry_TextChanged(object sender, EventArgs e)
        {
            this.keyEntry.BackColor = Color.White;
        }

        private void keyButton_Click(object sender, EventArgs e)
        {
            this.keyEntry.BackColor = this.Framework.User.HasSecurityKey(this.keyEntry.Text.Trim()) ? Color.LightGreen : Color.Red;
        }

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

        private void bMXVersionInfoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //  DataTable peek = this.Framework.Bmx.VersionInfo;
            this.NotYetImplemented();
        }

        private void NotYetImplemented()
        {
            MessageBox.Show("Not yet implement", "Demo App Message");
        }

        private void WindowsApplicationMainWindow_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (this.RemoteSession != null)
            {
                this.RemoteSession.Close();
            }
        }

        private void spawnSessionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            WindowsApplicationMainWindow window = new WindowsApplicationMainWindow();
            window.Framework = this.Framework;
            window.Show();
        }

        public void UpdateTitle()
        {
            this.Text = "BMX Test Bench :: " + this.RemoteSession.ToString();
        }

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

        private void remoteTriggerButton_Click(object sender, EventArgs e)
        {
            String eventName = this.remoteEventTriggerCombo.Text.Trim();
            String eventParam = this.remoteParamTriggerCombo.Text.Trim();

            if (eventName.Length > 0)
            {
                int result=this.RemoteSession.EventServices.TriggerEvent(eventName, eventParam, this.remoteCallBackCheck.Checked);
            }
        }

        private void localTriggerButton_Click(object sender, EventArgs e)
        {
            String eventName = this.localEventTriggerCombo.Text.Trim();
            String eventParam = this.localParamTriggerCombo.Text.Trim();

            if (eventName.Length > 0)
            {
                this.Framework.TriggerLocalEvent(eventName, eventParam);
            }
        }

        private void logViewerToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }
    }
}
