using FSI.Lib;
using System;
using System.Diagnostics;
using System.IO;
using System.Windows;

namespace FSI.BT.Tools.Commands
{
    /// <summary>
    /// Shows the main window.
    /// </summary>
    public class OpenAppCommand : CommandBase<OpenAppCommand>
    {
        public override void Execute(object parameter)
        {
            string[] files = new string[] { };
            string[] pathes = new string[] { };
            string arguments = string.Empty;

            switch ((string)parameter)
            {
                case "SimaticManager":
                    files = Global.Settings.SieSimaticManagerExe;
                    break;

                case "TIAv13":
                    files = Global.Settings.SieTiaV13Exe;
                    break;

                case "TIAv14":
                    files = Global.Settings.SieTiaV14Exe;
                    break;

                case "TIAv15":
                    files = Global.Settings.SieTiaV13Exe;
                    break;

                case "TIAv16":
                    files = Global.Settings.SieTiaV16Exe;
                    break;

                case "TIAv17":
                    files = Global.Settings.SieTiaV17Exe;
                    break;

                case "Starter":
                    files = Global.Settings.SieTiaVStarterExe;
                    break;

                case "Epl":
                    files = Global.Settings.EplExe;
                    arguments = Global.Settings.EplArguments;
                    break;

                case "EplPrj":
                    Lib.Guis.Prj.Mgt.FrmMain frmMainEplPrj = new()
                    {
                        ShowPdf = false,
                        CloseAtLostFocus = true,
                        WindowStartupLocation = WindowStartupLocation.CenterOwner,
                        Path = Global.Settings.EplPrjPath,
                        EplExes = Global.Settings.EplExe,
                    };
                    frmMainEplPrj.Show();
                    return;

                case "EplPdf":
                    Lib.Guis.Prj.Mgt.FrmMain frmMainEplPdf = new()
                    {
                        ShowPdf = true,
                        CloseAtLostFocus = true,
                        WindowStartupLocation = WindowStartupLocation.CenterOwner,
                        Path = Global.Settings.EplPdfPath,
                    };
                    frmMainEplPdf.Show();
                    return;

                case "EplPdfMgt":
                    Lib.Guis.Pdf.Mgt.FrmMain frmMainEplPdfMgt = new()
                    {
                        CloseAtLostFocus = true
                    };
                    frmMainEplPdfMgt.Show();
                    return;

                case "Npp":
                    files = Global.Settings.NppExe;
                    break;

                case "TotalCmd":
                    files = Global.Settings.TotalCmdExe;
                    break;

                case "TeXstudio":
                    files = Global.Settings.TeXstudioExe;
                    pathes = Global.Settings.TeXstudioPath;
                    break;

                case "VS":
                    files = Global.Settings.VsExe;
                    break;

                case "VS.Code":
                    files = Global.Settings.VsCodeExe;
                    break;


                case "Rdp":
                    files = Global.Settings.RdpExe;
                    break;

                case "DeEncrypt":
                    Lib.Guis.DeEncryptMessage.FrmMain frmMainDeEnCrypt = new()
                    {
                        Password = GetType().Namespace.ToString(),
                        CloseAtLostFocus = true,
                        WindowStartupLocation = WindowStartupLocation.CenterOwner,
                    };
                    frmMainDeEnCrypt.Show();
                    return;

                case "StarterCsvExporter":
                    Lib.Guis.SieStarterCsvExporter.FrmMain frmMain = new();
                    frmMain.Show();
                    return;

                case "Admin":
                    Gui.FrmAdmin frmAdmin = new()
                    {
                        Admins = Global.Settings.Admins,
                        Users = Global.Settings.Users,
                    };
                    frmAdmin.ShowDialog();

                    if (frmAdmin.DialogResult.HasValue && frmAdmin.DialogResult.Value)
                    {
                        Global.Settings.Admins = frmAdmin.Admins;
                        Global.Settings.Users = frmAdmin.Users;
                    }
                    return;

                case "Outlook":
                    files = Global.Settings.OutlookExe;
                    break;

                case "Teams":
                    files = Global.Settings.TeamsExe;
                    arguments = Global.Settings.TeamsArg;
                    break;

                case "Excel":
                    files = Global.Settings.ExcelExe;                   
                    break;

                case "Word":
                    files = Global.Settings.WordExe;
                    break;

                case "PaintNet":
                    files = Global.Settings.PaintNetExe;
                    break;
                                    
                case "Gimp":
                    files = Global.Settings.GimpExe;
                    break;   
                
                case "Vnc":
                    files = Global.Settings.VncExe;
                    break;
                                    
                case "VncAdrBook":
                    files = Global.Settings.VncAdrBookExe;
                    break;

            }

            string fileName = string.Empty;
            string path = string.Empty;

            for (int i = 0; i <= files.Length - 1; i++)
            {
                if (File.Exists(Environment.ExpandEnvironmentVariables(files[i].Trim())))
                {
                    fileName = Environment.ExpandEnvironmentVariables(files[i].Trim());
                }

                if (pathes.Length == 0)
                {
                    path = Path.GetDirectoryName(fileName);
                }
                else
                {
                    path = Environment.ExpandEnvironmentVariables(pathes[i].Trim());
                }
            }

            if (ProgramIsRunning(fileName))
            {
                ProgramToFront(fileName);
            }
            else
            {
                Process process = new();
                process.StartInfo.FileName = fileName;
                process.StartInfo.WorkingDirectory = path;
                process.StartInfo.Arguments = arguments;

                try
                {
                    process.Start();
                }
                catch (System.ComponentModel.Win32Exception ex) when (ex.NativeErrorCode == 740)
                {
                    try
                    {
                        process.StartInfo.UseShellExecute = true;
                        process.StartInfo.Verb = "runas";
                        process.Start();
                    }
                    catch { }
                }
            }
        }

        public override bool CanExecute(object parameter)
        {
            string[] files = new string[] { };
            switch ((string)parameter)
            {
                case "SimaticManager":
                    files = Global.Settings.SieSimaticManagerExe;
                    break;

                case "TIAv13":
                    files = Global.Settings.SieTiaV13Exe;
                    break;

                case "TIAv14":
                    files = Global.Settings.SieTiaV14Exe;
                    break;

                case "TIAv15":
                    files = Global.Settings.SieTiaV13Exe;
                    break;

                case "TIAv16":
                    files = Global.Settings.SieTiaV16Exe;
                    break;

                case "TIAv17":
                    files = Global.Settings.SieTiaV17Exe;
                    break;

                case "Starter":
                    files = Global.Settings.SieTiaVStarterExe;
                    break;

                case "Epl":
                    files = Global.Settings.EplExe;
                    break;

                case "EplPrj":
                    return true;

                case "EplPdf":
                    return true;

                case "EplPdfMgt":
                    return Global.AdminRights;

                case "Npp":
                    files = Global.Settings.NppExe;
                    break;

                case "TotalCmd":
                    files = Global.Settings.TotalCmdExe;
                    break;

                case "TeXstudio":
                    files = Global.Settings.TeXstudioExe;
                    break;

                case "VS":
                    files = Global.Settings.VsExe;
                    break;

                case "VS.Code":
                    files = Global.Settings.VsCodeExe;
                    break;


                case "Rdp":
                    files = Global.Settings.RdpExe;
                    break;

                case "DeEncrypt":
                    return Global.AdminRights;

                case "StarterCsvExporter":
                    return Global.AdminRights;

                case "Admin":
                    return Global.SuperAdminRights;

                case "Outlook":
                    files = Global.Settings.OutlookExe;
                    break;

                case "Teams":
                    files = Global.Settings.TeamsExe;
                    break;

                case "Excel":
                    files = Global.Settings.ExcelExe;
                    break;

                case "Word":
                    files = Global.Settings.WordExe;
                    break;

                case "PaintNet":
                    files = Global.Settings.PaintNetExe;
                    break;

                case "Gimp":
                    files = Global.Settings.GimpExe;
                    break;

                case "Vnc":
                    files = Global.Settings.VncExe;
                    break;

                case "VncAdrBook":
                    files = Global.Settings.VncAdrBookExe;
                    break;

                default: return false;

            }

            foreach (string file in files)
            {
                if (File.Exists(Environment.ExpandEnvironmentVariables(file.Trim())))
                {
                    return true;
                }
            }

            return false;
        }

        private bool ProgramIsRunning(string FullPath)
        {
            string FilePath = Path.GetDirectoryName(FullPath);
            string FileName = Path.GetFileNameWithoutExtension(FullPath).ToLower();
            bool isRunning = false;

            Process[] pList = Process.GetProcessesByName(FileName);

            foreach (Process p in pList)
            {
                if (p.MainModule.FileName.StartsWith(FilePath, StringComparison.InvariantCultureIgnoreCase))
                {
                    isRunning = true;
                    break;
                }
            }

            return isRunning;
        }

        [System.Runtime.InteropServices.DllImport("User32.dll")]
        private static extern bool SetForegroundWindow(IntPtr handle);
        [System.Runtime.InteropServices.DllImport("User32.dll")]
        private static extern bool ShowWindow(IntPtr handle, int nCmdShow);
        [System.Runtime.InteropServices.DllImport("User32.dll")]
        private static extern bool IsIconic(IntPtr handle);

        private void ProgramToFront(string FullPath)
        {
            string FilePath = Path.GetDirectoryName(FullPath);
            string FileName = Path.GetFileNameWithoutExtension(FullPath).ToLower();

            Process[] pList = Process.GetProcessesByName(FileName);

            foreach (Process p in pList)
            {
                if (p.MainModule.FileName.StartsWith(FilePath, StringComparison.InvariantCultureIgnoreCase))
                {
                    IntPtr handle = p.MainWindowHandle;
                    if (IsIconic(handle))
                    {
                        ShowWindow(handle, 9);
                    }
                    SetForegroundWindow(handle);
                    break;
                }
            }
        }
    }
}