using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using SokobanResultSearch.BusinessEntities;
using System.Runtime.Remoting.Messaging;

namespace SokobanResultSearch
{
    public partial class MainForm : Form
    {

        #region Delegates

        private delegate State SearcherDelegate();

        private delegate void ResultCallBackDelegate(IAsyncResult result);

        #endregion

        #region Private fields

        /// <summary>
        /// List of the sokoban tables.
        /// </summary>
        List<ITable> _tables;

        #endregion

        #region Constructors

        public MainForm()
        {
            InitializeComponent();
        }

        #endregion

        #region Event handlers

        private void MainForm_Load(object sender, EventArgs e)
        {
            //gets tables
            _tables = TableProviderFactory.TableProvider.GetTables();

            #region Initializes datagridview

            for (int i = 0; i < _tables.Count; i++)
            {
                DataGridViewTextBoxColumn column = new DataGridViewTextBoxColumn();
                column.Width                     = 200;
                dgvTables.Columns.Add(column);
            }

            DataGridViewRow row                 = new DataGridViewRow();
            row.Height                          = 280;
            dgvTables.Rows.Add(row);

            for (int i = 0; i < _tables.Count; i++)
            {
                dgvTables.Rows[0].Cells[i].Value            = _tables[i].Value;
                dgvTables.Rows[0].Cells[i].Style.Alignment = DataGridViewContentAlignment.MiddleCenter;
                dgvTables.Rows[0].Cells[i].Style.Font       = new Font("Courier New", 10);
            }

            #endregion
        }

        private void OnAboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //shows the About information
            MessageBox.Show(this, Properties.Resources.str_Author, this.Text, MessageBoxButtons.OK);
        }

        private void OnExitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Environment.Exit(0);
        }

        private void OnSearch_Click(object sender, EventArgs e)
        {
           
            txtResult.AppendText(string.Format("{0} - {1}", DateTime.Now, Properties.Resources.str_InitStart + Environment.NewLine));

            //disables controls below
            lblPleaseWait.Visible = !(mainToolStripMenuItem.Enabled = btnSearch.Enabled = false);
            Astar searcher = new Astar(TableProviderFactory.TableProvider.ConvertTableToByteArray(_tables[dgvTables.SelectedCells[0].ColumnIndex]));

            txtResult.AppendText(string.Format("{0} - {1}", DateTime.Now, Properties.Resources.str_InitEnd + Environment.NewLine));
            txtResult.AppendText(string.Format("{0} - {1}", DateTime.Now, Properties.Resources.str_SearchStart + Environment.NewLine));

            //starts  searching results on another thread
            new SearcherDelegate(searcher.Search).BeginInvoke(new AsyncCallback(ResultCallBack), null);
        }

        #endregion

        #region Private methods

        public void ResultCallBack(IAsyncResult aResult)
        {
            if (!InvokeRequired)
            {
                SearcherDelegate temp   = (SearcherDelegate)(aResult as AsyncResult).AsyncDelegate;
                State result           = temp.EndInvoke(aResult);

                //prints the result
                txtResult.AppendText(string.Format("{0} - {1}", DateTime.Now, Properties.Resources.str_SearchEnd + Environment.NewLine));
                if (result != null)
                {
                    txtResult.AppendText(result.ToString() + Environment.NewLine);
                }
                else
                    txtResult.AppendText(Properties.Resources.str_NoSolution + Environment.NewLine);

                //enables controls below
                lblPleaseWait.Visible = !(mainToolStripMenuItem.Enabled = btnSearch.Enabled = true);
                txtResult.AppendText("---------------------------------------------------------------------------------------------------------------------------------------" 
                    + Environment.NewLine);
            }
            else
                Invoke(new ResultCallBackDelegate(ResultCallBack), new object[] { aResult });
        }

        #endregion
    }
}