using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using VSview.Properties;

namespace VSview
{
    public class ParameterViewModel : BaseViewModel
    {
        private MainViewModel ViewModel;
        #region Constructors
        /// <summary>
        /// Default constructor
        /// </summary>
        public ParameterViewModel(MainViewModel mainViewModel)
        {
            //create reference to main view model
            ViewModel = mainViewModel;
            //setup command collection
            SetupCommands();
            //setup parameter collection
            SetupParameters();
        }
        #endregion

        #region Public properties

        /// <summary>
        /// Collection of detector parameters
        /// </summary>
        public ObservableCollection<Parameter> Parameters { get; set; }

        /// <summary>
        /// Selected parameter in datagrid
        /// </summary>
        public Parameter SelectedParameter { get; set; }

        /// <summary>
        /// Selected command value
        /// </summary>
        public string RequiredValue { get; set; }


        #endregion

        #region Commands

        /// <summary>
        /// Collection of parameter commands
        /// </summary>
        public Dictionary<string, RelayCommand> Command { get; set; }

        private void SetupCommands()
        {
            Command = new Dictionary<string, RelayCommand>();

            Command.Add("SelectionChanged", new RelayCommand(SelectionChanged));
            Command.Add("NumpadClick", new RelayCommand(NumpadClick));
            Command.Add("ChangeRequiredValue", new RelayCommand(ChangeRequiredValue));
            Command.Add("SendToHLD", new RelayCommand(SendToHLD));
            Command.Add("ExportValues", new RelayCommand(ExportValues));
            Command.Add("ImportValues", new RelayCommand(ImportValues));
        }

        /// <summary>
        /// Command for aquiring selected parameter values
        /// </summary>
        /// <param name="obj"></param>
        private void SelectionChanged(object obj)
        {
            try
            {
                RequiredValue = SelectedParameter.RequiredValue;
            }
            catch (Exception ex) { MessageBox.Show("Error occured during aquiring parameter values. \nReason: " + ex.Message, "Parameter error", MessageBoxButton.OK, MessageBoxImage.Warning); }
        }

        /// <summary>
        /// Method for using numpad on parameter tab
        /// </summary>
        /// <param name="obj"></param>
        private void NumpadClick(object obj)
        {
            try
            {
                string number = (string)obj;
                if (number == "C")
                    RequiredValue = "";
                else
                    RequiredValue += number;

            }
            catch (Exception ex) { MessageBox.Show("Error occured during writting to required parameter value. \nReason: " + ex.Message, "Parameter error", MessageBoxButton.OK, MessageBoxImage.Warning); }
        }

        /// <summary>
        /// Command for changing parameter required value
        /// </summary>
        /// <param name="obj"></param>
        private void ChangeRequiredValue(object obj)
        {
            try
            {
                if (SelectedParameter != null)
                SelectedParameter.RequiredValue = RequiredValue;
                else
                {
                    MessageBox.Show("No parameter is selected" ,"Parameter change warning", MessageBoxButton.OK, MessageBoxImage.Warning);
                }
            }
            catch (Exception ex) { MessageBox.Show("Error occured during changing required parameter value. \nReason: " + ex.Message, "Parameter error", MessageBoxButton.OK, MessageBoxImage.Warning); }
        }

        /// <summary>
        /// Command for sending required value to detector
        /// </summary>
        /// <param name="obj"></param>
        private void SendToHLD(object obj)
        {
            try
            {
                foreach (Parameter parameter in Parameters)
                {
                    if (!string.IsNullOrEmpty(parameter.CommandName) && !string.IsNullOrEmpty(parameter.RequiredValue))
                        ViewModel.Detector.SendToDetector(parameter.RequiredValue + " " + parameter.CommandName, true);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error during writting parameter required value to HLD. \nReason: " + ex.Message, "Parameter error", MessageBoxButton.OK, MessageBoxImage.Warning);
            }

        }

        /// <summary>
        /// Commnad for exporting actual values from detector to CSV file
        /// </summary>
        /// <param name="obj"></param>
        private void ExportValues(object obj)
        {

            new Thread(() =>
            {
                try
                {
                    string VSviewPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "Labtech", "VSview", "Exports");

                    if (!Directory.Exists(VSviewPath))
                        Directory.CreateDirectory(VSviewPath);

                    SaveFileDialog dialog = new SaveFileDialog()
                    {
                        InitialDirectory = VSviewPath,
                        Filter = "TXT files(.txt)|*.txt|all Files(*.*)|*.*",
                        DefaultExt = ".txt",
                        FilterIndex = 1,
                        RestoreDirectory = true
                    };

                    if (dialog.ShowDialog() == true)
                    {
                        StreamWriter streamWriter = new StreamWriter(dialog.FileName);
                        StringBuilder stringBuilder = new StringBuilder();

                        stringBuilder.Append("Name");
                        stringBuilder.Append(",");
                        stringBuilder.Append("Actual value");

                        streamWriter.WriteLine(stringBuilder);

                        stringBuilder.Clear();
                        streamWriter.Flush();

                        foreach (Parameter parameter in Parameters)
                        {
                            stringBuilder.Append(parameter.Name);
                            stringBuilder.Append(",");
                            stringBuilder.Append(parameter.ActualValue);

                            streamWriter.WriteLine(stringBuilder);

                            stringBuilder.Clear();
                            streamWriter.Flush();
                        }
                    }
                }
                catch (Exception ex) { MessageBox.Show("Error occured during exporting actual parameter values to CSV file. \nReason: " + ex.Message, "Parameter error", MessageBoxButton.OK, MessageBoxImage.Warning); }


            }).Start();
        }

        /// <summary>
        /// Method for importing actual values from detector as required values to detector
        /// </summary>
        /// <param name="obj"></param>
        private void ImportValues(object obj)
        {
            new Thread(() =>
            {
                try
                {
                    string VSviewPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "Labtech", "VSview", "Exports");

                    if (!Directory.Exists(VSviewPath))
                        Directory.CreateDirectory(VSviewPath);

                    OpenFileDialog dialog = new OpenFileDialog()
                    {
                        InitialDirectory = VSviewPath,
                        Filter = "TXT files(.txt)|*.txt|all Files(*.*)|*.*",
                        DefaultExt = ".txt",
                        FilterIndex = 1,
                        RestoreDirectory = true
                    };

                    if (dialog.ShowDialog() == true)
                    {
                        StreamReader streamReader = new StreamReader(dialog.FileName);

                        int rowIndex = 0;
                        string row = "";
                        while (!streamReader.EndOfStream)
                        {
                            row = streamReader.ReadLine();
                            if (rowIndex > 0)
                            {
                                string[] parts = row.Split(',');

                                //Get index of parameter with same name and replace its required value with loaded value
                                int ParameterIndex = Parameters.IndexOf(Parameters.First(par => par.Name == parts[0]));
                                if (ParameterIndex >= 0)
                                    Parameters[ParameterIndex].RequiredValue = parts[1];
                            }
                            rowIndex++;
                        }
                    }
                }
                catch (Exception ex) { MessageBox.Show("Error occured during importing required parameter values to CSV file. \nReason: " + ex.Message, "Parameter error", MessageBoxButton.OK, MessageBoxImage.Warning); }

            }).Start();
        }

        #endregion


        #region Private methods

        private void SetupParameters()
        {
            Parameters = new ObservableCollection<Parameter>();

            Parameters.Add(new Parameter("Autozero", "INIT AZ<0", "?AZ<0", "1 - autozero enabled, 0 - autozero disabled"));
            Parameters.Add(new Parameter("Zero enabled", "0", "", "1 - zeroing enabled, 0 - zeroing disabled"));
            Parameters.Add(new Parameter("Reject 1", "1.8E-4", "", "Reject warning range"));
            Parameters.Add(new Parameter("Reject 2", "1.6E-4", "", ""));
            Parameters.Add(new Parameter("Reject 3", "1.4E-4", "", ""));
            Parameters.Add(new Parameter("Reject 4", "1.2E-4", "", "Reject lower range"));
            Parameters.Add(new Parameter("Audio reject", "2E-4", "", "Audio reject warning"));
            Parameters.Add(new Parameter("Reject 1 active", "1", "", "Reject warning range"));
            Parameters.Add(new Parameter("Reject 2 active", "0", "", "Reject warning range"));
            Parameters.Add(new Parameter("Reject 3 active", "0", "", "Reject warning range"));
            Parameters.Add(new Parameter("Reject 4 active", "1", "", "Reject warning range"));
            Parameters.Add(new Parameter("Audio reject active", "1", "", "Reject warning range"));

            Parameters[0].RequiredValue = "1";
            Parameters[1].RequiredValue = "0";

            Parameters[2].RequiredValue = "1.8E-4";
            Parameters[3].RequiredValue = "1.6E-4";
            Parameters[4].RequiredValue = "1.4E-4";
            Parameters[5].RequiredValue = "1.2E-4";
            Parameters[6].RequiredValue = "2E-4";
            Parameters[7].RequiredValue = "1";
            Parameters[8].RequiredValue = "0";
            Parameters[9].RequiredValue = "0";
            Parameters[10].RequiredValue = "1";
            Parameters[11].RequiredValue = "1";


        }
        #endregion
    }
}
