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

namespace IndianHealthService.BMXNet.Example.CrossComponent
{
    public partial class UserInfoControl : UserControl, LocalConsumer, RemoteSessionConsumer
    {
        public UserInfoControl()
        {
            InitializeComponent();
        }

        private RemoteSession _remoteSession = null;

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

        private LocalSession _localSession = null;

        public LocalSession LocalSession
        {
            get { return _localSession; }
            set { _localSession = value; }
        }

        private void UserInfoControl_Load(object sender, EventArgs e)
        {
            if (this.LocalSession != null)
            {
                this.LocalSession.Context.Changing += new EventHandler<IndianHealthService.BMXNet.Model.ContextChangingArgs>(Context_Changing);
                this.LocalSession.Context.Changed += new EventHandler<IndianHealthService.BMXNet.Model.ContextChangedArgs>(Context_Changed);
                this.LocalSession.EventServices.RefreshRequested += new EventHandler(EventServices_RefreshRequested);
                this.LocalSession.EventServices.ApplicationEvent += new EventHandler<LocalEventArgs>(EventServices_ApplicationEvent);
            }

            if (this.RemoteSession != null)
            {
                this.RemoteSession.EventServices.InvokedControl = this;
                this.RemoteSession.EventServices.RpmsEvent += new EventHandler<RemoteEventArgs>(EventServices_RpmsEvent);
                this.RemoteSession.EventServices.TimerEvent += new EventHandler(EventServices_TimerEvent);
            }

            this.eventLogList.Clear();
            this.eventLogList.Columns.Add("", 20);
            this.eventLogList.Columns.Add("Context", 80);
            this.eventLogList.Columns.Add("Event", 100);
            this.eventLogList.Columns.Add("Details", 250);

            this.queryEntry.Text = "BMX ADO SS^IHS PATIENT^^~1~20~5";
            this.UpdateLabels();
            this.UpdatePollingLabel();
        }

        void Context_Changing(object sender, IndianHealthService.BMXNet.Model.ContextChangingArgs e)
        {
            e.Cancel = this.vetoCheckBox.Checked;
        }

        void EventServices_ApplicationEvent(object sender, LocalEventArgs e)
        {
            ListViewItem item = new ListViewItem((this.eventLogList.Items.Count + 1).ToString());
            item.SubItems.Add("Local");
            item.SubItems.Add(e.EventType);
            item.SubItems.Add(e.Details);
            this.eventLogList.Items.Insert(0, item);
      }

        protected void EventServices_TimerEvent(object sender, EventArgs e)
        {
            RemoteEventArgs args = new RemoteEventArgs();
            args.EventType = "Timer";
            args.Details = DateTime.Now.ToShortTimeString();

            this.UiSubscriptionLog(args);
        }

        protected void EventServices_RpmsEvent(object sender, RemoteEventArgs e)
        {
            this.UiSubscriptionLog(e);
        }

        public void UiSubscriptionLog(RemoteEventArgs e)
        {
            ListViewItem item = new ListViewItem((this.eventLogList.Items.Count + 1).ToString());
            item.SubItems.Add("Remote");
            item.SubItems.Add(e.EventType);
            item.SubItems.Add(e.Details);
            this.eventLogList.Items.Insert(0, item);
        }

        void EventServices_RefreshRequested(object sender, EventArgs e)
        {
            LocalEventArgs args = new LocalEventArgs();
            args.EventType = "REFRESH";
            this.EventServices_ApplicationEvent(null, args);
        
            this.UpdateLabels();
        }

        private void UpdateLabels()
        {
            try
            {
                if (this.LocalSession == null)
                {
                    this.userNameLabel.Text =
                        this.patientLabel.Text =
                            this.visitLabel.Text =
                                this.divisionLabel.Text = "Not connected to BMX Framework";

                    this.grid.DataSource = null;
                }
                else
                {
                    this.enableRemoteEvents.Checked = this.RemoteSession.EventServices.IsEventPollingEnabled;
      
                    //LocalSession and RemoteSession should have the write info
                    this.userNameLabel.Text = this.RemoteSession.User == null ? "No user" : this.RemoteSession.User.Name;
                    this.divisionLabel.Text = this.RemoteSession.User == null ? "No division" : this.RemoteSession.User.Division.Name;
                    this.patientLabel.Text = this.LocalSession.Context.HasPatient ? this.LocalSession.Context.Patient.PatientName : "No patient";
                    this.visitLabel.Text = this.LocalSession.Context.HasVisit ? this.LocalSession.Context.Visit.ToString() : "No visit";

                    try
                    {
                        string rawQuery = this.queryEntry.Text;
                        string query = rawQuery;
                        if (this.LocalSession.Context.HasPatient)
                        {
                            rawQuery.Replace("@P", this.LocalSession.Context.Patient.Ien);
                        }
                        if (this.LocalSession.Context.HasVisit)
                        {
                            query = rawQuery.Replace("@V", this.LocalSession.Context.Visit.Ien);
                        }
                        query = rawQuery.Replace("@U", this.LocalSession.User.Duz);
                        this.queryLabel.Text = query;
                        this.grid.DataSource = this.RemoteSession.TableFromCommand(query);


                        this.queryEntry.BackColor = Color.LightGreen;
                    }
                    catch
                    {
                        this.grid.DataSource = null;
                        this.queryEntry.BackColor = Color.Red;
                    }
                }

                this.lastUpdateLabel.Text = DateTime.Now.ToLongTimeString();
            }
            catch (Exception p)
            {
                MessageBox.Show(p.StackTrace);
            }
        }

        private String _configurationParameter = "Not connected to BMX Framework";

        public String ConfigurationParameter
        {
            get { return _configurationParameter; }
            set
            {
                this._configurationParameter = value;
                this.UpdateLabels();
            }
        }
        void Context_Changed(object sender, IndianHealthService.BMXNet.Model.ContextChangedArgs e)
        {
            this.UpdateLabels();
        }

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

        private List<string> _localSubscriptions = new List<string>();

        public List<string> LocalSubscriptions
        {
            get { return _localSubscriptions; }
            set { _localSubscriptions = value; }
        }


        private List<string> _subscriptions = new List<string>();

        public List<string> Subscriptions
        {
            get { return _subscriptions; }
            set { _subscriptions = value; }
        }

        public String FireEventName
        {
            get { return this.fireEventEntry.Text.Trim(); }
        }


        public String SubscriptionEventName
        {
            get { return this.subscriptionEvent.Text.Trim(); }
        }

        private void subscribeButton_Click(object sender, EventArgs e)
        {
            if ((this.SubscriptionEventName.Length > 0) && !this.Subscriptions.Contains(this.SubscriptionEventName))
            {
                int result = this.RemoteSession.EventServices.Subscribe(this.SubscriptionEventName);
                this.Subscriptions.Add(this.SubscriptionEventName);
                this.UpdateEventList();
            }
        }

        private void UpdateEventList()
        {

            this.subscriptionList.BeginUpdate();
            this.subscriptionList.Items.Clear();
            foreach (String each in this.Subscriptions)
            {
                this.subscriptionList.Items.Add(each);
            }
            this.subscriptionList.EndUpdate();

            this.localSubscriptions.BeginUpdate();
            this.localSubscriptions.Items.Clear();
            foreach (String each in this.LocalSubscriptions)
            {
                this.localSubscriptions.Items.Add(each);
            }
            this.localSubscriptions.EndUpdate();
        }

        private void unsubscribeButton_Click(object sender, EventArgs e)
        {
            if (this.Subscriptions.Contains(this.SubscriptionEventName))
            {
                this.RemoteSession.EventServices.Unsubscribe(this.SubscriptionEventName);
                this.Subscriptions.Remove(this.SubscriptionEventName);
                this.UpdateEventList();
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (this.FireEventName.Length > 0)
            {
                this.RemoteSession.EventServices.TriggerEvent(this.FireEventName, this.parameterEntry.Text.Trim(), this.raiseBackCheckbox.Checked);
            }
        }

        private void subscriptionList_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.subscriptionEvent.Text = this.subscriptionList.SelectedItem.ToString();
            this.fireEventEntry.Text = this.subscriptionList.SelectedItem.ToString();
        }

        private void pollingTrack_ValueChanged(object sender, EventArgs e)
        {
            this.RemoteSession.EventServices.EventPollingInterval = this.pollingTrack.Value * 1000;
            this.UpdatePollingLabel();
        }

        protected void UpdatePollingLabel()
        {
            this.pollingLabel.Text = "Polling Interval: " + ((int)(this.RemoteSession.EventServices.EventPollingInterval / 1000)).ToString().PadLeft(4);
        }

        private void enableRemoteEvents_CheckedChanged(object sender, EventArgs e)
        {
            this.RemoteSession.EventServices.IsEventPollingEnabled = this.enableRemoteEvents.Checked;
        }

        private void queryEntry_TextChanged_1(object sender, EventArgs e)
        {

        }

        private void fireLocalEntry_TextChanged(object sender, EventArgs e)
        {
        }


        private void localSubscribeButton_Click(object sender, EventArgs e)
        {
            String eventName = this.localEvent.Text.Trim();
            if ((eventName.Length > 0) && !this.LocalSubscriptions.Contains(eventName))
            {
                this.LocalSession.EventServices.Subscribe(eventName);
                this.LocalSubscriptions.Add(eventName);
                this.UpdateEventList();
            }
        }

        private void localUnsubscribeButton_Click(object sender, EventArgs e)
        {
            String eventName = this.localEvent.Text.Trim();
            if (this.LocalSubscriptions.Contains(eventName))
            {
                this.LocalSession.EventServices.Unsubscribe(eventName);
                this.LocalSubscriptions.Remove(eventName);
                this.UpdateEventList();
            }
        }

        private void localSubscriptions_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.localEvent.Text = this.localSubscriptions.SelectedItem.ToString();
            this.fireLocalEvent.Text = this.localSubscriptions.SelectedItem.ToString();
        }


        public String LocalFireEventName
        {
            get { return this.fireLocalEvent.Text.Trim(); }
        }


        private void triggerLocalButton_Click(object sender, EventArgs e)
        {
            if (this.LocalFireEventName.Length > 0)
            {
                this.LocalSession.EventServices.TriggerEvent(this.LocalFireEventName, this.fireLocalParameter.Text.Trim());

            }
        }

        private void vetoCheckBox_CheckedChanged(object sender, EventArgs e)
        {

        }
    }
}