using AgentWebservicesClient.AgentContactWS;
using Nortel.CCT;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using System.Windows.Forms;


namespace AgentWebservicesClient
{
    public partial class Form1 : Form
    {
        private bool loggedIn;
        private AgentUtilityWS.AgentUtilityWS utilityWS = new AgentWebservicesClient.AgentUtilityWS.AgentUtilityWS();
        private AgentContactWS.AgentContactWS contactWS = new AgentWebservicesClient.AgentContactWS.AgentContactWS();
        private AgentEmailWS.AgentEmailWS emailWS = new AgentWebservicesClient.AgentEmailWS.AgentEmailWS();
        private AgentWebCommWS.AgentWebCommWS webWS = new AgentWebservicesClient.AgentWebCommWS.AgentWebCommWS();
        private AWContact contact;
        private string sessionKey = "";
        private string contactID = "";
        private Toolkit cctToolkit = null;
        private ISession cctSession = null;
        private ContactScopeEventHandler cctContactScopeEventHandler = null;
        private TerminalPropertyEventHandler cctTerminalPropertyEventHandler = null;
        private AgentWebservicesClient.AgentEmailWS.AWAttachment[] AttachmentsList;
        private long webContactID;
        private DateTime m_dtReadTime;
        private bool bCreatingNewMail = false;
        private bool bHtmlMail = true;
        string tempMessage = "";
        string strWebChat = "";

        // Values for Web Chat
        //NumericValue	TextValue
        //1	            Chat Message from Customer
        //2	            Chat Message from Agent
        //3	            Page Pushed by Customer
        //4	            Page Pushed by Agent
        //5	            Form Shared by Customer
        //6	            Form Shared by Agent
        //7	            CallMe Request from Customer
        //8	            Page Previewed by Customer
        //9	            Page Previewed by Agent
        //10	        Session Disconnected by Customer
        //11	        Session Disconnected by Agent

        enum WebChat {Chat_Message_from_Customer, 
                      Chat_Message_from_Agent, 
                      Page_Pushed_by_Customer,
                      Page_Pushed_by_Agent, 
                      Form_Shared_by_Customer, 
                      Form_Shared_by_Agent, 
                      CallMe_Request_from_Customer,
                      Page_Previewed_by_Customer, 
                      Page_Previewed_by_Agent, 
                      Session_Disconnected_by_Customer,
                      Session_Disconnected_by_Agent}



        public Form1()
        {
            InitializeComponent();
            txtUsername.Focus();
        }

        #region CCMM & UI

        private void Login()
        {
            if (!loggedIn)
            {
                try
                {
                    utilityWS.AgentDesktopLogoff(txtUsername.Text);
                }
                catch { }
                if (txtUsername.Text != "" && txtPassword.Text != "")
                {
                    try
                    {
                        sessionKey = utilityWS.AgentDesktopLogin(txtUsername.Text, txtPassword.Text);                        
                        btnLogin.Text = "Logoff";
                        loggedIn = true;
                        txtPassword.Enabled = false;
                        txtUsername.Enabled = false;
                        txtContactID.Enabled = true;
                        btnReadContact.Enabled = true;
                        btnNew.Enabled = true;

                        cmbClosedReasonCode.Items.Clear();
                        foreach (AWClosedReasonCode code in contactWS.GetAllClosedReasonCodes(sessionKey))
                        {
                            cmbClosedReasonCode.Items.Add(code);
                        }
                        if (cmbClosedReasonCode.Items.Count > 0)
                            cmbClosedReasonCode.Enabled = true;

                        cmbClosedReasonCode.DisplayMember = "name";
                        cmbClosedReasonCode.ValueMember = "numericvalue";
                    }

                    catch (Exception ex)
                    {
                        if (ex.Message.ToLower().Contains("no data exists in code mapping table"))
                            MessageBox.Show("Note: No Closed Reason Codes have been configured on the CCMM server.", "No CRCs found");
                        else
                            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    }

                    try
                    {


                        cmbSkillsets.Items.Clear();
                        foreach (AgentEmailWS.AWSkillset ss in emailWS.GetAllSkillSets(sessionKey))
                        {
                            cmbSkillsets.Items.Add(ss);
                        }

                        cmbSkillsets.DisplayMember = "name";
                        cmbSkillsets.ValueMember = "id";

                        txtContactID.Focus();
                    }
                    catch (Exception ex)
                    {
                        if (ex.Message.ToLower().Contains("no data exists in code mapping table"))
                            MessageBox.Show("Note: No Closed Reason Codes have been configured on the CCMM server.", "No CRCs found");
                        else
                            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    }
                }
            }
            else
            {
                utilityWS.AgentDesktopLogoff(txtUsername.Text);
                ClearText();
                txtContactID.Clear();

                sessionKey = "";
                contact = null;
                contactID = "0";
                loggedIn = false;
                btnLogin.Text = "Login";
                txtPassword.Enabled = true;
                txtUsername.Enabled = true;

                ButtonsEnabled(false);
                btnSend.Enabled = false;

                txtUsername.Focus();
            }
        }

        private void ButtonsEnabled(bool enabled)
        {
            txtContactID.Enabled = enabled;
            btnReadContact.Enabled = enabled;

            txtFrom.Enabled = enabled;
            txtTo.Enabled = enabled;
            txtCC.Enabled = enabled;
            txtBCC.Enabled = enabled;
            txtSubject.Enabled = enabled;
            txtBody.Enabled = enabled;
            treeActions.Enabled = enabled;

            btnCancel.Enabled = enabled;
            btnCloseContact.Enabled = enabled;
            txtClosedComment.Enabled = enabled;
            cmbClosedReasonCode.Enabled = enabled;
            btnForward.Enabled = enabled;
            btnReply.Enabled = enabled;
            btnReplyAll.Enabled = enabled;
            btnNew.Enabled = enabled;
        }

        private void TextReadonly(bool enabled)
        {
            txtFrom.ReadOnly = enabled;
            txtTo.ReadOnly = enabled;
            txtCC.ReadOnly = enabled;
            txtBCC.ReadOnly = enabled;
            txtSubject.ReadOnly = enabled;
            txtBody.ReadOnly = enabled;
        }

        private void ClearText()
        {
            txtFrom.Clear();
            txtTo.Clear();
            txtCC.Clear();
            txtBCC.Clear();
            txtSubject.Clear();
            txtBody.Clear();
            txtAttach.Clear();
            treeActions.Nodes.Clear();
            txtClosedComment.Clear();
            lblContactArrivalText.Text = "";
            lblPriorityText.Text = "";
            lblSkillsetText.Text = "";
            lblStatusText.Text = "";
            lblFromTopText.Text = "";
            lblToTopText.Text = "";
            lblCCTopText.Text = "";
            lblOriginalSubjectText.Text = "";
        }

        private void CloseOpenContact()
        {
            ClearText();
            ButtonsEnabled(false);

            btnReadContact.Enabled = true;
            txtContactID.Enabled = true;
            cmbClosedReasonCode.SelectedIndex = -1;
        }

        private void ReadContact()
        {
            try
            {
                ClearText();
                cmbClosedReasonCode.SelectedIndex = -1; // reset closed reason dropdown

                // contactID = (long)Convert.ToInt32(txtContactID.Text);
                contactID = txtContactID.Text;
                contact = contactWS.ReadContact(contactID, sessionKey);
                ButtonsEnabled(true);
                TextReadonly(true);

                txtContactID.Enabled = false;
                btnReadContact.Enabled = false;

                if (contact.actionList != null && contact.actionList.Length > 0)
                {
                    txtSubject.Text = contact.actionList[0].subject;
                    txtBody.Text = contact.actionList[0].text;
                    txtFrom.Text = contact.actionList[0].mailFrom;
                    txtTo.Text = contact.actionList[0].mailTo;
                    txtBCC.Text = contact.actionList[0].mailBCC;
                    txtCC.Text = contact.actionList[0].mailCC;
                    if (contact.actionList[0].attachmentList != null)
                        PopulateAttachmentTextbox(contact.actionList[0].attachmentList);

                    AWClosedReasonCode lastActionClosedReason = null;
                    string lastActionClosedReasonComment = "";
                    foreach (AWAction action in contact.actionList)
                    {
                        DateTime creationTime = new DateTime(1970, 1, 1, 0, 0, 0).AddMilliseconds(action.creationTime.milliseconds);
                        TreeNode tn = new TreeNode(action.id.ToString() + " - " + action.subject + " - " + creationTime.ToString());
                        treeActions.Nodes.Add(tn);
                        if (action.closedReason != null)
                        {
                            lastActionClosedReason = action.closedReason;
                        }
                        lastActionClosedReasonComment = action.comment;
                    }
                    if (lastActionClosedReason != null)
                    {
                        foreach (AWClosedReasonCode closedReason in cmbClosedReasonCode.Items)
                        {
                            if (closedReason.numericValue == lastActionClosedReason.numericValue)
                            {
                                cmbClosedReasonCode.SelectedItem = closedReason;
                            }
                        }
                    }
                    txtClosedComment.Text = lastActionClosedReasonComment;
                }

                lblFromTopText.Text = contact.MailFrom;
                lblToTopText.Text = contact.MailTo;
                lblCCTopText.Text = contact.MailCC;
                lblOriginalSubjectText.Text = contact.originalSubject;
                DateTime arrivalTime = new DateTime(1970, 1, 1, 0, 0, 0).AddMilliseconds(contact.arrivalTime.milliseconds);
                lblContactArrivalText.Text = arrivalTime.ToString();
                lblPriorityText.Text = contact.priority.ToString();
                lblSkillsetText.Text = contact.skillset.name;
                lblStatusText.Text = contact.status.ToString();
                if (contact.status == AWContactStatus.Closed)
                {
                    btnCloseContact.Enabled = false;
                    txtClosedComment.Enabled = false;
                    cmbClosedReasonCode.Enabled = false;
                    btnForward.Enabled = false;
                    btnReply.Enabled = false;
                    btnReplyAll.Enabled = false;
                    btnAttach.Enabled = false;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                ButtonsEnabled(true);
            }
        }

        private void txtPassword_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Return)
            {
                Login();
            }
        }

        private void btnLogin_Click(object sender, EventArgs e)
        {
            Login();
        }

        private void txtContactID_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Return)
            {
                ReadContact();
            }
        }

        private void btnReadContact_Click(object sender, EventArgs e)
        {
            ReadContact();
        }

        private void btnCloseContact_Click(object sender, EventArgs e)
        {
            try
            {
                if (cmbClosedReasonCode.SelectedItem != null)
                {
                    contactWS.CloseContact(contactID, txtClosedComment.Text, ((AWClosedReasonCode)cmbClosedReasonCode.SelectedItem).numericValue, true, sessionKey);
                }
                //else
                //{
                //    contactWS.CloseContact(contactID, txtClosedComment.Text, 0, false, sessionKey);
                //}
                CloseOpenContact();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            if (btnSend.Enabled)
            {
                if (bCreatingNewMail)
                {
                    ButtonsEnabled(false);
                    txtContactID.Enabled = true;
                    btnReadContact.Enabled = true;

                    btnAttach.Enabled = false;
                    txtAttach.Text = "";
                    txtBody.Text = "";
                    txtSubject.Text = "";
                    txtFrom.Text = "";
                    txtTo.Text = "";
                    txtCC.Text = "";
                    txtBCC.Text = "";
                    btnNew.Enabled = true;
                    btnSend.Enabled = false;

                    bCreatingNewMail = false;
                }
                else
                {
                    ButtonsEnabled(true);
                    txtContactID.Enabled = false;
                    btnReadContact.Enabled = false;
                    if (contact.status == AWContactStatus.Closed)
                    {
                        btnCloseContact.Enabled = false;
                        txtClosedComment.Enabled = false;
                        cmbClosedReasonCode.Enabled = false;
                    }

                    if (treeActions.Nodes.Count > 0)
                    {
                        treeActions.SelectedNode = treeActions.Nodes[0];
                    }
                    string actionid = treeActions.SelectedNode.Text.Substring(0, treeActions.SelectedNode.Text.IndexOf(" - "));
                    foreach (AWAction action in contact.actionList)
                    {
                        if (action.id.ToString() == actionid)
                        {
                            txtBody.Text = action.text;
                            txtSubject.Text = action.subject;
                            txtFrom.Text = action.mailFrom;
                            txtTo.Text = action.mailTo;
                            txtCC.Text = action.mailCC;
                            txtBCC.Text = action.mailBCC;
                        }
                    }

                    btnSend.Enabled = false;
                    btnAttach.Enabled = false;
                }
            }
            else
            {
                CloseOpenContact();
                contact = null;
                contactID = "0";
            }
        }

        private void btnNew_Click(object sender, EventArgs e)
        {
            ButtonsEnabled(false);
            txtBody.Clear();
            txtAttach.Clear();
            txtBody.Enabled = true;
            txtTo.Enabled = true;
            txtTo.ReadOnly = false;
            txtFrom.Enabled = true;
            txtFrom.ReadOnly = false;
            txtCC.Enabled = true;
            txtCC.ReadOnly = false;
            txtBCC.Enabled = true;
            txtBCC.ReadOnly = false;
            txtBody.ReadOnly = false;
            txtSubject.Enabled = true;
            txtSubject.ReadOnly = false;
            btnCancel.Enabled = true;
            btnNew.Enabled = false;
            //btnReplyAll.Enabled = true;
            //btnForward.Enabled = true;
            btnSend.Enabled = true;
            btnAttach.Enabled = true;
            txtCharSet.Enabled = true;

            if (cmbSkillsets.Items.Count > 0)
                cmbSkillsets.Enabled = true;

            if (cmbClosedReasonCode.Items.Count > 0)
                cmbClosedReasonCode.Enabled = true;

            bCreatingNewMail = true;
        }

        private void btnReply_Click(object sender, EventArgs e)
        {
            ButtonsEnabled(false);
            txtBody.Clear();
            txtAttach.Clear();
            txtBody.Enabled = true;
            txtBody.ReadOnly = false;
            txtSubject.Enabled = true;
            txtSubject.ReadOnly = false;
            btnCancel.Enabled = true;

            btnReplyAll.Enabled = true;
            btnForward.Enabled = true;
            btnSend.Enabled = true;
            btnAttach.Enabled = true;
        }

        private void btnReplyAll_Click(object sender, EventArgs e)
        {
            ButtonsEnabled(false);
            txtBody.Clear();
            txtAttach.Clear();
            txtBody.Enabled = true;
            txtBody.ReadOnly = false;
            txtSubject.Enabled = true;
            txtSubject.ReadOnly = false;
            btnCancel.Enabled = true;

            btnReply.Enabled = true;
            btnForward.Enabled = true;
            btnSend.Enabled = true;
            btnAttach.Enabled = true;
        }

        private void btnForward_Click(object sender, EventArgs e)
        {
            ButtonsEnabled(false);
            txtBody.Clear();
            txtAttach.Clear();
            txtBody.Enabled = true;
            txtBody.ReadOnly = false;
            txtSubject.Enabled = true;
            txtSubject.ReadOnly = false;
            txtTo.Enabled = true;
            txtTo.ReadOnly = false;
            txtCC.Enabled = true;
            txtCC.ReadOnly = false;
            txtBCC.Enabled = true;
            txtBCC.ReadOnly = false;
            btnCancel.Enabled = true;
            btnAttach.Enabled = true;

            btnReplyAll.Enabled = true;
            btnReply.Enabled = true;
            btnSend.Enabled = true;
        }

        private void treeActions_AfterSelect(object sender, TreeViewEventArgs e)
        {
            string actionid = treeActions.SelectedNode.Text.Substring(0, treeActions.SelectedNode.Text.IndexOf(" - "));
            foreach (AWAction action in contact.actionList)
            {
                if (action.id.ToString() == actionid)
                {
                    txtBody.Text = action.text;
                    txtSubject.Text = action.subject;
                    txtFrom.Text = action.mailFrom;
                    txtTo.Text = action.mailTo;
                    txtCC.Text = action.mailCC;
                    txtBCC.Text = action.mailBCC;
                    if (action.attachmentList != null)
                        PopulateAttachmentTextbox(action.attachmentList);
                }
            }
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            if (bCreatingNewMail)   // It's a new (originated) mail
            {
                // set up some defaults
                string skillsetID = "0";
                string CRCid = "0";
                if (cmbSkillsets.SelectedIndex > -1)
                {
                    skillsetID = ((AgentEmailWS.AWSkillset)cmbSkillsets.SelectedItem).id.ToString();
                }
                else
                {
                    MessageBox.Show("You must select a Skillset before sending new mails. \n(Note also that if the selected skillset " +
                        "does not have an associated outbox in CCMM Administrator, your mail will not be sent.", "Select Skillset", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                    return;
                }

                // CRC can be left at 0, if none selected
                if (cmbClosedReasonCode.SelectedIndex > -1)
                {
                    CRCid = ((AWClosedReasonCode)cmbClosedReasonCode.SelectedItem).numericValue.ToString();
                    // MessageBox.Show("CRC ID = " + CRCid);
                }


                string[] contactsCreated = new string[0]; // for receiving return value from call to OriginateMail()

                // Now call the web method - either with or without attachments
                if (txtAttach.Text != "") 
                {
                    if(bHtmlMail)
                    {
                        contactsCreated = emailWS.OriginateMailWithAttachmentsHtml(txtSubject.Text.Trim(), txtBody.Text.Trim(), txtTo.Text.Trim(), txtCC.Text.Trim(), txtBCC.Text.Trim(), txtFrom.Text.Trim(),
                            txtCharSet.Text.Trim(), txtUsername.Text.Trim(), skillsetID,
                            CRCid, sessionKey, AttachmentsList);
                    }
                    else
                    {
                        contactsCreated = emailWS.OriginateMailWithAttachments(txtSubject.Text.Trim(), txtBody.Text.Trim(), txtTo.Text.Trim(), txtCC.Text.Trim(), txtBCC.Text.Trim(), txtFrom.Text.Trim(),
                               txtCharSet.Text.Trim(), txtUsername.Text.Trim(), skillsetID,
                               CRCid, sessionKey, AttachmentsList);

                    }
                    
                }
                
                else
                { 
                    if(bHtmlMail)
                    {
                        contactsCreated = emailWS.OriginateMailHtml(txtSubject.Text.Trim(), txtBody.Text.Trim(), txtTo.Text.Trim(), txtCC.Text.Trim(), txtBCC.Text.Trim(), txtFrom.Text.Trim(),
                           txtCharSet.Text.Trim(), txtUsername.Text.Trim(), skillsetID,
                           CRCid, sessionKey);
                    }
                    else
                    {
                        contactsCreated = emailWS.OriginateMail(txtSubject.Text.Trim(), txtBody.Text.Trim(), txtTo.Text.Trim(), txtCC.Text.Trim(), txtBCC.Text.Trim(), txtFrom.Text.Trim(),
                           txtCharSet.Text.Trim(), txtUsername.Text.Trim(), skillsetID,
                           CRCid, sessionKey);
                    }
                }
                // reset flag and controls
                bCreatingNewMail = false;
                cmbSkillsets.Enabled = false;
                txtCharSet.Enabled = false;

                // Now show (the first, if many) created contact in the UI
                int iHowMany = contactsCreated.Length;
                if (iHowMany > 0)
                {
                    MessageBox.Show(contactsCreated.Length + (iHowMany > 1 ? " contacts were" : " contact was") + " created. Displaying the first...");
                    txtContactID.Text = contactsCreated[0];
                    ReadContact();
                }
                else
                {
                    MessageBox.Show("Web Service did not create any contacts.");
                }
            }

            // It's a reply to an existing contact
            else if (!btnReply.Enabled)
            {
                if (txtAttach.Text != "")
                    if(bHtmlMail)
                    {
                        emailWS.ReplyWithAttachmentsHtml(contactID, txtSubject.Text, txtBody.Text, sessionKey, AttachmentsList);
                    }
                    else
                    {
                        emailWS.ReplyWithAttachments(contactID, txtSubject.Text, txtBody.Text, sessionKey, AttachmentsList);
                    }
                else
                {
                    if(bHtmlMail)
                    {
                        emailWS.ReplyHtml(contactID, txtSubject.Text, txtBody.Text, sessionKey);
                    }
                    else
                    {
                        emailWS.Reply(contactID, txtSubject.Text, txtBody.Text, sessionKey);
                    }

                }
                    

                ReadContact();
            }
            // It's a Reply All to an existing contact
            else if (!btnReplyAll.Enabled)
            {
                if (txtAttach.Text != "")
                {
                    if (bHtmlMail)
                    {
                        emailWS.ReplyAllWithAttachmentsHtml(contactID, txtSubject.Text, txtBody.Text, sessionKey, AttachmentsList);
                    }
                    else
                    {
                        emailWS.ReplyAllWithAttachments(contactID, txtSubject.Text, txtBody.Text, sessionKey, AttachmentsList);
                    }
                    
                }
                else
                {
                    if(bHtmlMail)
                    {
                        emailWS.ReplyAllHtml(contactID, txtSubject.Text, txtBody.Text, sessionKey);
                    }
                    else
                    {
                        emailWS.ReplyAll(contactID, txtSubject.Text, txtBody.Text, sessionKey);
                    }
                    
                }

                ReadContact();
            }
            // It's a Forward of an existing contact
            else if (!btnForward.Enabled)
            {
                if (txtAttach.Text != "")
                {
                    if(bHtmlMail)
                    {
                        emailWS.ForwardWithAttachmentsHtml(contactID, txtSubject.Text, txtBody.Text, txtTo.Text, txtCC.Text, txtBCC.Text, sessionKey, AttachmentsList);
                    }
                    else
                    {
                        emailWS.ForwardWithAttachments(contactID, txtSubject.Text, txtBody.Text, txtTo.Text, txtCC.Text, txtBCC.Text, sessionKey, AttachmentsList);
                    }                    
                }                    
                else
                {
                    if(bHtmlMail)
                    {
                        emailWS.ForwardHtml(contactID, txtSubject.Text, txtBody.Text, txtTo.Text, txtCC.Text, txtBCC.Text, sessionKey);
                    }
                    else
                    {
                        emailWS.Forward(contactID, txtSubject.Text, txtBody.Text, txtTo.Text, txtCC.Text, txtBCC.Text, sessionKey);
                    }                    
                }
                    

                ReadContact();
            }
        }

        #endregion

        #region CCT

        private void btnConnect_Click(object sender, EventArgs e)
        {
            cctToolkit = new Toolkit();
            cctToolkit.Server = Properties.Settings.Default.CCTServer;
            cctToolkit.Port = 29373;

            cctToolkit.Credentials = new CCTCredentials();
            CredentialsForm form = new CredentialsForm(cctToolkit.Credentials);

            if (form.ShowDialog(this) == DialogResult.OK)
            {
                cctToolkit.Credentials = form.GetCredentials();

                cctToolkit.SessionDisconnected += new SessionDisconnectedEventHandler(OnSessionDisconnectedEvent);

                cctSession = cctToolkit.Connect();

                cctContactScopeEventHandler = cctToolkit.CreateEventHandler(new ContactScopeEventHandler(OnContactScopeChanged));
                cctSession.ContactEnteringScope += cctContactScopeEventHandler;
                cctTerminalPropertyEventHandler = cctToolkit.CreateEventHandler(new TerminalPropertyEventHandler(OnTerminalPropertyEvent));
                cctSession.TerminalPropertyChanged += cctTerminalPropertyEventHandler;

                btnDisconnect.Enabled = true;
                btnConnect.Enabled = false;
                btnCctLogin.Enabled = true;
            }
            else
            {
                MessageBox.Show("Connection Failed", "No Credentials Entered", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }

        private void cctLogin_Click(object sender, EventArgs e)
        {
            IAgent[] cctAgents = cctSession.Agents;
            ITerminal[] cctTerminals = cctSession.Terminals;
            List<IAgentTerminal> agentTerminalList = new List<IAgentTerminal>();

            foreach (ITerminal terminal in cctTerminals)
            {
                IAgentTerminal agentTerminal = terminal as IAgentTerminal;
                if (agentTerminal != null)
                {
                    if (agentTerminal.State == ResourceState.InService)
                    {
                        agentTerminalList.Add(agentTerminal);
                    }
                }
            }

            int i = 0;
            if (agentTerminalList.Count >= cctAgents.Length)
            {
                foreach (IAgent cctAgent in cctAgents)
                {
                    if (cctAgent.IsLoggedIn)
                    {
                        cctAgent.Logout();
                    }
                    cctAgent.StaticVoiceTerminal = (IAgentTerminal)agentTerminalList[i];
                    i++;
                    cctAgent.Login(AgentState.Ready);
                }
            }
            else
            {
                // We've run out of agent Terminals to associate with agents
                MessageBox.Show("Login Failed", "Terminals not in service", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }

        private void OnSessionDisconnectedEvent(SessionDisconnectedEventArgs e)
        {
            cctDisconnect();
        }

        private void OnTerminalPropertyEvent(TerminalPropertyEventArgs e)
        {
            if (e.ChangedProperty == AgentTerminalProperty.AgentLoggedOut)
            {
                BeginInvoke((MethodInvoker)delegate
                    {
                        btnCctLogin.Enabled = true;
                    });
                BeginInvoke((MethodInvoker)delegate
                   {
                       lblReady.Text = "Not Logged In";
                   });
            }
            else if (e.ChangedProperty == AgentTerminalProperty.AgentLoggedIn)
            {
                BeginInvoke((MethodInvoker)delegate
                    {
                        btnCctLogin.Enabled = false;
                    });
                BeginInvoke((MethodInvoker)delegate
                   {
                       lblReady.Text = "Ready";
                   });
            }
            else if (e.ChangedProperty == AgentTerminalProperty.ReadyStatus)
            {
                IAgent[] cctAgents = cctSession.Agents;
                foreach (IAgent cctAgent in cctAgents)
                {
                    if (cctAgent.IsReady)
                    {
                        BeginInvoke((MethodInvoker)delegate
                           {
                               lblReady.Text = "Ready";
                           });
                    }
                    else
                    {
                        BeginInvoke((MethodInvoker)delegate
                           {
                               lblReady.Text = "Not Ready";
                           });
                    }
                }
            }
        }

        private void OnContactScopeChanged(ContactScopeEventArgs e)
        {
            if (e.EnteringScope)
            {
                IContact contact = e.Contact;
                foreach (string item in contact.ContactTypes)
                {
                    if (item.ToLower().Equals("email"))
                    {
                        if (DialogResult.OK.Equals(MessageBox.Show("A new email contact has arrived - id:" + contact.ID + "\n Do you wish to read it?", "New Multimedia Contact", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation)))
                        {
                            string id = contact.ID;
                            ReadNewContactCallback = new ReadNewContactDelegate(ReadNewContact);
                            ReadNewContactCallback(id);
                        }
                    }
                }
            }
        }

        public delegate void ReadNewContactDelegate(string id);
        public ReadNewContactDelegate ReadNewContactCallback;

        private void ReadNewContact(string id)
        {
            // Make sure we're on the UI thread
            if (!this.InvokeRequired)
            {
                txtContactID.Text = id;
                btnReadContact.PerformClick();
            }
            else
            {
                this.BeginInvoke(ReadNewContactCallback, new object[] { id });
            }
        }

        private void btnDisconnect_Click(object sender, EventArgs e)
        {
            cctDisconnect();
        }

        private void cctDisconnect()
        {
            try
            {
                cctToolkit.Disconnect();
            }
            catch { }
            cctToolkit = null;
            cctSession = null;

            cctContactScopeEventHandler = null;
            cctTerminalPropertyEventHandler = null;
            BeginInvoke((MethodInvoker)delegate
                {
                    btnCctLogin.Enabled = false;
                });
            BeginInvoke((MethodInvoker)delegate
                {
                    btnDisconnect.Enabled = false;
                });
            BeginInvoke((MethodInvoker)delegate
                {
                    btnConnect.Enabled = true;
                });
            BeginInvoke((MethodInvoker)delegate
                {
                    lblReady.Text = "Not Logged In";
                });
        }

        #endregion

        private void btnAttach_Click(object sender, EventArgs e)
        {
            try
            {

                dlgAttachment.Filter = "All files (*.*)|*.*|Text files (*.txt)|*.txt|HTML files (*.htm;*.html)|*.htm;*.html";
                dlgAttachment.FilterIndex = 1;
                dlgAttachment.Multiselect = true;

                if (dlgAttachment.ShowDialog() == DialogResult.OK)
                    AddToAttachmentsList();

            }
            catch (Exception Ex)
            {
                MessageBox.Show("Error on Attach button click: " + Ex);
            }
        }

        private void AddToAttachmentsList()
        {
            try
            {
                AttachmentsList = new AgentWebservicesClient.AgentEmailWS.AWAttachment[dlgAttachment.FileNames.Length];
                txtAttach.Text = "";

                for (int inx = 0; inx < dlgAttachment.FileNames.Length; inx++)
                {
                    string sFileName = dlgAttachment.FileNames[inx];
                    FileInfo tempFI = new FileInfo(sFileName);
                    long tempFileSize = tempFI.Length;

                    if (tempFileSize > 1048576) // 1MB, (arbitrary) limit for test client 
                    {
                        MessageBox.Show(sFileName + " is too large.\n  For this test client, file sizes are limited to 1MB", "FILE IS TOO LARGE", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    else
                    {
                        AgentWebservicesClient.AgentEmailWS.AWAttachment latestAttachment = new AgentWebservicesClient.AgentEmailWS.AWAttachment();

                        latestAttachment.displayFileName = getFileName(sFileName);
                        latestAttachment.internalFileName = latestAttachment.displayFileName;

                        AgentWebservicesClient.AgentEmailWS.AWCodeMapping cmDirection = new AgentWebservicesClient.AgentEmailWS.AWCodeMapping();
                        cmDirection.fieldName = "AttachmentDirection";
                        cmDirection.textValue = "OutAttachShare";  	// Inbound attachments use "InAttachShare"
                        cmDirection.numericValue = 1;			// Inbound use 2
                        cmDirection.numericValueSpecified = true;
                        latestAttachment.direction = cmDirection;
                        latestAttachment.fileContents = File.ReadAllBytes(sFileName);

                        AttachmentsList[inx] = latestAttachment;

                    }
                }
                UpdateAttachmentsDisplay();
            }
            catch (Exception Ex)
            {
                MessageBox.Show("Error attaching file: " + Ex);
            }
        }


        public void UpdateAttachmentsDisplay()
        {
            try
            {
                // Clear the current text box.
                txtAttach.Text = string.Empty;

                // Update it by stepping through the current attachments in the AttachmentsList
                foreach (AgentWebservicesClient.AgentEmailWS.AWAttachment thisAttachment in AttachmentsList)
                {
                    txtAttach.Text += "\"" + thisAttachment.displayFileName + "\", ";
                }

                txtAttach.Text = txtAttach.Text.TrimEnd();
                txtAttach.Text = txtAttach.Text.TrimEnd(',');
            }
            catch (Exception Ex)
            {
                MessageBox.Show("Error updating attachment list: " + Ex);
            }
        }

        private string getFileName(string strFullPath)
        {
            string strResult = strFullPath;

            string[] strPathArray = Regex.Split(strFullPath, @"\\");
            strResult = strPathArray[strPathArray.GetUpperBound(0)];

            return strResult;
        }

        private void PopulateAttachmentTextbox(AgentWebservicesClient.AgentContactWS.AWAttachment[] attachmentList)
        {
            txtAttach.Text = string.Empty;
            foreach (AgentWebservicesClient.AgentContactWS.AWAttachment tempAttach in attachmentList)
            {
                txtAttach.Text += "\"" + tempAttach.displayFileName + "\", ";
            }
        }

        /// <summary>
        /// Unscrambles the session key.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <returns>session key</returns>
        private static string SessionKeyUnScramble(string key)
        {
            key = key.Substring(0, key.LastIndexOf("__"));
            char[] keyArray = key.ToCharArray();

            int top = keyArray.GetUpperBound(0) - 4;
            int bottom = keyArray.GetLowerBound(0) + 2;

            return Swap(keyArray, bottom, top);
        }

        /// <summary>
        /// Swaps the specified key.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="a">A.</param>
        /// <param name="b">The b.</param>
        /// <returns></returns>
        private static string Swap(char[] key, int a, int b)
        {
            char temp = key[a];
            key[a] = key[b];
            key[b] = temp;

            return new string(key);
        }

        private void btnCreateWCSession_Click(object sender, EventArgs e)
        {
            CreateWCSession();
        }
       

        private void CreateWCSession()
        {
            if (txtContactID.Text != "")
            {
                contactID = txtContactID.Text;
                webContactID = (long)Convert.ToUInt64(contactID);

                long lresult = webWS.CreateWCSession(webContactID, sessionKey);

                //Initialise the first readtime to some value in the past to catch all messages initially.
                DateTime m_dtReadTime = new DateTime(0);
            }
        }


        private void ReadWebChatMessage(object sender, EventArgs e)
        {
            if (webContactID != 0)
            {

                AgentWebCommWS.ListOfWebCommsMessages webInCommMessage;
                webInCommMessage = webWS.ReadChatMessage(webContactID, m_dtReadTime, true, sessionKey);
                string readMessageToAdd;

                if (webInCommMessage.ListOfWebCommsMessages1 != null)
                {

                    readMessageToAdd = webInCommMessage.ListOfWebCommsMessages1[webInCommMessage.ListOfWebCommsMessages1.Length - 1].Message.ToString();
                    
                    if (tempMessage != readMessageToAdd && strWebChat != readMessageToAdd)
                    {

                        tempMessage = readMessageToAdd;

                        txtWebChatConversation.AppendText(readMessageToAdd + System.Environment.NewLine);
                        DateTime AliveTime = webWS.UpdateAliveTime(webContactID, sessionKey);
                        lblAliveTime.Text = (" The last replied at " + AliveTime);
                        m_dtReadTime = new DateTime(0);
                    }
                }

            }
        }


        private void btnWebChatSend_Click(object sender, EventArgs e)
        {
            long webOutCommMessage;
            strWebChat = txtWebChat.Text;

            webOutCommMessage = webWS.WriteChatMessage(webContactID, strWebChat, "", (long)WebChat.Chat_Message_from_Agent, sessionKey);

            txtWebChatConversation.AppendText(strWebChat + System.Environment.NewLine);
        
            txtWebChat.Clear();
            
        }

        private void btnWebChatClose_Click(object sender, EventArgs e)
        {
            long webChatCloseResult;
            string strWebClosedText = "This action records the closing of this contact by a user.";
            webChatCloseResult = webWS.CloseSession(webContactID, ((AWClosedReasonCode)cmbClosedReasonCode.SelectedItem).numericValue, txtClosedComment.Text, (long)WebChat.Session_Disconnected_by_Agent, strWebClosedText, false, sessionKey);
            txtClosedComment.Clear();
            txtWebChat.Clear();
            txtWebChatConversation.Clear();
            ReadTimeElapsed.Stop();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void splitLeftTop_Panel1_Paint(object sender, PaintEventArgs e)
        {

        }










    }
}