using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI.WebControls;
using System.Data;
using System.IO;
using System.Windows.Forms;
using Control = System.Web.UI.Control;
using Label = System.Web.UI.WebControls.Label;
using Panel = System.Web.UI.WebControls.Panel;
using TextBox = System.Web.UI.WebControls.TextBox;
using LiveSearchDemo.Entities;
using System.Text;
using SimMetrics.Net.Metric;

namespace WebApplicationUsingWebService
{
    public partial class _Default : System.Web.UI.Page
    {
        #region Constants

        const string title = "DataMatch Enterprise API Demo";

        bool useLog = false;

        const string searchConstID = "_dynSearchControls_ID";
        const string editConstID = "_dynEditControls_ID";

        const string taskTable = "TaskTable";

        const string box = "box";
        const string label = "label";

        const int highLevelDefault = 90;
        const int lowLevelDefault = 80;

        #endregion
        
        #region Methods

        private string[] getMatchingValues()
        {
            return getBoxValues(this.DynamicSearchPanel);
        }

        private string[] getMatchingFields()
        {
            return getLabelNames(this.DynamicSearchPanel);
        }

        private string[] getInsertValues()
        {
            return getBoxValues(this.DynamicEditPanel);
        }

        private string[] getBoxValues(Panel panel)
        {
            List<string> tmp = new List<string>();
            for (int i = 0; i < panel.Controls.Count; i++)
            {
                Control control = panel.Controls[i];
                if (control is TextBox)
                {
                   TextBox tb = control as TextBox;
                   tmp.Add(tb.Text);
                }
            }
            return tmp.ToArray();
        }

        private string[] getLabelNames(Panel panel)
        {
            List<string> tmp = new List<string>();
            for (int i = 0; i < panel.Controls.Count; i++)
            {
                Control control = panel.Controls[i];
                if (control is Label)
                {
                    Label label = control as Label;
                    tmp.Add(label.Text.Trim().Replace("&nbsp",""));
                }
            }
            return tmp.ToArray();
        }

        private TextBox findTextBoxById(string id)
        {
            TextBox res = null;

            var panel = DynamicSearchPanel;
            for (int i = 0; i < panel.Controls.Count; i++)
            {
                Control control = panel.Controls[i];
                if (control is TextBox)
                {
                    if (control.ID.Equals(id))
                        return control as TextBox;
                }
            }
            return res;
        }

        private void saveControlValues()
        {
            saveControlValues(DynamicSearchPanel, searchConstID);
            if (useLog)
            {
                saveControlValues(DynamicEditPanel, editConstID);
            }
        }

        private void saveControlValues(Panel panel, string constID)
        {
            List<string> dynamicValues = new List<string>();
            for (int i = 0; i < panel.Controls.Count; i++)
            {
                Control control = panel.Controls[i];
                if (control is TextBox)
                {
                    TextBox textBox = control as TextBox;
                    dynamicValues.Add(box);
                    dynamicValues.Add(textBox.ID);
                    dynamicValues.Add(textBox.Text);
                }
                if (control is Label)
                {
                    Label lbl = control as Label;
                    dynamicValues.Add(label);
                    dynamicValues.Add(lbl.ID);
                    dynamicValues.Add(lbl.Text);
                }
            }
            this.ViewState[constID] = dynamicValues;
            this.SaveViewState();
        }

        private void restoreControls(string constID, Panel panel)
        {
            panel.Controls.Clear();
            List<string> dynamicValues = this.ViewState[constID] as List<string>;
            if (dynamicValues != null)
            {
                int index = 0;
                for (int i = 0; i < dynamicValues.Count / 3; i++)
                {
                    string type = dynamicValues[index++];
                    string id = dynamicValues[index++];
                    string text = dynamicValues[index++];
                    if (panel.FindControl(id) == null)
                    {
                        if (type == box)
                        {
                            TextBox textBox = new TextBox();
                            textBox.ID = id;
                            textBox.Text = text;
                            panel.Controls.Add(textBox);
                        }
                        else if (type == label)
                        {
                            Label lbl = new Label();
                            lbl.ID = id;
                            lbl.Text = text;
                            panel.Controls.Add(lbl);
                        }
                    }
                }
            }
        }

        private void bindSearchResults()
        {
            if (Session[taskTable] != null)
            {
                ResultsGridView.Columns.Clear();
                ResultsGridView.DataSource = null;
                ResultsGridView.DataSource = Session[taskTable];
                ResultsGridView.DataBind();
            }
        }

        private void resetLabels()
        {
            ErrorLabel.Text = "...";
            TimeLabel.Text = "...";
        }

        private int getFirstDataCol()
        {
            int result = 0;
            DataTable dataTable = Session[taskTable] as DataTable;
            if (dataTable != null)
            {
                for (int i = 0; i < dataTable.Columns.Count; i++)
                {
                    string fieldName = dataTable.Columns[i].ColumnName;
                    result = i;
                    if (fieldName.ToLower().EndsWith("score"))
                    {
                        continue;
                    }
                    else
                    {
                        break;
                    }
                }
            }
            return result;
        }


        private String PerfectFormatTime(TimeSpan timeSpan)
        {
            return String.Format("{0} sec {1} ms", (Int32)timeSpan.TotalSeconds, timeSpan.Milliseconds);
        }

        #endregion

        #region Properties and Fields

        string tableName { get { return projectsRadioButtonList.SelectedValue; } }


        #endregion

        #region Events

        protected void Page_Init(object sender, EventArgs e)
        {
            String projectsFile = "projects.txt";
            String currentDir = Directory.GetCurrentDirectory();

            projectsRadioButtonList.Items.Clear();

            if (System.IO.File.Exists(projectsFile))
            {
                String[] projects = File.ReadAllLines(projectsFile);
                foreach (String projectName in projects)
                {
                    projectsRadioButtonList.Items.Add(projectName);
                }
            }
            ButtonLiveSearch.Visible = false;
            Panel1.Visible = true;
            ButtonRealTimeInsert.Visible = true;
            Panel3.Visible = false;

            string str = $"{title} {SampleServiceNamespace.ProductInfo.VersionApi} ({SampleServiceNamespace.ProductInfo.Version})";
            Title = str;
            FooterLabel.Text = str;
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            restoreControls(searchConstID, DynamicSearchPanel);
            if (useLog)
            {
                restoreControls(editConstID, DynamicEditPanel);
            }
            else
            {
                insertButton.Visible = false;
                updateButton.Visible = false;
                deleteButton.Visible = false;
            }

            bindSearchResults();
            
            if (!string.IsNullOrEmpty(tableName))
                InitButton_Click(null, null);
        }

        protected void SearchButtonClick(object sender, EventArgs e)
        {
            System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
            System.Diagnostics.Stopwatch colorizingTime = new System.Diagnostics.Stopwatch();
            string[] forValues = new string[0];
            stopwatch.Start();
            resetLabels();
            using (ServiceReference1.SampleServiceClient client = new ServiceReference1.SampleServiceClient())
            {
                
                int records;
                int.TryParse(RecordsTextBox.Text, out records);
                if (records <= 0)
                {
                    ErrorLabel.Text = "Invalid records count";
                    return;
                }

                DataTable dataTable = GetMatches(client, records, out forValues);

                stopwatch.Stop();

                if (dataTable.Rows.Count > 0)
                {
                    colorizingTime.Start();
                    string[] matchingValues = getMatchingValues();
                    string[] matchingfields = getMatchingFields();

                    int rowCnt = dataTable.Rows.Count;
                    int colCnt = dataTable.Columns.Count; ; //Number of columns

                    TableRow theader = new TableRow();
                    theader.BackColor = System.Drawing.ColorTranslator.FromHtml("#1C6EA4");
                    theader.ForeColor = System.Drawing.Color.White;

                    Table1.Rows.Add(theader);
                    for (int i = 0; i < colCnt; i++)
                    {
                        TableCell tCell = new TableCell();
                        tCell.BorderColor = System.Drawing.Color.White;
                        tCell.BorderWidth = Unit.Pixel(1);
                        tCell.Text = dataTable.Columns[i].ColumnName;
                        theader.Cells.Add(tCell);
                    }

                    for (int i = 0; i < rowCnt; i++)
                    {
                        TableRow tRow = new TableRow();
                        tRow.BorderColor = System.Drawing.Color.Black;
                        tRow.BorderWidth = Unit.Pixel(1);
                        tRow.BorderStyle = System.Web.UI.WebControls.BorderStyle.Solid;
                        Table1.Rows.Add(tRow);
                        for (int j = 0; j < colCnt; j++)
                        {
                            TableCell tCell = new TableCell();
                            tCell.BorderColor = System.Drawing.Color.Black;
                            tCell.BorderWidth = Unit.Pixel(1);
                            string txt = dataTable.Rows[i][j].ToString();
                            if (matchingfields.Contains(dataTable.Columns[j].ColumnName))
                            {
                                int index = Array.IndexOf(matchingfields, dataTable.Columns[j].ColumnName);
                                string pattern = matchingValues[index];
                                int[] weights = ColorizingAlgorithmWithJaro(pattern, txt);
                                string tmp = "";
                                for (int k = 0; k < weights.Length; k++)
                                {
                                    if (weights[k] == 1)
                                        tmp += "<span style=\"color:red;\">" + txt[k] + "</span>";
                                    else
                                        tmp += "<span>" + txt[k] + "</span>";

                                }
                                txt = tmp;
                            }
                            tCell.Text = txt;
                            tRow.Cells.Add(tCell);
                        }
                    }
                    colorizingTime.Stop();
                }
            }
            stopwatch.Stop();

            saveControlValues();

            string responceTime = "Response time (";
            for (int i = 0; i < forValues.Length; i++)
            {
                responceTime += forValues[i];
                if (i != forValues.Length - 1)
                {
                    responceTime += ", ";
                }
            }
            responceTime += "): ";

            TimeLabel.Text = responceTime + PerfectFormatTime(stopwatch.Elapsed);
        }

        #region Colorizing Algorithm
        
        //complex implementation
        private int[] ColorizingAlgorithmWithJaro(string pattern_, string sample_)
        {
            string pattern = pattern_.ToLower();
            string sample = sample_.ToLower();

            int[] weights = new int[sample.Length];

            var jaroWinkler = new JaroWinkler();
            double score = jaroWinkler.GetSimilarity(pattern, sample);

            for (int i = 0; i < sample.Length; i++)
            {
                string newSample = sample.Remove(i, 1);
                double newScore = jaroWinkler.GetSimilarity(pattern, newSample);
                if (score > newScore)
                    weights[i] = 1;
                else
                    weights[i] = 0;
            }

            return weights;
        }


        //naive implementation
        private int[] ColorizingAlgorithm(string pattern_, string sample_)
        {
            string pattern = pattern_.ToLower();
            string sample = sample_.ToLower();

            int[] weights = new int[sample.Length];
            for (int i = 0; i < sample.Length; i++)
            {
                char nowChar = sample[i];
                if (pattern.Contains(nowChar))
                {
                    int cnt1 = pattern.Where(c => c == nowChar).Count();
                    int cnt2 = sample.Where(c => c == nowChar).Count();
                    if (cnt1 == cnt2)
                    {
                        weights[i] = 2;
                    }
                    else
                    {
                        weights[i] = 1;
                    }

                    if (i == 0)
                    {
                        if (CheckAfter(pattern, sample, i)) weights[i] += 1;
                    }
                    else if (i == sample.Length - 1)
                    {
                        if (CheckBefore(pattern, sample, i)) weights[i] += 1;
                    }
                    else
                    {
                        if (CheckAfter(pattern, sample, i) || CheckBefore(pattern, sample, i))
                            weights[i] += 1;
                    }
                }
                else
                {
                    weights[i] = 0;
                }
            }

            int[] res = weights.Select(w => w > 2 ? 1 : 0).ToArray();
            return res;
        }

        private bool CheckBefore(string pattern, string sample, int i)
        {
            char first = sample[i - 1];
            char second = sample[i];
            return FindToChar(pattern, sample, first, second);
        }

        private bool CheckAfter(string pattern, string sample, int i)
        {
            if (sample.Length == 1) return false;

            char first = sample[i];
            char second = sample[i + 1];
            return FindToChar(pattern, sample, first, second);
        }

        private bool FindToChar(string pattern, string sample, char first, char second)
        {
            bool res = false;
            for (int j = 0; j < pattern.Length - 1; j++)
            {
                if (pattern[j] == first)
                    if (pattern[j + 1] == second)
                    {
                        return true;
                    }
            }
            return res;
        }
        #endregion

        private DataTable GetMatches(ServiceReference1.SampleServiceClient client, int records, out string[] forStrings)
        {
            string[] matchingValues = getMatchingValues();
            forStrings = getMatchingValues();
            string hash = SampleServiceNamespace.PortableHash.GetHash(tableName);

            string[] matches = client.GetMatches(hash, tableName, matchingValues, records);
            DataTable dataTable = new DataTable();
            if (matches.Length > 1)
            {
                dataTable = FromStringArrayToDataTable(matches);

                if (this.DynamicEditPanel.Controls.Count == 0)
                {
                    bool lastScoreColReached = false;
                    for (int i = 0; i < dataTable.Columns.Count; i++)
                    {
                        string fieldName = dataTable.Columns[i].ColumnName;
                        if (!lastScoreColReached)
                        {
                            if (fieldName.ToLower().EndsWith("score"))
                            {
                                continue;
                            }
                            else
                            {
                                lastScoreColReached = true;
                            }
                        }

                        Label label = new Label();
                        label.ID = fieldName + editConstID + "_label";
                        label.Text = fieldName;
                        this.DynamicEditPanel.Controls.Add(label);
                        TextBox textBox = new TextBox();
                        textBox.ID = fieldName + editConstID;
                        this.DynamicEditPanel.Controls.Add(textBox);
                    }
                }
            }

            return dataTable;
        }

        private DataTable FromStringArrayToDataTable(string[] strings)
        {
            DataTable dataTable = new DataTable();
            int index = 0;

            if (strings.Length > 1)
            {
                int colCount;
                if (int.TryParse(strings[index++], out colCount))
                {
                    for (int colIndex = 0; colIndex < colCount; colIndex++)
                    {
                        dataTable.Columns.Add(new DataColumn(strings[index++], typeof(string), "",
                            MappingType.Element));
                    }

                    int returnedRecords = ((strings.Length - 1) / dataTable.Columns.Count) - 1;
                    for (int i = 0; i < returnedRecords; i++)
                    {
                        DataRow dataRow = dataTable.NewRow();
                        for (int col = 0; col < colCount; col++)
                        {
                            dataRow[col] = strings[index++];
                        }

                        dataTable.Rows.Add(dataRow);
                    }
                }
            }

            return dataTable;
        }

        protected void InitButton_Click(object sender, EventArgs e)
        {
            resetLabels();
            using (ServiceReference1.SampleServiceClient client = new ServiceReference1.SampleServiceClient())
            {
                client.InnerChannel.OperationTimeout = new TimeSpan(0,10,0);

                System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
                stopwatch.Start();
                string hash = SampleServiceNamespace.PortableHash.GetHash(tableName);
                if (client.Init(hash, tableName, useLog, false))
                {
                    string[] matchFieldNames = client.GetMatchingFields(hash, tableName);
                    this.DynamicSearchPanel.Controls.Clear();
                    int length = matchFieldNames.Select(name => name.Length).Max() + 3;
                    for (int i = 0; i < matchFieldNames.Length; i++)
                    {
                        string fieldName = matchFieldNames[i];
                        Label label = new Label();
                        label.ID = fieldName + searchConstID + "_label";
                        string addition = "";
                        for (int j = 0; j < length - fieldName.Length; j++)
                        {
                            addition += "&nbsp";
                        }
                        label.Text = fieldName + addition;
                        this.DynamicSearchPanel.Controls.Add(label);

                        TextBox textBox = new TextBox();
                        string id = fieldName + searchConstID;
                        textBox.ID = id;
                        textBox.Attributes.Add("onkeyup", $"txtOnKeyPress('{id}');");
                        this.DynamicSearchPanel.Controls.Add(textBox);

                        this.DynamicSearchPanel.Controls.Add(new System.Web.UI.LiteralControl("<br/> <br/>"));
                    }

                    ErrorLabel.Text = tableName + " started...";

                    string error;
                    Int32 high, low;

                    if (Int32.TryParse(HighLevelTextBox.Text, out high))
                        if (Int32.TryParse(LowLevelTextBox.Text, out low))
                        {
                            if (client.ChangeThresholds(hash, tableName, high, low, out error))
                            {
                            }
                        }
                }
                else
                {
                    ErrorLabel.Text = tableName + " didn't start";
                }

                saveControlValues();
                TimeLabel.Text = "Response time: " + PerfectFormatTime(stopwatch.Elapsed);

            }
        }
        
        protected void testProjectButton_Click(object sender, EventArgs e)
        {
            resetLabels();
            using (ServiceReference1.SampleServiceClient client = new ServiceReference1.SampleServiceClient())
            {
                System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
                stopwatch.Start();
                string hash = SampleServiceNamespace.PortableHash.GetHash(tableName);
                if (client.IsRunning(hash, tableName))
                {
                    ErrorLabel.Text = tableName + " project is loaded and running";
                }
                else
                {
                    ErrorLabel.Text = tableName + " project is not active";
                }

                saveControlValues();
                TimeLabel.Text = "Response time: " + PerfectFormatTime(stopwatch.Elapsed);
            }
        }

        protected void unloadButton_Click(object sender, EventArgs e)
        {
            resetLabels();
            using (ServiceReference1.SampleServiceClient client = new ServiceReference1.SampleServiceClient())
            {
                System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
                stopwatch.Start();
                string hash = SampleServiceNamespace.PortableHash.GetHash(tableName);
                if (!client.IsRunning(hash, tableName))
                {
                    ErrorLabel.Text = tableName + " project is not active. It cannot be unloaded.";
                }
                else
                {
                    if (client.Unload(hash, tableName))
                    {
                        ErrorLabel.Text = tableName + " project is not active";
                    }
                }

                projectsRadioButtonList.SelectedIndex = -1;
                saveControlValues();
            }
        }

        protected void SetThresholdsButton_Click(object sender, EventArgs e)
        {
            using (ServiceReference1.SampleServiceClient client = new ServiceReference1.SampleServiceClient())
            {
                System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
                stopwatch.Start();
                string hash = SampleServiceNamespace.PortableHash.GetHash(tableName);
                if (!client.IsRunning(hash, tableName))
                {
                    ErrorLabel.Text = tableName + " project is not active. It cannot be edited.";
                }
                else
                {
                    string error;
                    string highValue = HighLevelTextBox.Text;
                    string lowValue = LowLevelTextBox.Text;
                    int high, low;
                    if (Int32.TryParse(highValue, out high))
                    {
                        if (Int32.TryParse(lowValue, out low))
                        {
                            if (client.ChangeThresholds(hash, tableName, high, low, out error))
                            {
                                ErrorLabel.Text = "Thresholds are changed";
                            }
                            else
                            {
                                ErrorLabel.Text = error;
                            }
                        }
                        else
                        {
                            ErrorLabel.Text = " Manual match level must be a number";
                        }
                    }
                    else
                    {
                        ErrorLabel.Text = "Auto match level must be a number";
                    }                    
                    
                }

                saveControlValues();
                TimeLabel.Text = "Response time: " + PerfectFormatTime(stopwatch.Elapsed);
            }
        }

        protected void insertButton_Click(object sender, EventArgs e)
        {
            System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
            stopwatch.Start();
            //ErrorLabel.Visible = false;
            resetLabels();
            using (ServiceReference1.SampleServiceClient client = new ServiceReference1.SampleServiceClient())
            {
                int records;
                int.TryParse(RecordsTextBox.Text, out records);
                if (records <= 0)
                {
                    ErrorLabel.Text = "Invalid records count";
                    return;
                }

                string[] forVals;
                DataTable dataTable = GetMatches(client, records, out forVals);

                int duplicates, strongDuplicates;
                CalculateDuplicates(dataTable, out duplicates, out strongDuplicates);
                if (strongDuplicates > 0)
                {
                    //there are duplicates, it's not unique
                    ErrorLabel.Text = "This record is not unique. Inserting was forbidden";
                    Session[taskTable] = dataTable;
                    bindSearchResults();
                }
                else if (duplicates > 0)
                {
                    //possible, there is duplicate, ask about writing
                    DuplicateGridView.Columns.Clear();
                    DuplicateGridView.DataSource = null;
                    DuplicateGridView.DataSource = dataTable;
                    DuplicateGridView.DataBind();

                    MessageAboutDuplicatesLabel.Text = $"Number of possible duplicates: {duplicates}. Do you want write this record in any case?";

                    //Panel3.Visible = false;
                    SubmitButton.Visible = false;
                    UpdatePanel1.Visible = false;
                    PanelDialog.Visible = true;
                }
                else
                {
                    //it's uniqe, write it without additional permission
                    InsertRecord(client);
                }
            }

            saveControlValues();
            TimeLabel.Text = "Response time: " + PerfectFormatTime(stopwatch.Elapsed);
        }

        /// <summary>
        /// calculates how many in a given table a records under the high level and a records between the low and the high levels
        /// </summary>
        /// <param name="table">given table</param>
        /// <param name="duplicates">number of records between low and high level</param>
        /// <param name="strongDuplicates">number of records under high level</param>
        private void CalculateDuplicates(DataTable table, out int duplicates, out int strongDuplicates)
        {
            duplicates = 0;
            strongDuplicates = 0;

            int index = -1;
            for (int i = 0; i < table.Columns.Count; i++)
            {
                if (table.Columns[i].ColumnName.Equals("Score"))
                {
                    index = i;
                    break;
                }
            }

            if (index == -1) return;

            double high, low;
            if (Double.TryParse(HighLevelTextBox.Text, out high))
            {
                if (Double.TryParse(LowLevelTextBox.Text, out low))
                {
                    for (int i = 0; i < table.Rows.Count; i++)
                    {
                        object o = table.Rows[i]["Score"];
                        try
                        {
                            double d;
                            if (o is String)
                            {
                                Double.TryParse(o as String, out d);
                            }
                            else
                            {
                                d = (double)o;
                            }
                            if (d > high)
                            {
                                strongDuplicates++;
                            }
                            else
                            {
                                duplicates++;
                            }
                        }
                        catch { }

                    }
                }
            }
        }

        protected void StrongWriteButton_Click(object sender, EventArgs e)
        {
            resetLabels();
            using (ServiceReference1.SampleServiceClient client = new ServiceReference1.SampleServiceClient())
            {
                System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
                stopwatch.Start();
                InsertRecord(client);

                saveControlValues();
                TimeLabel.Text = "Response time: " + PerfectFormatTime(stopwatch.Elapsed);
            }

            SubmitButton.Visible = true;
            UpdatePanel1.Visible = true;
            PanelDialog.Visible = false;
        }

        protected void CancelWriteButtonClick(object sender, EventArgs e)
        {
            resetLabels();

            ErrorLabel.Text = "Inserting was aborted by user";

            SubmitButton.Visible = true;
            UpdatePanel1.Visible = true;
            PanelDialog.Visible = false;
        }
        
        private void InsertRecord(ServiceReference1.SampleServiceClient client)
        {
            string hash = SampleServiceNamespace.PortableHash.GetHash(tableName);
            if (!client.IsRunning(hash, tableName))
            {
                ErrorLabel.Text = tableName + " project is not active. It cannot be edited.";
            }
            else
            {
                string error;
                string[] result;
                string[] fields = client.GetMatchingFields(hash, tableName);
                string[] values = getMatchingValues();
                if (client.InsertRecord(hash, tableName, fields, values, out result, out error))
                {
                    DataTable table = FromStringArrayToDataTable(result);
                    ErrorLabel.Text = "Record is inserted succesfully: ";

                    Session[taskTable] = table;
                    bindSearchResults();
                }
                else
                {
                    ErrorLabel.Text = "Error happened while inserting: " + error;
                }
            }
        }

        protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
        {
            ErrorLabel.Text = ResultsGridView.SelectedIndex.ToString();
            bindSearchResults();
            string[] matchingValues = getMatchingValues();
            DataTable dataTable = Session[taskTable] as DataTable;
            DataRow dataRow = dataTable.Rows[ResultsGridView.SelectedIndex];
            int startIndex = getFirstDataCol();
            int counter = 0;
            for (int i = startIndex; i < dataTable.Columns.Count; i++)
            {
                (DynamicEditPanel.Controls[counter++ * 2 + 1] as TextBox).Text = dataRow[i].ToString();
            }
        }

        protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
        {
            return;
            ResultsGridView.EditIndex = e.NewEditIndex;
            bindSearchResults();
            string[] matchingValues = getMatchingValues();
            DataTable dataTable = Session[taskTable] as DataTable;
            DataRow dataRow = dataTable.Rows[e.NewEditIndex];
            int startIndex = matchingValues.Length + 1; // score fields, + 1 is for total score
            int counter = 0;
            for (int i = startIndex; i < dataTable.Columns.Count; i++)
            {
                (DynamicEditPanel.Controls[counter++ * 2 + 1] as TextBox).Text = dataRow[i].ToString();
            }
        }

        protected void updateButton_Click(object sender, EventArgs e)
        {
            resetLabels();
            using (ServiceReference1.SampleServiceClient client = new ServiceReference1.SampleServiceClient())
            {
                System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
                stopwatch.Start();
                string hash = SampleServiceNamespace.PortableHash.GetHash(tableName);
                if (!client.IsRunning(hash, tableName))
                {
                    ErrorLabel.Text = tableName + " project is not active. It cannot be edited.";
                }
                else
                {
                    string error;
                    string[] values = getInsertValues();
                    string id = values[0];
                    if (client.UpdateRecord(hash, tableName, values, id, out error))
                    {
                        ErrorLabel.Text = "record from " + tableName + " updated";
                    }
                    else
                    {
                        ErrorLabel.Text = error;
                    }
                }

                saveControlValues();
                //TimeLabel.Text = "response time: " + stopwatch.Elapsed.ToString();
                TimeLabel.Text = "Response time: " + PerfectFormatTime(stopwatch.Elapsed);
            }
        }

        protected void deleteButton_Click(object sender, EventArgs e)
        {
            resetLabels();
            using (ServiceReference1.SampleServiceClient client = new ServiceReference1.SampleServiceClient())
            {
                System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
                stopwatch.Start();
                string hash = SampleServiceNamespace.PortableHash.GetHash(tableName);
                if (!client.IsRunning(hash, tableName))
                {
                    ErrorLabel.Text = tableName + " project is not active. It cannot be edited.";
                }
                else
                {
                    string error;
                    string[] values = getInsertValues();
                    string id = values[0];
                    if (client.DeleteRecord(hash, tableName, id, out error))
                    {
                        ErrorLabel.Text = "record from " + tableName + " deleted";
                    }
                    else
                    {
                        ErrorLabel.Text = error;
                    }
                }

                saveControlValues();
                //TimeLabel.Text = "response time: " + stopwatch.Elapsed.ToString();
                TimeLabel.Text = "Response time: " + PerfectFormatTime(stopwatch.Elapsed);
            }
        }

        protected void projectsRadioButtonList_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.DynamicEditPanel.Controls.Clear();
            saveControlValues();
        }

        protected void addProjectButton_Click(Object sender, EventArgs e)
        {
            if (FileUploader.HasFile)
            {
                string projectFileName = FileUploader.FileName;
                String projectName = System.IO.Path.GetFileNameWithoutExtension(projectFileName);
                projectsRadioButtonList.Items.Add(projectName);
            }
            else
            {

            }
        }

        protected void showLiveSearch_Click(Object sender, EventArgs e)
        {
            Panel1.Visible = true;
            Panel3.Visible = false;


            ButtonLiveSearch.Visible = false;
            ButtonRealTimeInsert.Visible = true;
        }

        protected void showRealTimeInsert_Click(Object sender, EventArgs e)
        {
            Panel1.Visible = false;
            Panel3.Visible = true;

            ButtonLiveSearch.Visible = true;
            ButtonRealTimeInsert.Visible = false;
        }

        #endregion
    }
}