using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using CommonLib.IO;
using CommonLib.Misc;
using CommonLib.Windows.Forms;
using CommonLib.Windows.Misc;

namespace All_Purpose_Auto_Setup
{
   class WindowsShortcutManager
   {
      // An event that can be raised, allowing other classes to
      // subscribe to it and do what they like with the message.
      public event Action<string, string, List<CommonLib.Windows.Forms.TextFormat.TextFontAndColor>> UpdateStatusDisplayAndLogEvent;

      // this dictionary stores shortcut name and its associated target_path and arguments
      // it would look like this:
      // [ shortcut1_name ]  ->  List[target_path,arguments]
      // [ shortcut2_name ]  ->  List[target_path,arguments]
      public Dictionary<ConfigFileManager.Ini_KeyValue<string>, List<ConfigFileManager.Ini_KeyValue<string>>> shortcutNameToTargetAndArgs = new Dictionary<ConfigFileManager.Ini_KeyValue<string>, List<ConfigFileManager.Ini_KeyValue<string>>>();

      Form m_parentForm;

      public WindowsShortcutManager(Form parentForm)
      {
         m_parentForm = parentForm;
      }

      public bool creatShortcuts(string sectionName)
      {
         string indentation = String.Empty;
         bool setupSuccessful = true;
         string msg, msg2, shortcutArgs;
         string tempPath = "";

         string shortcutPath = String.Empty;
         string shortcutTargetPath = String.Empty;
         string shortcutLocation = String.Empty;

         CommonLib.Windows.Forms.TextFormat.TextFontAndColor defaultTextProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
         CommonLib.Windows.Forms.TextFormat.TextFontAndColor textProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
         List<CommonLib.Windows.Forms.TextFormat.TextFontAndColor> textPropList = new List<CommonLib.Windows.Forms.TextFormat.TextFontAndColor>();

         bool createShortcut = true;
         bool statusGiven = false;

         // set font to default text and color
         textProp.textFont = defaultTextProp.textFont;
         textProp.textColor = Common.getSetupStepTitleColor();
         textProp.wordIndex = 0;
         textProp.wordCount = 100;
         textPropList.Add(textProp);

         DateTime dat1 = DateTime.Now;
         msg = "\n\n<-------------------Date and Time: " + dat1.ToString(@"MM/dd/yyyy     hh:mm:ss tt", System.Globalization.CultureInfo.InvariantCulture) + "------------------->";

         UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
         // set font to default text and color
         textProp.textFont = defaultTextProp.textFont;
         textProp.textColor = Common.getSetupStepTitleColor();
         textProp.wordIndex = 0;
         textProp.wordCount = 100;
         // set font size
         textProp.textFont = new Font(textProp.textFont.Name, 12);
         // set font style
         textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
         textPropList.Add(textProp);

         msg = "\n-=Creating Windows Shortcuts=-";
         UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);

         shortcutNameToTargetAndArgs.Clear();

         ConfigFileManager.readOneToManyDictionary(ConfigFileManager.ms_configGeneralInfo.iniFile,
                    sectionName, @"(shortcut\d+)_name$", @"(shortcut\d+)_.+", shortcutNameToTargetAndArgs);

         if (setupSuccessful)
         {
            foreach (KeyValuePair<ConfigFileManager.Ini_KeyValue<string>, List<ConfigFileManager.Ini_KeyValue<string>>> entry in shortcutNameToTargetAndArgs)
            {
               shortcutLocation = getShortcutLocation(entry.Value);

               if (shortcutLocation.Length > 0)
               {
                  shortcutPath = Path.Combine(shortcutLocation, entry.Key.iniValue) + ".lnk";
                  shortcutTargetPath = getShortcutTargetPath(entry.Value);
                  shortcutArgs = getShortcutArguments(entry.Value);

                  indentation = Common.getIndentation(1);
                  msg = "\n" + indentation + shortcutPath;

                  if (String.Equals(PathManip.AddTrailingSlashToPath(shortcutLocation), PathManip.AddTrailingSlashToPath(PathManip.GetUserStartupFolderPath()), StringComparison.CurrentCultureIgnoreCase))
                  {
                     tempPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonStartup), entry.Key.iniValue) + ".lnk";

                     if (File.Exists(tempPath))
                     {
                        msg += " - SKIPPED. This shortcut already exists for all users";

                        // set font to default text and color
                        textProp.textFont = defaultTextProp.textFont;
                        textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.USER_SKIP);
                        textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "SKIPPED."); ;
                        textProp.wordCount = 1;
                        // set font style
                        textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
                        textPropList.Add(textProp);

                        UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);

                        createShortcut = false;

                        if (!statusGiven)
                           statusGiven = true;
                     }
                  }
                  else if (String.Equals(PathManip.AddTrailingSlashToPath(shortcutLocation), PathManip.AddTrailingSlashToPath(PathManip.GetUserDesktopPath()), StringComparison.CurrentCultureIgnoreCase))
                  {
                     tempPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonDesktopDirectory), entry.Key.iniValue) + ".lnk";

                     if (File.Exists(tempPath))
                     {
                        msg += " - SKIPPED. This shortcut already exists for all users";

                        // set font to default text and color
                        textProp.textFont = defaultTextProp.textFont;
                        textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.USER_SKIP);
                        textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "SKIPPED."); ;
                        textProp.wordCount = 1;
                        // set font style
                        textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
                        textPropList.Add(textProp);

                        UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);

                        createShortcut = false;

                        if (!statusGiven)
                           statusGiven = true;
                     }
                  }

                  if (!statusGiven && File.Exists(shortcutPath))
                  {
                     msg2 = ((frmSetupStatusDisplay)m_parentForm).displayMessageBox(MessageBoxCustom.PopUpMsgType.YESNO, null, "Shortcut \"" + Path.GetFileName(shortcutPath) + "\" already exists.\n\nDo you wish to overwrite it?", "Warning!!!", -1);

                     if (!String.Equals(msg2, "yes", StringComparison.OrdinalIgnoreCase))
                     {
                        msg += " - SKIPPED. Shortcut already exists";

                        // set font to default text and color
                        textProp.textFont = defaultTextProp.textFont;
                        textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.USER_SKIP);
                        textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "SKIPPED."); ;
                        textProp.wordCount = 1;
                        // set font style
                        textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
                        textPropList.Add(textProp);

                        UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);

                        createShortcut = false;

                        if (!statusGiven)
                           statusGiven = true;
                     }
                  }

                  if (shortcutPath.Length == 0 || shortcutTargetPath.Length == 0 || shortcutLocation.Length == 0)
                  {
                     createShortcut = false;
                  }

                  if (createShortcut)
                  {
                     try
                     {
                        File.Delete(shortcutPath);

                        WindowShortcut.Create(shortcutPath, shortcutTargetPath, shortcutArgs, Path.GetDirectoryName(shortcutTargetPath), "", "", null);

                        msg += " - SUCCESS.";

                        // set font to default text and color
                        textProp.textFont = defaultTextProp.textFont;
                        textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SUCCESS);
                        textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "SUCCESS."); ;
                        textProp.wordCount = 1;
                        // set font style
                        textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
                        textPropList.Add(textProp);
                     }
                     catch (Exception e)
                     {
                        msg += " - FAILED. (" + e.Message + ")";

                        // set font to default text and color
                        textProp.textFont = defaultTextProp.textFont;
                        textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
                        textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "FAILED."); ;
                        textProp.wordCount = 1;
                        // set font style
                        textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
                        textPropList.Add(textProp);

                        setupSuccessful = false;
                     }

                     if (!statusGiven)
                        statusGiven = true;

                     UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
                  }
               }
               else
               {
                  // set font to default text and color
                  textProp.textFont = defaultTextProp.textFont;
                  textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
                  textProp.wordIndex = 0;
                  textProp.wordCount = 2;
                  // set font style
                  textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
                  textPropList.Add(textProp);

                  indentation = Common.getIndentation(1);
                  msg = "\n" + indentation + "- FAILED. Unable to determine Windows Login Id";

                  UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);

                  if (!statusGiven)
                     statusGiven = true;

                  break;
               }
               createShortcut = true;
            }

            if (!statusGiven)
            {
               // set font to default text and color
               textProp.textFont = defaultTextProp.textFont;
               textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SYSTEM_SKIP);
               textProp.wordIndex = 0;
               textProp.wordCount = 2;
               // set font style
               textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
               textPropList.Add(textProp);

               indentation = Common.getIndentation(1);
               msg = "\n" + indentation + "- SKIPPED. No configuration info found";

               UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
            }
         }

         return setupSuccessful;
      }


      public string getShortcutTargetPath(List<ConfigFileManager.Ini_KeyValue<string>> iniKeys)
      {
         string targetPath = "";

         foreach (ConfigFileManager.Ini_KeyValue<string> iniKey in iniKeys)
         {
            if (Regex.IsMatch(iniKey.iniKeyName, @"shortcut\d+_target_path", RegexOptions.IgnoreCase))
            {
               targetPath = iniKey.iniValue;
               break;
            }
         }

         return targetPath;
      }

      public string getShortcutArguments(List<ConfigFileManager.Ini_KeyValue<string>> iniKeys)
      {
         string args = "";

         foreach (ConfigFileManager.Ini_KeyValue<string> iniKey in iniKeys)
         {
            if (Regex.IsMatch(iniKey.iniKeyName, @"shortcut\d+_arguments", RegexOptions.IgnoreCase))
            {
               args = iniKey.iniValue;
               break;
            }
         }

         return args;
      }

      public string getShortcutLocation(List<ConfigFileManager.Ini_KeyValue<string>> iniKeys)
      {
         string location = "";

         foreach (ConfigFileManager.Ini_KeyValue<string> iniKey in iniKeys)
         {
            if (Regex.IsMatch(iniKey.iniKeyName, @"shortcut\d+_location", RegexOptions.IgnoreCase))
            {
               location = Common.resolveMacroPath(iniKey.iniValue);

               if (String.IsNullOrEmpty(location))
               {
                  if (Directory.Exists(iniKey.iniValue))
                  {
                     location = iniKey.iniValue;
                  }
               }
            }
         }

         return location;
      }
   }
}
