using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Nappat.Testing;
using System.ComponentModel;
using System.Collections;
using Microsoft.Win32;
using Microsoft.WindowsAPICodePack.Taskbar;

namespace Nappat.Testing.WPF
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        #region Private Fields
        DataSender dataSender;
        BackgroundWorker backgroundWorker = new BackgroundWorker();
        Program program;
        TestProgressBar testProgressBar;
        List<LogLine> loggerList = new List<LogLine>();
        #endregion

        #region Constructors
        public MainWindow()
        {
            InitializeComponent();
            dataSender = new DataSender();

            this.DataContext = dataSender;
            this.startButton.IsEnabled = false;
            this.stopButton.IsEnabled = false;
            dataSender.LogChanged += dataSender_LogChanged;

            backgroundWorker.DoWork += backgroundWorker_DoWork;
            backgroundWorker.ProgressChanged += backgroundWorker_ProgressChanged;
            backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted;
            backgroundWorker.WorkerReportsProgress = true;
            backgroundWorker.WorkerSupportsCancellation = true;

            program = new Program(dataSender);
            program.InterpretingStart += program_InterpretingStart;
            program.InterpretingStop += program_InterpretingStop;

            testProgressBar = new TestProgressBar(this);

            dataSender.LogMessages = new LogLine(DateTime.Now.ToString(), "Program", "Info", "Hallo", null);
        }

        private void program_InterpretingStart()
        {
            this.Dispatcher.Invoke((Action)(() =>
            {
                testProgressBar.Start(dataSender);
            }));
        }
        private void program_InterpretingStop()
        {
            this.Dispatcher.Invoke((Action)(() =>
            {
                testProgressBar.Stop(dataSender);
            }));
        }
        private void dataSender_LogChanged()
        {
            LogUpdate();
        }
        #endregion

        #region Private Methods
        #region BackgroundWorker Methods
        private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;

                if (worker.CancellationPending == true)
                {
                    e.Cancel = true;
                }
                else
                {
                    try
                    {
                        program.Play();
                        worker.ReportProgress(1);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                
            }
        }
        private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            //
        }
        private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            this.startButton.IsEnabled = false;
            this.stopButton.IsEnabled = false;
            if (e.Cancelled == true)
            {
                //this.dataSender.LogMessages.Add(string.Format("{0:HH:mm:ss.fff: }", DateTime.Now) + "Tests was canceled by user." + Environment.NewLine);
            }
            else if (e.Error != null)
            {
                //this.dataSender.LogMessages.Add(string.Format("{0:HH:mm:ss.fff: }", DateTime.Now) + "An error occured." + Environment.NewLine);
            }
        }
        #endregion

        #region MenuItem Methods
        private void saveMenuItem_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if ((this.dataSender.DriverPaths != null && this.dataSender.ScriptPaths != null) || (this.dataSender.DriverPaths != null && this.dataSender.CsFilePaths != null))
                {
                    Microsoft.Win32.SaveFileDialog saveFileDialog = new Microsoft.Win32.SaveFileDialog();
                    saveFileDialog.Filter = "Nappat Save File|*.nsf|Plain Text|*.txt";
                    saveFileDialog.Title = "Save Testing";
                    saveFileDialog.FileName = this.dataSender.TestNames;
                    saveFileDialog.ShowDialog();

                    if (saveFileDialog.FileName != "")
                    {
                        SaveLoad sl = new SaveLoad(this.dataSender);
                        sl.Save(saveFileDialog.FileName);
                    }
                }
                else
                    throw new Exception("No Parameters to save.");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        private void loadMenuItem_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
                //dlg.Multiselect = true;
                dlg.DefaultExt = ".nsf";
                dlg.Filter = "Nappat Save File|*.nsf";
                Nullable<bool> result = dlg.ShowDialog();
                if (result == true)
                {
                    SaveLoad sl = new SaveLoad(dataSender);
                    sl.DataTransporter(dataSender, sl.Load(dlg.FileName));
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        private void closeMenuItem_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        private void interpretMenuItem_Click(object sender, RoutedEventArgs e)
        {
            InterpretDialog dialog = new InterpretDialog(dataSender);
            dialog.Closed += dialog_Closed;
            dialog.ShowDialog();
        }
        private void createAndInterpretMenuItem_Click(object sender, RoutedEventArgs e)
        {
            CreateAndInterpretDialog dialog = new CreateAndInterpretDialog(dataSender);
            dialog.Closed += dialog_Closed;
            dialog.ShowDialog();
        }
        private void helpMenuItem_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                AboutBox ab = new AboutBox();
                ab.ShowDialog();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        private void dialog_Closed(object sender, EventArgs e)
        {
            if ((this.dataSender.DriverPaths != null && this.dataSender.ScriptPaths != null) || (this.dataSender.DriverPaths != null && this.dataSender.CsFilePaths != null))
                this.startButton.IsEnabled = true;
        }
        #endregion

        private void Window_Loaded(object sender, EventArgs e)
        {
            try
            {
                SaveLoad sl = new SaveLoad(dataSender);
                sl.DataTransporter(dataSender, sl.LoadInit());
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            try
            {
                string message = "Are you sure that you would like to close the App?";
                string caption = "Application Closing";
                MessageBoxResult result = MessageBox.Show(message, caption, MessageBoxButton.YesNo, MessageBoxImage.Question);
                if (result == MessageBoxResult.No)
                {
                    e.Cancel = true;
                }
                if (result == MessageBoxResult.Yes)
                {
                    if ((this.dataSender.DriverPaths != null && this.dataSender.ScriptPaths != null) || (this.dataSender.DriverPaths != null && this.dataSender.CsFilePaths != null))
                    {
                        SaveLoad sl = new SaveLoad(this.dataSender);
                        sl.SaveInit();
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        private void startButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if ((this.dataSender.DriverPaths != null && this.dataSender.ScriptPaths != null) || (this.dataSender.DriverPaths != null && this.dataSender.CsFilePaths != null))
                {
                    if (backgroundWorker.IsBusy != true)
                    {
                        backgroundWorker.RunWorkerAsync();
                        this.startButton.IsEnabled = false;
                        this.stopButton.IsEnabled = true;
                    }
                }
                else
                {
                    System.Windows.MessageBox.Show("No parameters insert.");
                }
            }
            catch (Exception ex)
            {
                this.dataSender.LogMessages = new LogLine(DateTime.Now.ToString(), "Program", "Error", ex.Message, null);
                MessageBox.Show(ex.Message);
            }
        }
        private void stopButton_Click(object sender, RoutedEventArgs e)
        {
            
            this.backgroundWorker.CancelAsync();

        }
        private void saveLog_Click(object sender, RoutedEventArgs e)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.Filter = "Plain Text|*.txt";
            saveFileDialog.Title = "Save Testing";
            if (loggerList != null)
            {
                if (dataSender.TestNames != null)
                {
                    saveFileDialog.FileName = dataSender.TestNames + "_Log";
                }
                else
                    saveFileDialog.FileName = "Log";

                saveFileDialog.ShowDialog();

                List<string> loggerStrings = new List<string>();
                foreach (var line in loggerList)
                {
                    loggerStrings.Add(line.ToString());
                }

                if (saveFileDialog.FileName != "")
                {
                    System.IO.File.WriteAllLines(saveFileDialog.FileName, loggerStrings);
                }
            }
            else
                MessageBox.Show("Nothing to save. :(");
        }
        private void LogUpdate()
        {
            this.Dispatcher.Invoke((Action)(() =>
            {
                LogWriter lw = new LogWriter(this.logTextBox);
                lw.UpdateBox(dataSender);
                if (testProgressBar.CanProgress)
                    testProgressBar.Progress(dataSender);
                loggerList.Add(dataSender.LogMessages);
            }));
        }
        #endregion
    }
}
