using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;

namespace VSview
{
    public class SettingViewModel : BaseViewModel
    {
        /// <summary>
        /// Reference to main view model
        /// </summary>
        private MainViewModel ViewModel;

        #region Constants
        /// <summary>
        /// List of detector types
        /// </summary>
        public static List<string> DetectorTypes { get; set; }

        /// <summary>
        /// List of serial ports
        /// </summary>
        public static List<string> SerialPorts { get; set; }

        /// <summary>
        /// List of languages
        /// </summary>
        public static List<string> Languages { get; set; }

        /// <summary>
        /// List of control modules
        /// </summary>
        public static List<string> ControlModules { get; set; }

        /// <summary>
        /// List of availliable analog convertion
        /// </summary>
        public static List<string> AnalogConvertions { get; set; }

        #endregion

        #region Constructors
        /// <summary>
        /// Default constructor
        /// </summary>
        public SettingViewModel(MainViewModel mainViewModel)
        {
            //Create reference to main view model
            ViewModel = mainViewModel;
            //Setup constant lists
            SetupConstants();
            //Setup commands
            SetupCommands();
            //Scan serial ports
            SerialPorts = ScanPorts();
        }
        #endregion


        #region Public properties


        /// <summary>
        /// Index of selected port
        /// </summary>
        public static int PortIndex { get; set; }

        /// <summary>
        /// Index of selected control module
        /// </summary>
        public static int ControlIndex { get; set; }

        /// <summary>
        /// IP address of control module (Turck)
        /// </summary>
        public static string IPAddress { get; set; }

        /// <summary>
        /// MAC address of control module (Turck)
        /// </summary>
        public static string MACAddress { get; set; }

        /// <summary>
        /// If connection to control module (Turck) is made using IP address 
        /// </summary>
        public static bool UsingIP { get; set; }

        /// <summary>
        /// If connection to control module (Turck) is made using MAC address 
        /// </summary>
        public static bool UsingMAC { get; set; }

        /// <summary>
        /// Index of selected language
        /// </summary>
        public static int LanguageIndex { get; set; }

        /// <summary>
        /// Index of selected detector
        /// </summary>
        public static int DetectorIndex { get; set; }



        #endregion

        #region Commands

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

        /// <summary>
        /// Method for creating command collection
        /// </summary>
        private void SetupCommands()
        {
            Command = new Dictionary<string, RelayCommand>();


            Command.Add("Autodetect", new RelayCommand(Autodetect));
            Command.Add("ConnectDetector", new RelayCommand(ConnectDetector));
            Command.Add("ConnectControl", new RelayCommand(ConnectControl));
            Command.Add("IPUsingChanged", new RelayCommand(IPUsingChanged));
            Command.Add("MACUsingChanged", new RelayCommand(MACUsingChanged));
            Command.Add("LanguageChanged", new RelayCommand(LanguageChanged));
        }

        /// <summary>
        /// Command for autodetecting serial port to which is connected detector
        /// </summary>
        /// <param name="obj"></param>
        private void Autodetect(object obj)
        {
            ViewModel.Detector.Communication.Autodetection();
        }

        /// <summary>
        /// Command for connecting detector
        /// </summary>
        private void ConnectDetector(object obj)
        {
            if (!ViewModel.Detector.Settings.IsConnected)
                ViewModel.Detector.Communication.OpenSerial(SerialPorts[PortIndex]);
            else
                ViewModel.Detector.Communication.CloseSerial();
        }

        /// <summary>
        /// Command for connecting control module
        /// </summary>
        private void ConnectControl(object obj)
        {
            if (!ViewModel.ControlModule.IsConnected)
            {
                if (UsingIP)
                    ViewModel.ControlModule.ConnectTurck(IPAddress);
                else
                    ViewModel.ControlModule.ConnectWithMac();
            }
            else
            {
                ViewModel.ControlModule.DisconnectTurck();
            }          
        }

        /// <summary>
        /// Command for selecting using of IP address
        /// </summary>
        /// <param name="obj"></param>
        private void IPUsingChanged(object obj)
        {
            UsingMAC = false;
        }

        /// <summary>
        /// Command for selecting using of MAC address
        /// </summary>
        /// <param name="obj"></param>
        private void MACUsingChanged(object obj)
        {
            UsingIP = false;
        }

        /// <summary>
        /// Command for changing application language
        /// </summary>
        private void LanguageChanged(object obj)
        {
            new Thread(() =>
            {
                try
                {
                    if (Languages.Count > 0)
                    {
                        LoadStringResource(Languages[LanguageIndex]);
                        ViewModel.Detector.Communication.CommunicationList = new CommunicationList();
                        ViewModel.TerminalViewModel.SelectionInfo = "";
                    }
                }
                catch (Exception ex) { }//MessageBox.Show("Error occured during language change. \nReason: " + ex.Message, "Setting error", MessageBoxButton.OK, MessageBoxImage.Warning); }
            }).Start();
        }

        #endregion

        #region Private methods

        /// <summary>
        /// Method for creating constants collections
        /// </summary>
        private void SetupConstants()
        {
            DetectorTypes = new List<string>() { "VS-PR", "VS-C15" };
            Languages = new List<string>() { "English", "Czech" };
            ControlModules = new List<string>() { "Turck - S1 - 8DIP", "Turck - S1 - 8DOP", "Turck - S1 - 4DIP - 4DOP", "Turck - S1 - 8DXP", "Turck - S2 - 4AI", "Turck - S2 - 4AO" };
            AnalogConvertions = new List<string>() { "No convertion", "MKS 902B", "MKS 925", "PCG 750/PCG 752", "Custom - linear", "Custom - exponential", "Custom - Quadratic" };
        }

        #endregion

        #region Public methods

        /// <summary>
        /// Method for loading dynamic resource dictionaries
        /// </summary>
        /// <param name="local"></param>
        public static void LoadStringResource(string local)
        {
            var resources = new ResourceDictionary();

            resources.Source = new Uri("pack://application:,,,/View/Resources/Languages/Resources_" + local + ".xaml", UriKind.Absolute);

            var current = Application.Current.Resources.MergedDictionaries.FirstOrDefault(
                             m => m.Source.OriginalString.Contains("Resources_"));

            if (current != null)
            {
                Application.Current.Resources.MergedDictionaries.Remove(current);
            }

            Application.Current.Resources.MergedDictionaries.Add(resources);
        }

        /// <summary>
        /// Method for scanning serial ports
        /// </summary>
        /// <returns></returns>
        public static List<string> ScanPorts()
        {
            try
            {
                List<string> ports = new List<string>();
                foreach (string port in SerialPort.GetPortNames())
                {
                    ports.Add(port);
                }
                return ports;
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error occured during serial port names getting. Reason: " + ex.Message, "Settings error", MessageBoxButton.OK, MessageBoxImage.Warning);
                return null;
            }
        }

        #endregion
    }
}
