using System;
using System.IO;
using System.Text;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Controls;
using System.Security.Cryptography;
using System.Net;
using System.Xml;
using System.Drawing.Imaging;
using RestSharp;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace Web_Service_Toolbox
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    /// 
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls |
                                                  SecurityProtocolType.Tls11 |
                                                  SecurityProtocolType.Tls12 |
                                                  SecurityProtocolType.Ssl3;

            //btnFolderItems.IsChecked = true;  // This should be the default
            btnFolderItems.IsChecked = true;
        }

        public static string getHost()
        {
            return ("apex-prd.certna.org");
        }

        public static string getBase64Hash(string strB64Source)
        {
            Encoding u8 = Encoding.UTF8; // We use UTF8 encoding

            byte[] b64Bytes = u8.GetBytes(strB64Source); // Put the Document B64 string into a byte array

            byte[] b64HashBytes = SHA384.Create().ComputeHash(b64Bytes);  // Compute the SHA384 hash

            //Convert the SHA384 hash to a Base64 string

            string strB64Value = System.Convert.ToBase64String(b64HashBytes, 0, b64HashBytes.Length);

            return strB64Value;
        }

        public static string GetSalt(string srcUserName)
        {
            RestClient client = null;
            RestRequest request = null;
            IRestResponse response = null;

            string strSalt = null;

            string strURL = "https://" + getHost() + "/APEX/Service/APEXPublicServer.svc/user/" + srcUserName + "/salt"; 

            client = new RestClient(strURL);
            request = new RestRequest(Method.GET);

            request.AddHeader("Cache-Control", "no-cache");
            request.AddHeader("Content-Type", "application/json");
            response = client.Execute(request);

            if (response.IsSuccessful)
            {

                var jsonResult1 = JsonConvert.DeserializeObject<dynamic>(response.Content);
                strSalt = jsonResult1.salt;
            }

            return strSalt;
        }


        public static string HashPassword(string srcPassword, string srcSalt)
        {
            var combinedPassword = srcPassword + srcSalt;

            SHA256Managed sha256Managed = new SHA256Managed();
            UTF8Encoding utf8Encoding = new UTF8Encoding();

            // Would normally be enclosedin a try/catch block.

            return Convert.ToBase64String(sha256Managed.ComputeHash(utf8Encoding.GetBytes(combinedPassword)));
        }

        private void btnBrowseLocalFolders_Click(object sender, RoutedEventArgs e)
        {
            FolderBrowserDialog fbd = new FolderBrowserDialog();
            DialogResult rc = fbd.ShowDialog();

            string strPath = fbd.SelectedPath;

            tbLocalFolderName.Text = strPath;
        }

        private void getFolderFileDetails(string strFolderName)
        {
            RestClient client = null;
            RestRequest request = null;
            IRestResponse response = null;

            string strURL = "https://" + getHost() + "/APEX/Service/APEXPublicServer.svc/user/login";

            // Password has to be hashed.
            // New convention uses a Salt value from the user record

            string strSalt = GetSalt(tbUserName.Text);
            string strPassword = tbPassword.Password.ToString();

            string strHashedPassword = HashPassword(strPassword, strSalt);

            string strParms = "{\n\t\"user_name\" : \"";
            strParms += tbUserName.Text;
            strParms += "\",\n\t\"password\" : \"";
            strParms += strHashedPassword;
            strParms += "\"\n}";

            client = new RestClient(strURL);
            request = new RestRequest(Method.POST);

            request.AddHeader("Cache-Control", "no-cache");
            request.AddHeader("Content-Type", "application/json");

            request.AddParameter("Login", strParms, ParameterType.RequestBody);
            response = client.Execute(request);

            if (response.IsSuccessful)
            {
                var jsonResult1 = JsonConvert.DeserializeObject<dynamic>(response.Content);
                string token = jsonResult1.access_token;

                strURL = null;
                client = null;
                request = null;
                response = null;

                strURL = "https://" + getHost() + "/APEX/Service/APEXPublicServer.svc/payloads/" + strFolderName; 

                client = new RestClient(strURL);
                request = new RestRequest(Method.GET);

                request.AddHeader("Cache-Control", "no-cache");
                request.AddHeader("access_token", token);
                response = client.Execute(request);

                if (response.IsSuccessful)
                {
                    JObject joResponse = JObject.Parse(response.Content);
                    JArray array = (JArray)joResponse["result"];

                    // Load the grid

                    resultGrid.Children.Clear();
                    resultGrid.RowDefinitions.Clear();

                    resultGrid.RowDefinitions.Add(new RowDefinition());

                    if (array.Count == 0)
                    {
                        tbMessageLine.Text = "*** No Transactions Found In The Selected Reposository ***";
                    }
                    else
                    {
                        TextBlock[] txtCreated = new TextBlock[array.Count+1];
                        TextBlock[] txtFileName = new TextBlock[array.Count+1];
                        TextBlock[] txtLockStatus = new TextBlock[array.Count+1];
                        TextBlock[] txtModified = new TextBlock[array.Count+1];

                        // Header row

                        txtCreated[0] = new TextBlock();
                        txtCreated[0].Padding = new Thickness(0, 5, 25, 5);
                        txtCreated[0].Text = "Created";
                        Grid.SetRow(txtCreated[0], 0);
                        Grid.SetColumn(txtCreated[0], 0);
                        resultGrid.Children.Add(txtCreated[0]);
                        txtFileName[0] = new TextBlock();
                        txtFileName[0].Padding = new Thickness(0, 5, 25, 5);
                        txtFileName[0].Text = "File Name";
                        Grid.SetRow(txtFileName[0], 0);
                        Grid.SetColumn(txtFileName[0], 1);
                        resultGrid.Children.Add(txtFileName[0]);
                        txtLockStatus[0] = new TextBlock();
                        txtLockStatus[0].Padding = new Thickness(0, 5, 25, 5);
                        txtLockStatus[0].Text = "Lock Status";
                        Grid.SetRow(txtLockStatus[0], 0);
                        Grid.SetColumn(txtLockStatus[0], 2);
                        resultGrid.Children.Add(txtLockStatus[0]);
                        txtModified[0] = new TextBlock();
                        txtModified[0].Padding = new Thickness(0, 5, 25, 5);
                        txtModified[0].Text = "Modified Date";
                        Grid.SetRow(txtModified[0], 0);
                        Grid.SetColumn(txtModified[0], 3);
                        resultGrid.Children.Add(txtModified[0]);

                        for (int i = 1; i <= array.Count; i++)
                        {
                            resultGrid.RowDefinitions.Add(new RowDefinition());

                            txtCreated[i] = new TextBlock();
                            txtCreated[i].Padding = new Thickness(0, 5, 25, 5);
                            txtCreated[i].Text = (String)array[i - 1]["created"];
                            Grid.SetRow(txtCreated[i], i);
                            Grid.SetColumn(txtCreated[i], 0);
                            resultGrid.Children.Add(txtCreated[i]);
                            txtFileName[i] = new TextBlock();
                            txtFileName[i].Padding = new Thickness(0, 5, 25, 5);
                            //txtFileName[i].Text = (String)array[i - 1]["file_name"] + ".xml";
                            txtFileName[i].Text = (String)array[i - 1]["file_name"];
                            Grid.SetRow(txtFileName[i], i);
                            Grid.SetColumn(txtFileName[i], 1);
                            resultGrid.Children.Add(txtFileName[i]);
                            txtLockStatus[i] = new TextBlock();
                            txtLockStatus[i].Padding = new Thickness(0, 5, 25, 5);
                            txtLockStatus[i].Text = (String)array[i - 1]["lock_status"];
                            Grid.SetRow(txtLockStatus[i], i);
                            Grid.SetColumn(txtLockStatus[i], 2);
                            resultGrid.Children.Add(txtLockStatus[i]);
                            txtModified[i] = new TextBlock();
                            txtModified[i].Padding = new Thickness(0, 5, 25, 5);
                            txtModified[i].Text = (String)array[i - 1]["modified"];
                            Grid.SetRow(txtModified[i], i);
                            Grid.SetColumn(txtModified[i], 3);
                            resultGrid.Children.Add(txtModified[i]);
                        }
                    }
                }
                else
                {
                    var jsonResult2 = JsonConvert.DeserializeObject<dynamic>(response.Content);
                    string strMessage = jsonResult2.Exception.Message;
                    tbMessageLine.Text = strMessage;
                }
            }
            else
            {
                var jsonResult2 = JsonConvert.DeserializeObject<dynamic>(response.Content);
                tbMessageLine.Text = jsonResult2.ToString();
            }
        }

        private string[] getRepositoryFileNames(string strRepositoryName)
        {
            string[] strFileNames = null;

            RestClient client = null;
            RestRequest request = null;
            IRestResponse response = null;

            string strURL = "https://" + getHost() + "/APEX/Service/APEXPublicServer.svc/user/login";

            // Password has to be hashed.
            // New convention uses a Salt value from the user record

            string strSalt = GetSalt(tbUserName.Text);
            string strPassword = tbPassword.Password.ToString();

            string strHashedPassword = HashPassword(strPassword, strSalt);

            string strParms = "{\n\t\"user_name\" : \"";
            strParms += tbUserName.Text;
            strParms += "\",\n\t\"password\" : \"";
            strParms += strHashedPassword;
            strParms += "\"\n}";

            client = new RestClient(strURL);
            request = new RestRequest(Method.POST);

            request.AddHeader("Cache-Control", "no-cache");
            request.AddHeader("Content-Type", "application/json");

            request.AddParameter("Login", strParms, ParameterType.RequestBody);
            response = client.Execute(request);

            if (response.IsSuccessful)
            {
                var jsonResult1 = JsonConvert.DeserializeObject<dynamic>(response.Content);
                string token = jsonResult1.access_token;

                strURL = null;
                client = null;
                request = null;
                response = null;

                strURL = "https://" + getHost() + "/APEX/Service/APEXPublicServer.svc/payloads/" + strRepositoryName; 

                client = new RestClient(strURL);
                request = new RestRequest(Method.GET);

                request.AddHeader("Cache-Control", "no-cache");
                request.AddHeader("access_token", token);
                response = client.Execute(request);

                if (response.IsSuccessful)
                {
                    JObject joResponse = JObject.Parse(response.Content);
                    JArray array = (JArray)joResponse["result"];

                    strFileNames = new string[array.Count];

                    for (int i = 0; i < array.Count; i++)
                    {
                        //strFileNames[i] = (String)array[i]["file_name"] + ".xml";
                        strFileNames[i] = (String)array[i]["file_name"];
                    }
                }
                else
                {
                    var jsonResult2 = JsonConvert.DeserializeObject<dynamic>(response.Content);
                    string strMessage = jsonResult2.Exception.Message;
                    tbMessageLine.Text = strMessage;
                }
            }
            else
            {
                var jsonResult2 = JsonConvert.DeserializeObject<dynamic>(response.Content);
                tbMessageLine.Text = jsonResult2.ToString();
            }
            return (strFileNames);
        }

        private bool LockUnlockRemoteFile(string strRepositoryType, string strFileName, string strAction)
        {
            bool rc = false;  //Default

            if (strAction == "lock")
            {
                tbMessageLine.Text = "Locking remote file " + strFileName;
            }
            else if (strAction == "unlock")
            {
                tbMessageLine.Text = "Unlocking remote file " + strFileName;
            }
            else
            {
                tbMessageLine.Text = "";
            }

            RestClient client = null;
            RestRequest request = null;
            IRestResponse response = null;

            string strURL = "https://" + getHost() + "/APEX/Service/APEXPublicServer.svc/user/login";

            // Password has to be hashed.
            // New convention uses a Salt value from the user record

            string strSalt = GetSalt(tbUserName.Text);
            string strPassword = tbPassword.Password.ToString();

            string strHashedPassword = HashPassword(strPassword, strSalt);

            string strParms = "{\n\t\"user_name\" : \"";
            strParms += tbUserName.Text;
            strParms += "\",\n\t\"password\" : \"";
            strParms += strHashedPassword;
            strParms += "\"\n}";

            client = new RestClient(strURL);
            request = new RestRequest(Method.POST);

            request.AddHeader("Cache-Control", "no-cache");
            request.AddHeader("Content-Type", "application/json");

            request.AddParameter("Login", strParms, ParameterType.RequestBody);
            response = client.Execute(request);

            if (response.IsSuccessful)
            {
                var jsonResult1 = JsonConvert.DeserializeObject<dynamic>(response.Content);
                string token = jsonResult1.access_token;

                strURL = null;
                client = null;
                request = null;
                response = null;

                strURL = "https://" + getHost() + "/APEX/Service/APEXPublicServer.svc/payloads/" + strRepositoryType + "/" + strFileName + "?operation=" + strAction;  

                client = new RestClient(strURL);
                request = new RestRequest(Method.PATCH);

                request.AddHeader("Cache-Control", "no-cache");
                request.AddHeader("access_token", token);
                response = client.Execute(request);

                if (response.IsSuccessful)
                {
                    if (strAction == "lock")
                    {
                        tbMessageLine.Text = "Remote file " + strFileName + " successfully locked.";
                    }
                    else if (strAction == "unlock")
                    {
                        tbMessageLine.Text = "Remote file " + strFileName + " successfully unlocked.";
                    }
                    else
                    {
                        tbMessageLine.Text = "";
                    }
                    rc = true;
                }
                else
                {
                    var jsonResult2 = JsonConvert.DeserializeObject<dynamic>(response.Content);
                    string strMessage = jsonResult2.Exception.Message;
                    tbMessageLine.Clear();
                    tbMessageLine.Text = strMessage;
                }
            }
            else
            {
                var jsonResult2 = JsonConvert.DeserializeObject<dynamic>(response.Content);
                tbMessageLine.Text = jsonResult2.ToString();
            }
            return (rc);
        }

        private void DownloadRemoteFile(string strRepositoryType, string strFileName, string strLocalFolder)
        {
            tbMessageLine.Text = "";

            RestClient client = null;
            RestRequest request = null;
            IRestResponse response = null;

            string strURL = "https://" + getHost() + "/APEX/Service/APEXPublicServer.svc/user/login";

            // Password has to be hashed.
            // New convention uses a Salt value from the user record

            string strSalt = GetSalt(tbUserName.Text);
            string strPassword = tbPassword.Password.ToString();

            string strHashedPassword = HashPassword(strPassword, strSalt);

            string strParms = "{\n\t\"user_name\" : \"";
            strParms += tbUserName.Text;
            strParms += "\",\n\t\"password\" : \"";
            strParms += strHashedPassword;
            strParms += "\"\n}";

            client = new RestClient(strURL);
            request = new RestRequest(Method.POST);

            request.AddHeader("Cache-Control", "no-cache");
            request.AddHeader("Content-Type", "application/json");

            request.AddParameter("Login", strParms, ParameterType.RequestBody);
            response = client.Execute(request);

            if (response.IsSuccessful)
            {
                var jsonResult1 = JsonConvert.DeserializeObject<dynamic>(response.Content);
                string token = jsonResult1.access_token;

                strURL = null;
                client = null;
                request = null;
                response = null;

                strURL = "https://" + getHost() + "/APEX/Service/APEXPublicServer.svc/payloads/" + strRepositoryType + "/" + strFileName;  

                client = new RestClient(strURL);
                request = new RestRequest(Method.GET);

                request.AddHeader("Cache-Control", "no-cache");
                request.AddHeader("access_token", token);
                request.AddHeader("Content-Type", "text/plain");
                response = client.Execute(request);

                if (response.IsSuccessful)
                {
                    XmlReader myXmlReader = XmlReader.Create(new MemoryStream(Encoding.UTF8.GetBytes(response.Content)));
                    XmlDocument xmlDoc = new XmlDocument();
                    xmlDoc.Load(myXmlReader);
                    xmlDoc.Save(strLocalFolder + "\\" + strFileName);
                }
                else
                {
                    var jsonResult2 = JsonConvert.DeserializeObject<dynamic>(response.Content);
                    string strMessage = jsonResult2.Exception.Message;
                    tbMessageLine.Text = strMessage;
                }
            }
            else
            {
                var jsonResult2 = JsonConvert.DeserializeObject<dynamic>(response.Content);
                tbMessageLine.Text = jsonResult2.ToString();
            }
        }

        private bool SendFile(string strRepositoryType, string strFileName)
        {
            tbMessageLine.Text = "";

            bool rc = false;

            RestClient client = null;
            RestRequest request = null;
            IRestResponse response = null;

            string strURL = "https://" + getHost() + "/APEX/Service/APEXPublicServer.svc/user/login";

            // Password has to be hashed.
            // New convention uses a Salt value from the user record

            string strSalt = GetSalt(tbUserName.Text);
            string strPassword = tbPassword.Password.ToString();

            string strHashedPassword = HashPassword(strPassword, strSalt);

            string strParms = "{\n\t\"user_name\" : \"";
            strParms += tbUserName.Text;
            strParms += "\",\n\t\"password\" : \"";
            strParms += strHashedPassword;
            strParms += "\"\n}";

            client = new RestClient(strURL);
            request = new RestRequest(Method.POST);

            request.AddHeader("Cache-Control", "no-cache");
            request.AddHeader("Content-Type", "application/json");

            request.AddParameter("Login", strParms, ParameterType.RequestBody);
            response = client.Execute(request);

            if (response.IsSuccessful)
            {
                tbMessageLine.Text = "Sending XML file "+strFileName;

                var jsonResult1 = JsonConvert.DeserializeObject<dynamic>(response.Content);
                string token = jsonResult1.access_token;

                FileStream fs = new FileStream(strFileName, FileMode.Open, FileAccess.Read);

                XmlDocument xmlDoc = new XmlDocument();

                xmlDoc.Load(fs);

                strURL = null;
                client = null;
                request = null;
                response = null;

                strURL = "https://" + getHost() + "/APEX/Service/APEXPublicServer.svc/payloads/" + strRepositoryType;  

                client = new RestClient(strURL);
                request = new RestRequest(Method.POST);

                request.AddHeader("Cache-Control", "no-cache");
                request.AddHeader("access_token", token);
                request.AddHeader("content-type", "text/plain");
                request.AddParameter("undefined", xmlDoc.InnerXml, ParameterType.RequestBody);
                response = client.Execute(request);

                if (response.IsSuccessful)
                {
                    var jsonResult2 = JsonConvert.DeserializeObject<dynamic>(response.Content);
                    string strRemoteFileName = jsonResult2.result;
                    string strAction = "finalize"; // You must finalize the remote file to change the extension from .tmp to .xml

                    strURL = null;
                    client = null;
                    request = null;
                    response = null;

                    strURL = "https://" + getHost() + "/APEX/Service/APEXPublicServer.svc/payloads/" + strRepositoryType + "/" + strRemoteFileName + "?operation=" + strAction;  

                    client = new RestClient(strURL);
                    request = new RestRequest(Method.PATCH);

                    request.AddHeader("Cache-Control", "no-cache");
                    request.AddHeader("access_token", token);
                    response = client.Execute(request);

                    if (response.IsSuccessful)
                    {
                        tbMessageLine.Text = "XML file " + strFileName+" successfully sent.";
                        rc = true;
                    }
                    else
                    {
                        var jsonResult3 = JsonConvert.DeserializeObject<dynamic>(response.Content);
                        string strMessage = jsonResult3.Exception.Message;
                        tbMessageLine.Text = strMessage;
                    }
                }
                else
                {
                    var jsonResult2 = JsonConvert.DeserializeObject<dynamic>(response.Content);
                    string strMessage = jsonResult2.Exception.Message;
                    tbMessageLine.Text = strMessage;
                }
            }
            else
            {
                var jsonResult2 = JsonConvert.DeserializeObject<dynamic>(response.Content);
                tbMessageLine.Text = jsonResult2.ToString();
            }

            return (rc);
        }

        private bool DeleteRemoteFile(string strRepositoryType, string strFileName)
        {
            tbMessageLine.Text = "Deleting remote file " + strFileName;

            bool rc = false;

            RestClient client = null;
            RestRequest request = null;
            IRestResponse response = null;

            string strURL = "https://" + getHost() + "/APEX/Service/APEXPublicServer.svc/user/login";

            // Password has to be hashed.
            // New convention uses a Salt value from the user record

            string strSalt = GetSalt(tbUserName.Text);
            string strPassword = tbPassword.Password.ToString();

            string strHashedPassword = HashPassword(strPassword, strSalt);

            string strParms = "{\n\t\"user_name\" : \"";
            strParms += tbUserName.Text;
            strParms += "\",\n\t\"password\" : \"";
            strParms += strHashedPassword;
            strParms += "\"\n}";

            client = new RestClient(strURL);
            request = new RestRequest(Method.POST);

            request.AddHeader("Cache-Control", "no-cache");
            request.AddHeader("Content-Type", "application/json");

            request.AddParameter("Login", strParms, ParameterType.RequestBody);
            response = client.Execute(request);

            if (response.IsSuccessful)
            {
                var jsonResult1 = JsonConvert.DeserializeObject<dynamic>(response.Content);
                string token = jsonResult1.access_token;

                strURL = null;
                client = null;
                request = null;
                response = null;

                strURL = "https://" + getHost() + "/APEX/Service/APEXPublicServer.svc/payloads/" + strRepositoryType + "/" + strFileName; 

                client = new RestClient(strURL);
                request = new RestRequest(Method.DELETE);

                request.AddHeader("Cache-Control", "no-cache");
                request.AddHeader("access_token", token);
                response = client.Execute(request);

                if (response.IsSuccessful)
                {
                    tbMessageLine.Text = "Remote file " + strFileName + " successfully retrieved. Remote file deleted.";
                    rc = true;
                }
                else
                {
                    var jsonResult2 = JsonConvert.DeserializeObject<dynamic>(response.Content);
                    string strMessage = jsonResult2.Exception.Message;
                    tbMessageLine.Text = strMessage;
                }
            }
            else
            {
                var jsonResult2 = JsonConvert.DeserializeObject<dynamic>(response.Content);
                tbMessageLine.Text = jsonResult2.ToString();
            }

            return (rc);
        }

        private void btnFolderItems_Checked(object sender, RoutedEventArgs e)
        {
            tbMessageLine.Text = "";

            spSendRetrieve.Visibility = Visibility.Hidden;
            spLockUnlock.Visibility = Visibility.Hidden;
            spFolderItems.Visibility = Visibility.Visible;
            spCheckStatus.Visibility = Visibility.Hidden;
        }

        private void btnSendRetrieve_Checked(object sender, RoutedEventArgs e)
        {
            tbMessageLine.Text = "";

            spFolderItems.Visibility = Visibility.Hidden;
            spLockUnlock.Visibility = Visibility.Hidden;
            spSendRetrieve.Visibility = Visibility.Visible;
            spCheckStatus.Visibility = Visibility.Hidden;
        }

        private void btnLockUnlock_Checked(object sender, RoutedEventArgs e)
        {
            tbMessageLine.Text = "";

            spFolderItems.Visibility = Visibility.Hidden;
            spSendRetrieve.Visibility = Visibility.Hidden;
            spLockUnlock.Visibility = Visibility.Visible;
            spCheckStatus.Visibility = Visibility.Hidden;
        }
        private void btnCheckStatus_Checked(object sender, RoutedEventArgs e)
        {
            ResetTransactionPanels();

            spFolderItems.Visibility = Visibility.Hidden;
            spSendRetrieve.Visibility = Visibility.Hidden;
            spLockUnlock.Visibility = Visibility.Hidden;
            spCheckStatus.Visibility = Visibility.Visible;
        }
        private void cbFolderName_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            tbMessageLine.Text = "";

            string strSelectedFolder = ((sender as System.Windows.Controls.ComboBox).SelectedItem as ComboBoxItem).Content as string;
            getFolderFileDetails(strSelectedFolder);
        }

        private void cbRepositoryName_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            tbMessageLine.Text = "";

            string strSelectedRepository = ((sender as System.Windows.Controls.ComboBox).SelectedItem as ComboBoxItem).Content as string;
            string[] strRepositoryFileNames = getRepositoryFileNames(strSelectedRepository);

            if (strRepositoryFileNames != null)
            {
                cbFileNames.Items.Clear();

                for (int i = 0; i < strRepositoryFileNames.Length; i++)
                {
                    cbFileNames.Items.Add(strRepositoryFileNames[i]);
                }
            }
        }

        private void tbPrimaryReference_TextChanged(object sender, TextChangedEventArgs e)
        {
            ResetTransactionPanels();
        }

        private void chkTransactionHistory_Click(object sender, RoutedEventArgs e)
        {
            ResetTransactionPanels();
        }

        private void btnSend_Click(object sender, RoutedEventArgs e)
        {
            string strRepository = (cbRepository.SelectedItem as ComboBoxItem).Content as string;
            string strLocalFolder = tbLocalFolderName.Text;

            string[] strFolderFileNames = Directory.GetFiles(strLocalFolder);

            if (strFolderFileNames != null)
            {
                for (int i = 0; i < strFolderFileNames.Length; i++)
                {
                    bool rc = SendFile(strRepository, strFolderFileNames[i]);  // Send the file (The file names are fully qualified.)
                }
            }
        }
        private void btnRetrieve_Click(object sender, RoutedEventArgs e)
        {
            bool rc;

            string strLocalFolder = tbLocalFolderName.Text;
            string strRepository = (cbRepository.SelectedItem as ComboBoxItem).Content as string;
            string[] strFolderFileNames = getRepositoryFileNames(strRepository);

            if (strFolderFileNames != null)
            {
                for (int i = 0; i < strFolderFileNames.Length; i++)
                {
                    rc = LockUnlockRemoteFile(strRepository, strFolderFileNames[i], "lock"); // You must lock the file before you can do any operations on it.
                    DownloadRemoteFile(strRepository, strFolderFileNames[i], strLocalFolder);  // Retrieve the file
                    rc = DeleteRemoteFile(strRepository, strFolderFileNames[i]); // After successfully retrieving the file it should be removed from the remote repository.
                }
            }
        }

        private void btnLock_Click(object sender, RoutedEventArgs e)
        {
            string strRepository = (cbRepositoryName.SelectedItem as ComboBoxItem).Content as string;
            string strSelectedFile = cbFileNames.SelectedItem.ToString();
            bool rc = LockUnlockRemoteFile(strRepository, strSelectedFile, "lock"); // You must lock the file before you can do any operations on it.
        }

        private void btnUnlock_Click(object sender, RoutedEventArgs e)
        {
            string strRepository = (cbRepositoryName.SelectedItem as ComboBoxItem).Content as string;
            string strSelectedFile = cbFileNames.SelectedItem.ToString();
            bool rc = LockUnlockRemoteFile(strRepository, strSelectedFile, "unlock"); // You must lock the file before you can do any operations on it.
        }

        private void btnDelete_Click(object sender, RoutedEventArgs e)
        {
            string strRepository = (cbRepositoryName.SelectedItem as ComboBoxItem).Content as string;
            string strSelectedFile = cbFileNames.SelectedItem.ToString();
            bool rc = LockUnlockRemoteFile(strRepository, strSelectedFile, "lock"); // You must lock the file before you can delete it.
            rc = DeleteRemoteFile(strRepository, strSelectedFile);
        }

        private void btnGetStatus_Click(object sender, RoutedEventArgs e)
        {
            RestClient client = null;
            RestRequest request = null;
            IRestResponse response = null;

            ResetTransactionPanels();

            string strURL = "https://" + getHost() + "/APEX/Service/APEXPublicServer.svc/user/login";

            // Password has to be hashed.
            // New convention uses a Salt value from the user record

            string strSalt = GetSalt(tbUserName.Text);
            string strPassword = tbPassword.Password.ToString();

            string strHashedPassword = HashPassword(strPassword, strSalt);

            string strParms = "{\n\t\"user_name\" : \"";
            strParms += tbUserName.Text;
            strParms += "\",\n\t\"password\" : \"";
            strParms += strHashedPassword;
            strParms += "\"\n}";

            client = new RestClient(strURL);
            request = new RestRequest(Method.POST);

            request.AddHeader("Cache-Control", "no-cache");
            request.AddHeader("Content-Type", "application/json");

            request.AddParameter("Login", strParms, ParameterType.RequestBody);
            response = client.Execute(request);

            if (response.IsSuccessful)
            {
                var jsonResult1 = JsonConvert.DeserializeObject<dynamic>(response.Content);
                string token = jsonResult1.access_token;

                if (chkTransactionHistory.IsChecked == true)
                {
                    strURL = "https://" + getHost() + "/APEX/Service/APEXPublicServer.svc/transaction?submitter_id=" + tbSubmitterID.Text + "&primary_reference=" + tbPrimaryReference.Text + "&include_history=true";
                }
                else
                {
                    strURL = "https://" + getHost() + "/APEX/Service/APEXPublicServer.svc/transaction?submitter_id=" + tbSubmitterID.Text + "&primary_reference=" + tbPrimaryReference.Text + "&include_history=false";
                }

                client = new RestClient(strURL);
                request = new RestRequest(Method.GET);

                request.AddHeader("Cache-Control", "no-cache");
                request.AddHeader("access_token", token);
                response = client.Execute(request);

                if (response.IsSuccessful)
                {
                    if (chkTransactionHistory.IsChecked == true)
                    {
                        panelTranDetails.Visibility = Visibility.Visible;
                        panelTranHistory.Visibility = Visibility.Visible;
                    }
                    else
                    {
                        panelTranDetails.Visibility = Visibility.Visible;
                        panelTranHistory.Visibility = Visibility.Hidden;
                    }

                    var jsonResult2 = JsonConvert.DeserializeObject<dynamic>(response.Content);

                    tbTransactionID.Text = jsonResult2.result.TRANSACTION_ID;
                    tbPrimaryRef.Text = jsonResult2.result.PRIMARY_REFERENCE;
                    tbSecondaryRef.Text = jsonResult2.result.SECONDARY_REFERENCE;
                    tbCountyName.Text = jsonResult2.result.COUNTY_NAME;
                    tbSubID.Text = jsonResult2.result.SUBMITTER_ID;
                    tbAgentID.Text = jsonResult2.result.AGENT_ID;
                    tbCreatorUserName.Text = jsonResult2.result.CREATOR_USER_NAME;
                    tbDateCreated.Text = jsonResult2.result.CREATED;
                    tbLastModified.Text = jsonResult2.result.LAST_MODIFIED;
                    tbStatusID.Text = jsonResult2.result.TRANSACTION_STATUS_ID;
                    tbStatusName.Text = jsonResult2.result.TRANSACTION_STATUS;

                    if (chkTransactionHistory.IsChecked == true)
                    {
                        JObject joResponse = JObject.Parse(response.Content);
                        JArray jaHistory = (JArray)joResponse["result"]["TRANSACTION_STATUS_HISTORY"];

                        // Load the grid

                        historyGrid.Children.Clear();
                        historyGrid.RowDefinitions.Clear();

                        historyGrid.RowDefinitions.Add(new RowDefinition());

                        if (jaHistory.Count == 0)
                        {
                            tbMessageLine.Text = "*** No Transaction History Available ***";
                        }
                        else
                        {
                            TextBlock[] txtStatusCode = new TextBlock[jaHistory.Count + 1];
                            TextBlock[] txtStatusName = new TextBlock[jaHistory.Count + 1];
                            TextBlock[] txtTimeStamp = new TextBlock[jaHistory.Count + 1];

                            // Header row

                            txtStatusCode[0] = new TextBlock();
                            txtStatusCode[0].Padding = new Thickness(0, 5, 25, 5);
                            txtStatusCode[0].Text = "Code";
                            Grid.SetRow(txtStatusCode[0], 0);
                            Grid.SetColumn(txtStatusCode[0], 0);
                            historyGrid.Children.Add(txtStatusCode[0]);
                            txtStatusName[0] = new TextBlock();
                            txtStatusName[0].Padding = new Thickness(0, 5, 25, 5);
                            txtStatusName[0].Text = "Status";
                            Grid.SetRow(txtStatusName[0], 0);
                            Grid.SetColumn(txtStatusName[0], 1);
                            historyGrid.Children.Add(txtStatusName[0]);
                            txtTimeStamp[0] = new TextBlock();
                            txtTimeStamp[0].Padding = new Thickness(0, 5, 25, 5);
                            txtTimeStamp[0].Text = "Timestamp";
                            Grid.SetRow(txtTimeStamp[0], 0);
                            Grid.SetColumn(txtTimeStamp[0], 2);
                            historyGrid.Children.Add(txtTimeStamp[0]);

                            for (int i = 1; i <= jaHistory.Count; i++)
                            {
                                historyGrid.RowDefinitions.Add(new RowDefinition());

                                txtStatusCode[i] = new TextBlock();
                                txtStatusCode[i].Padding = new Thickness(0, 5, 25, 5);
                                txtStatusCode[i].Text = (String)jaHistory[i - 1]["TRANSACTION_STATUS_ID"];
                                Grid.SetRow(txtStatusCode[i], i);
                                Grid.SetColumn(txtStatusCode[i], 0);
                                historyGrid.Children.Add(txtStatusCode[i]);
                                txtStatusName[i] = new TextBlock();
                                txtStatusName[i].Padding = new Thickness(0, 5, 25, 5);
                                txtStatusName[i].Text = (String)jaHistory[i - 1]["TRANSACTION_STATUS"];
                                Grid.SetRow(txtStatusName[i], i);
                                Grid.SetColumn(txtStatusName[i], 1);
                                historyGrid.Children.Add(txtStatusName[i]);
                                txtTimeStamp[i] = new TextBlock();
                                txtTimeStamp[i].Padding = new Thickness(0, 5, 25, 5);
                                txtTimeStamp[i].Text = (String)jaHistory[i - 1]["TIMESTAMP"];
                                Grid.SetRow(txtTimeStamp[i], i);
                                Grid.SetColumn(txtTimeStamp[i], 2);
                                historyGrid.Children.Add(txtTimeStamp[i]);
                            }
                        }
                    }
                }
                else
                {
                    var jsonResult2 = JsonConvert.DeserializeObject<dynamic>(response.Content);
                    string strMessage = jsonResult2.Exception.Message;
                    tbMessageLine.Text = strMessage;
                }
            }
            else
            {
                var jsonResult2 = JsonConvert.DeserializeObject<dynamic>(response.Content);
                tbMessageLine.Text = jsonResult2.ToString();
            }
            return;

        }

        private void ResetTransactionPanels()
        {
            tbMessageLine.Text = "";
            tbTransactionID.Text = "";
            tbPrimaryRef.Text = "";
            tbSecondaryRef.Text = "";
            tbCountyName.Text = "";
            tbSubID.Text = "";
            tbAgentID.Text = "";
            tbCreatorUserName.Text = "";
            tbDateCreated.Text = "";
            tbLastModified.Text = "";
            tbStatusID.Text = "";
            tbStatusName.Text = "";

            historyGrid.Children.Clear();
            historyGrid.RowDefinitions.Clear();

            panelTranDetails.Visibility = Visibility.Hidden;
            panelTranHistory.Visibility = Visibility.Hidden;
        }

    }
}
