using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using CensusParser;
using System.Collections;
using System.Diagnostics;

namespace Initializer
{
    public partial class Manager : Form
    {
        private string accessKey = "Enter your AWS Key here";
        private string secretKey = "Enter your AWS Private Key here";

        private string datasetDrive = @"F:";
        private string parseQueue = "CensusParseQueue";
        static string pdsInvalidDrive = @"The drive you pointed at does not contain the Year 2000 Census Public Data Set.  Please set the value of 'datasetDrive'.";
        private Dictionary<string, string> regionDictionary = new Dictionary<string, string>();
        private int itemsProcessed = 0;

        SQS.Requestor parserRequestor;

        public Manager()
        {
            InitializeComponent();

            SetupQueue();
        }

        private void SetupQueue()
        {
            //
            // configure parserRequestor SQS
            //
            parserRequestor = new SQS.Requestor();

            parserRequestor.AutoDelete = false;
            parserRequestor.AwsID = accessKey;
            parserRequestor.AWSSecretKey = secretKey;
            parserRequestor.MeasureNetLatency = false;
            parserRequestor.PollingMode = SQS.SQSManager.pollMode.Adaptive;
            parserRequestor.Queue = parseQueue;
            parserRequestor.ReceiveDelay = 100;
            parserRequestor.Threads = 3;
            parserRequestor.responseEvent += new SQS.Requestor.ProcessEvent(parserRequestor_responseEvent);

        }

        private void btnStart_Click(object sender, EventArgs e)
        {

            // Add requests for each of the regions in the Census Demographics Data
                        StringBuilder regionsPath = new StringBuilder();
            regionsPath.Append(datasetDrive);
            regionsPath.Append(@"/census_2000/datasets/demographic_profile");

            string dirpath = regionsPath.ToString();

            DirectoryInfo regionsDI = new DirectoryInfo(dirpath);

            if (regionsDI.Exists == false)
            {
                Console.WriteLine(pdsInvalidDrive);
            }
            else
            {
                lbOutput.Items.Clear();
                regionDictionary.Clear();

                lvResults.Items.Clear();
                
                DirectoryInfo[] dirs = regionsDI.GetDirectories();
                
                itemsProcessed = 0;
                txtProgress.Text = itemsProcessed + " / " + dirs.Length;

                int added = 0;

                foreach (DirectoryInfo d in dirs)
                {
                    string formattedRegion = FormatDirs(d.Name);

                    if (!formattedRegion.Contains("All State") &&
                        !formattedRegion.Contains("National") &&
                        !formattedRegion.Contains("United States"))
                    {

                        
                        if (added < 56)
                        {
                            lbOutput.Items.Add("Adding: " + formattedRegion);
                            regionDictionary.Add(d.FullName, "");

                            added++;

                            parserRequestor.MakeRequest(d.FullName);
                        }
                    }
                    
                }

            }
        }

        private string FormatDirs(string s)
        {
            string ret = string.Empty;

            // Remove the 0_ from those Regions that start with it
            if (s.IndexOf("0_") == 0)
            {
                s = s.Substring(2);
            }

            s = s.Replace('_', ' ');

            ret = s;

            return s;
        }


        void Initializer_FormClosed(object sender, System.Windows.Forms.FormClosedEventArgs e)
        {
            // Stop the SQS requestor
            parserRequestor.Stop();
        }

        void Initializer_Load(object sender, System.EventArgs e)
        {
            // Start the SQS requestor
            parserRequestor.Start();
        }

        private bool parserRequestor_responseEvent(SQS.Requestor requestor, SQS.SQSMessage message)
        {

            txtProgress.Text = Convert.ToString((itemsProcessed+1)) + " / " + Convert.ToString(regionDictionary.Count);
            
            //lbOutput.Items.Add("Processed Response ("+Convert.ToString(DateTime.Now)+"): " + message._payload);

            string [] topTenItems;
            topTenItems = message._payload.Split(',');

            foreach (string topTenItem in topTenItems)
            {
                string[] components = topTenItem.Split('|');

                if (components.Length == 3)
                {
                    // Create a ListViewItem for each of the topTen Census Regions that are returns
                    // by the processor

                    // Pop20to34
                    ListViewItem li = new ListViewItem();
                    li.Text = components[2];

                    // SubRegion
                    ListViewItem.ListViewSubItem si1 = new ListViewItem.ListViewSubItem();
                    si1.Text = components[1];
                    li.SubItems.Add(si1);

                    // Region
                    ListViewItem.ListViewSubItem si2 = new ListViewItem.ListViewSubItem();
                    si2.Text = components[0];
                    li.SubItems.Add(si2);

                    lvResults.Items.Add(li);
                    
                }
            }

            itemsProcessed++;
            return true;
        }

        void lvResults_ColumnClick(object sender, System.Windows.Forms.ColumnClickEventArgs e)
        {
            Sorter columnSorter = new Sorter(e.Column);
            columnSorter.column = e.Column;

            if ((columnSorter.bAscending = (lvResults.Sorting == SortOrder.Ascending)))
                lvResults.Sorting = SortOrder.Descending;
            else
                lvResults.Sorting = SortOrder.Ascending;
            
            Debug.WriteLine("Column : " + e.Column);

            lvResults.ListViewItemSorter = columnSorter;
            lvResults.Sort();

        }


    }

    public class Sorter : System.Collections.IComparer
    {
        public Sorter(int col)
        {
            column = col;
        }

        // Initialize the variables to default
        public int column = 0;
        public bool bAscending = true;

        // Using the Compare function of IComparer
        public int Compare(object x, object y)
        {
            // Cast the objects to ListViewItems
            ListViewItem lvi1 = (ListViewItem)x;
            ListViewItem lvi2 = (ListViewItem)y;

            // If the column is the string columns
            if (column != 0)
            {
                string lvi1String = lvi1.SubItems[column].ToString();
                string lvi2String = lvi2.SubItems[column].ToString();

                // Return the normal Compare
                if (bAscending)
                    return String.Compare(lvi1String, lvi2String);

                // Return the negated Compare
                return -String.Compare(lvi1String, lvi2String);
            }

            // The column is the Age column
            int lvi1Int = Convert.ToInt32(lvi1.SubItems[column].Text.ToString());
            int lvi2Int = Convert.ToInt32(lvi2.SubItems[column].Text.ToString());

            // Return the normal compare.. if x < y then return -1
            if (bAscending)
            {
                if (lvi1Int < lvi2Int)
                    return -1;
                else if (lvi1Int == lvi2Int)
                    return 0;

                return 1;
            }

            // Return the opposites for descending
            if (lvi1Int > lvi2Int)
                return -1;
            else if (lvi1Int == lvi2Int)
                return 0;

            return 1;
        }

        private int ParseListItemString(string x)
        {
            //ListViewItems are returned like this: "ListViewSubItem: {19}"
            int counter = 0;
            for (int i = x.Length - 1; i >= 0; i--, counter++)
            {
                if (x[i] == '{')
                    break;
            }

            return Int32.Parse(x.Substring(x.Length - counter, counter - 1));
        }
    }

}
