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

namespace All_Purpose_Auto_Setup
{
   public partial class frmSetupStatusDisplay : ChildForm
   {
      enum SectionName { Setup_Step_Manager };
      private delegate bool SetupStepDelegate(string iniSectionName);
      private delegate string CustomMessageBoxDelegate(MessageBoxCustom.PopUpMsgType msgType, List<MessageBoxCustom.clsCustomButton> customButtons, string msg, string caption, int timeOut_ms);
      private AutoResetEvent _resetEvent = new AutoResetEvent(false);

      private frmMain frmParent = null;

      public bool restartApplicationRequested = false;

      public bool rebootRequested = false;

      public bool setupProcessNeedRestartToContinue = false;

      BackgroundWorker bgwSetup;

      string pathAndNameOfConfigFile = "";
      string pathAndNameOfSetupLog = @"setupLog.txt";
      StreamWriter swSetupLog;

      ConfigFileManager configFileMgr;
      WindowFeaturesManager windowFeaturesMgr;
      DotNet2Pt0FrameworkManager dotNet2Pt0FrameworkMgr;
      FoldersManager gutsFoldersMgr;
      WindowsShortcutManager winShortcutMgr;
      SetupMiscellaneous gutsSetupMisc;
      SoftwareInstallManager softwareInstallMgr;
      GutsSoftwareBuildAssistant gutsBuildAssistant;
      FilePackageTransferManager fileTransferManager;
      GutsConfigFileManager gutsConfigFileManager;
      FileFolderRemovalManager fileSystemRemovalManager;
      RunApplicationsManager runAppManager;
      WindowsRegistryManager winRegistryManager;
      NetworkAdapterManager networkCardManager;

      Dictionary<int, bool> richTextBoxLineNumberDict = new Dictionary<int, bool>();

      List<ConfigFileManager.Ini_KeyValue<string>> configInfo = new List<ConfigFileManager.Ini_KeyValue<string>>();
      List<string[]> configInfoFormatted = new List<string[]>();

      public frmSetupStatusDisplay(frmMain d_parentForm)
      {
         InitializeComponent();

         this.frmParent = d_parentForm;
         this.FormClosing += Form_FormClosing;

         statusRtxtbox.WordWrap = false;
      }

      void Form_FormClosing(object sender, FormClosingEventArgs e)
      {
         if (swSetupLog != null)
            swSetupLog.Close();
      }

      private void frmSetupStatusDisplay_Shown(object sender, EventArgs e)
      {
         swSetupLog = null;

         pathAndNameOfConfigFile = frmParent.getConfigFile();

         // process the configuration file 
         configFileMgr = new ConfigFileManager(this, pathAndNameOfConfigFile);

         pathAndNameOfSetupLog = Path.Combine(Application.StartupPath, pathAndNameOfSetupLog);

         pathAndNameOfSetupLog = FileManip.GenerateUniqueFileName(Path.GetDirectoryName(pathAndNameOfSetupLog),
                        Path.GetFileNameWithoutExtension(pathAndNameOfSetupLog), Path.GetExtension(pathAndNameOfSetupLog));

         try
         {
            swSetupLog = new StreamWriter(pathAndNameOfSetupLog);
         }
         catch (Exception)
         {
            try
            {
               pathAndNameOfSetupLog = PathManip.AddTrailingSlashToPath(PathManip.GetUserDesktopPath()) + Path.GetFileName(pathAndNameOfSetupLog);

               swSetupLog = new StreamWriter(pathAndNameOfSetupLog);
            }
            catch (Exception)
            {
            }
         }

         bgwSetup = new BackgroundWorker();
         bgwSetup.WorkerSupportsCancellation = true;
         bgwSetup.DoWork += new DoWorkEventHandler(bgwSetup_DoWork);
         bgwSetup.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgwSetup_RunWorkerCompleted);

         bgwSetup.RunWorkerAsync();
      }

      private void restartApplicationEventHandler()
      {
         restartApplicationRequested = true;
      }

      private void rebootComputerEventHandler()
      {
         rebootRequested = true;
      }

      private void setupProcessNeedRestartToContinueEventHandler()
      {
         setupProcessNeedRestartToContinue = true;
      }

      private void updateStatusDisplayAndLogEventHandler(string displayMsg, string logMsg, List<CommonLib.Windows.Forms.TextFormat.TextFontAndColor> textPropList)
      {
         CommonLib.Windows.Forms.TextFormat.TextFontAndColor defaultTextProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
         defaultTextProp.textFont = new Font(defaultTextProp.textFont.Name, 9);

         FormControlsManipThreadSafe.ModifyRichTextBoxPerWords(statusRtxtbox, displayMsg, textPropList, defaultTextProp.textFont, defaultTextProp.textColor);

         if (swSetupLog != null && logMsg.Length > 0)
         {
            string str = Regex.Replace(logMsg, @"\r", "", RegexOptions.IgnoreCase);
            str = Regex.Replace(str, @"\n", "\r\n", RegexOptions.IgnoreCase);

            swSetupLog.Write(str);
            swSetupLog.Flush();
         }
      }

      public int updateStatusDisplayAndLog(string displayMsg, string logMsg, List<CommonLib.Windows.Forms.TextFormat.TextFontAndColor> textPropList)
      {
         CommonLib.Windows.Forms.TextFormat.TextFontAndColor defaultTextProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
         defaultTextProp.textFont = new Font(defaultTextProp.textFont.Name, 9);

         FormControlsManipThreadSafe.ModifyRichTextBoxPerWords(statusRtxtbox, displayMsg, textPropList, defaultTextProp.textFont, defaultTextProp.textColor);

         if (swSetupLog != null && logMsg.Length > 0)
         {
            string str = Regex.Replace(logMsg, @"\r", "", RegexOptions.IgnoreCase);
            str = Regex.Replace(str, @"\n", "\r\n", RegexOptions.IgnoreCase);

            swSetupLog.Write(str);
            swSetupLog.Flush();
         }

         return FormControlsManipThreadSafe.getRichTextBoxLastLineIndex(statusRtxtbox);
      }

      public void writeToLog(string logMsg)
      {
         if (swSetupLog != null && logMsg.Length > 0)
         {
            string str = Regex.Replace(logMsg, @"\r", "", RegexOptions.IgnoreCase);
            str = Regex.Replace(str, @"\n", "\r\n", RegexOptions.IgnoreCase);

            swSetupLog.Write(str);
            swSetupLog.Flush();
         }
      }

      public void removeStatusDisplayLine(int lineIndex, bool deleteLine)
      {
         FormControlsManipThreadSafe.RichTextBoxEraseLine(statusRtxtbox, lineIndex, deleteLine);
      }

      private void updateStatusDisplayAtLineEventHandler(string displayMsg, int lineIndex, List<CommonLib.Windows.Forms.TextFormat.TextFontAndColor> textPropList)
      {
         CommonLib.Windows.Forms.TextFormat.TextFontAndColor defaultTextProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
         defaultTextProp.textFont = new Font(defaultTextProp.textFont.Name, 9);

         FormControlsManipThreadSafe.ModifyRichTextBoxPerWordsAtLine(statusRtxtbox, lineIndex, displayMsg, textPropList, defaultTextProp.textFont, defaultTextProp.textColor);
      }

      public string displayMessageBox(MessageBoxCustom.PopUpMsgType msgType, List<MessageBoxCustom.clsCustomButton> customButtons, string msg, string caption, int timeOut_ms)
      {
         if (InvokeRequired)
         {
            CustomMessageBoxDelegate del = new CustomMessageBoxDelegate(displayMessageBox);
            return (string)this.Invoke(del, msgType, customButtons, msg, caption, timeOut_ms);
         }
         else
         {
            return MessageBoxCustom.Show(this, msgType, customButtons, msg, caption, timeOut_ms);
         }
      }

      private void bgwSetup_DoWork(object sender, DoWorkEventArgs bgwEvent)
      {
         string msg = "", errMsg = "";
         bool setupSuccessful = false;
         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>();

         BackgroundWorker bgw = sender as BackgroundWorker;

         setupSuccessful = displayAndLogHeaderInfo();

         ConfigFileManager.parseConfigInfo(SectionName.Setup_Step_Manager.ToString(), configInfo);

         if (setupSuccessful)
            setupSuccessful = verifySetupStepsInfo();

         //if (setupSuccessful)
         //   setupSuccessful = configFileMgr.verifyConfigurationInfo();

         int currentSetupStep = 0;
         if (setupSuccessful)
         {
            // manages windows features
            windowFeaturesMgr = new WindowFeaturesManager(this);
            // add an event handler to an event raised by windowFeaturesMgr
            windowFeaturesMgr.UpdateStatusDisplayAndLogEvent += updateStatusDisplayAndLogEventHandler;
            windowFeaturesMgr.UpdateStatusDisplayAtLine += updateStatusDisplayAtLineEventHandler;

            // manages .NET Framework 2.0 Settings
            dotNet2Pt0FrameworkMgr = new DotNet2Pt0FrameworkManager(this);
            // add an event handler to an event raised by dotNet2Pt0FrameworkMgr
            dotNet2Pt0FrameworkMgr.UpdateStatusDisplayAndLogEvent += updateStatusDisplayAndLogEventHandler;

            // manages file package transfer
            fileTransferManager = new FilePackageTransferManager(this);
            // add an event handler to an event raised by FilePackageTransferManager
            fileTransferManager.UpdateStatusDisplayAndLogEvent += updateStatusDisplayAndLogEventHandler;
            fileTransferManager.UpdateStatusDisplayAtLine += updateStatusDisplayAtLineEventHandler;

            // manages removal of files and folders
            fileSystemRemovalManager = new FileFolderRemovalManager(this);
            // add an event handler to an event raised by FileFolderRemovalManager
            fileSystemRemovalManager.UpdateStatusDisplayAndLogEvent += updateStatusDisplayAndLogEventHandler;
            fileSystemRemovalManager.UpdateStatusDisplayAtLine += updateStatusDisplayAtLineEventHandler;

            // manages folders
            gutsFoldersMgr = new FoldersManager(this);
            // add an event handler to an event raised by gutsFoldersMgr
            gutsFoldersMgr.UpdateStatusDisplayAndLogEvent += updateStatusDisplayAndLogEventHandler;

            // manages windows shortcut
            winShortcutMgr = new WindowsShortcutManager(this);
            // add an event handler to an event raised by WindowsShortcutManager
            winShortcutMgr.UpdateStatusDisplayAndLogEvent += updateStatusDisplayAndLogEventHandler;

            // process GUTS config file
            gutsConfigFileManager = new GutsConfigFileManager(this);
            // add an event handler to an event raised by GutsConfigFileManager
            gutsConfigFileManager.UpdateStatusDisplayAndLogEvent += updateStatusDisplayAndLogEventHandler;

            // setup miscellaneous items
            gutsSetupMisc = new SetupMiscellaneous(this);
            // add an event handler to an event raised by SetupMiscellaneous
            gutsSetupMisc.UpdateStatusDisplayAndLogEvent += updateStatusDisplayAndLogEventHandler;

            // manages software installs
            softwareInstallMgr = new SoftwareInstallManager(this);
            // add an event handler to an event raised by softwareInstallMgr
            softwareInstallMgr.UpdateStatusDisplayAndLogEvent += updateStatusDisplayAndLogEventHandler;
            softwareInstallMgr.UpdateStatusDisplayAtLine += updateStatusDisplayAtLineEventHandler;
            softwareInstallMgr.RebootComputer += rebootComputerEventHandler;
            softwareInstallMgr.SetupProcessNeedRestartToProceed += setupProcessNeedRestartToContinueEventHandler;

            // manages running applications
            runAppManager = new RunApplicationsManager(this);
            // add an event handler to an event raised by RunApplicationsManager
            runAppManager.UpdateStatusDisplayAndLogEvent += updateStatusDisplayAndLogEventHandler;
            runAppManager.UpdateStatusDisplayAtLine += updateStatusDisplayAtLineEventHandler;

            // assist in building GUTS
            gutsBuildAssistant = new GutsSoftwareBuildAssistant(this);
            // add an event handler to an event raised by GutsSoftwareBuildAssistant
            gutsBuildAssistant.UpdateStatusDisplayAndLogEvent += updateStatusDisplayAndLogEventHandler;
            gutsBuildAssistant.RestartApplication += restartApplicationEventHandler;

            winRegistryManager = new WindowsRegistryManager(this);
            winRegistryManager.UpdateStatusDisplayAndLogEvent += updateStatusDisplayAndLogEventHandler;

            networkCardManager = new NetworkAdapterManager(this);
            networkCardManager.UpdateStatusDisplayAndLogEvent += updateStatusDisplayAndLogEventHandler;

            Dictionary<Common.enum_SETUP_STEPS, SetupStepDelegate> setupStepCalls = new Dictionary<Common.enum_SETUP_STEPS, SetupStepDelegate>()
               {  { Common.enum_SETUP_STEPS.ASSIST_BUILDING_GUTS_APP, gutsBuildAssistant.gutsPrebuildCheck},
                  { Common.enum_SETUP_STEPS.CREATE_DIRECTORIES, gutsFoldersMgr.createDirectories},
                  { Common.enum_SETUP_STEPS.CREATE_WINDOWS_SHORTCUTS, winShortcutMgr.creatShortcuts},
                  { Common.enum_SETUP_STEPS.CREATE_NETWORK_SHARES, gutsFoldersMgr.shareFolders},
                  { Common.enum_SETUP_STEPS.ENABLE_INTERNET_INFORMATION_SERVICES, windowFeaturesMgr.enableWindowsOptionalFeatures},
                  { Common.enum_SETUP_STEPS.INSTALL_SOFTWARE_PACKAGES, softwareInstallMgr.manageRequiredSoftwarePackages},
                  { Common.enum_SETUP_STEPS.PROCESS_GUTS_CONFIG_FILE, gutsConfigFileManager.processGutsConfigFile},
                  { Common.enum_SETUP_STEPS.SET_DOTNET_FRAMEWORK_2_SECURITY_ZONE_LEVELS, dotNet2Pt0FrameworkMgr.adjustZoneSecurityForDotNetFrameWork2Pt0},
                  { Common.enum_SETUP_STEPS.SET_ENVIRONMENT_VARIABLES, gutsSetupMisc.setEnvironmentVariables},
                  { Common.enum_SETUP_STEPS.TRANSFER_FILE_PACKAGES, fileTransferManager.manageFilePackageTransfer},
                  { Common.enum_SETUP_STEPS.REMOVE_FILES_FOLDERS, fileSystemRemovalManager.removeFilesFolders},
                  { Common.enum_SETUP_STEPS.RUN_APPLICATIONS, runAppManager.runApplications},
                  { Common.enum_SETUP_STEPS.MODIFY_WINDOWS_REGISTRY, winRegistryManager.ModifyWindowsRegistry},
                  { Common.enum_SETUP_STEPS.CONFIGURE_NETWORK_ADAPTERS, networkCardManager.configureNetworkAdapters},
                  { Common.enum_SETUP_STEPS.PROMPT_USER, gutsSetupMisc.promptUser},
               };

            foreach (string[] entry in configInfoFormatted)
            {
               currentSetupStep++;
               Common.enum_SETUP_STEPS actualSetupstep = Common.enum_SETUP_STEPS.NOT_VALID_STEP;

               // the application had to be restart or rebooted in the middle of execution, we want to continue
               // at the point where it left off
               if ((int)Properties.Settings.Default["CurrentSetupStep"] > 0 &&
                     currentSetupStep < (int)Properties.Settings.Default["CurrentSetupStep"])
                  continue;

               if (getActualSetupStep(entry[0], ref actualSetupstep))
               {
                  setupSuccessful = setupStepCalls[actualSetupstep].Invoke(entry[1]);

                  // 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<-------------------Date and Time: " + dat1.ToString(@"MM/dd/yyyy     hh:mm:ss tt", System.Globalization.CultureInfo.InvariantCulture) + "------------------->";
                  FormControlsManipThreadSafe.ModifyRichTextBoxPerWords(statusRtxtbox, msg, textPropList, defaultTextProp.textFont, defaultTextProp.textColor);

                  writeToLog(msg);
               }

               if (!setupSuccessful || applicationNeedsToBeRestarted())
                  break;
            }
         }

         // only genereate summary if the entire setup process is complete or if an actual failure occur
         if (!applicationNeedsToBeRestarted())
         {
            // set font to default text and color
            textProp.textFont = defaultTextProp.textFont;
            textProp.textColor = defaultTextProp.textColor;

            textProp.wordIndex = 0;
            textProp.wordCount = 3;
            textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
            textPropList.Add(textProp);

            msg = "\n\nOVERALL SETUP STATUS: ";

            if (!setupSuccessful)
            {
               msg += " - FAILED.";

               // 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 = 10;
               textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
               textPropList.Add(textProp);

               Properties.Settings.Default["CurrentSetupStep"] = currentSetupStep;
            }
            else
            {
               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 = 10;
               textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
               textPropList.Add(textProp);

               Properties.Settings.Default["CurrentSetupStep"] = -1;

               string registryPath = @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon";
               // disable windows auto login
               WindowsRegistry.AddOrModifyRegistryKeySingleValue(registryPath, Microsoft.Win32.RegistryHive.LocalMachine, "AutoAdminLogon", Microsoft.Win32.RegistryValueKind.String, "0", ref errMsg);
               // delete user password
               WindowsRegistry.DeleteRegistryValueName(registryPath, Microsoft.Win32.RegistryHive.LocalMachine, "DefaultPassword", ref errMsg);
            }

            FormControlsManipThreadSafe.ModifyRichTextBoxPerWords(statusRtxtbox, msg, textPropList, defaultTextProp.textFont, defaultTextProp.textColor);

            msg = Regex.Replace(msg, @"\r", "", RegexOptions.IgnoreCase);
            msg = Regex.Replace(msg, @"\n", "\r\n", RegexOptions.IgnoreCase);
            swSetupLog.Write(msg);

            // set font to default text and color
            textProp.textFont = defaultTextProp.textFont;
            textProp.textColor = defaultTextProp.textColor;

            textProp.wordIndex = 0;
            textProp.wordCount = 3;
            textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
            textPropList.Add(textProp);

            msg = "\nSETUP COMPLETED.";

            FormControlsManipThreadSafe.ModifyControlText(btnCancel, "CLOSE");

            FormControlsManipThreadSafe.ModifyRichTextBoxPerWords(statusRtxtbox, msg, textPropList, defaultTextProp.textFont, defaultTextProp.textColor);

            msg = Regex.Replace(msg, @"\r", "", RegexOptions.IgnoreCase);
            msg = Regex.Replace(msg, @"\n", "\r\n", RegexOptions.IgnoreCase);
            swSetupLog.Write(msg);

            DateTime dat1 = DateTime.Now;
            msg = StringManip.TextAlign("\nDate and Time: ", 25, StringManip.enumTextHorizontalAlignment.Left) + dat1.ToString(@"MM/dd/yyyy     hh:mm:ss tt", System.Globalization.CultureInfo.InvariantCulture);
            FormControlsManipThreadSafe.ModifyRichTextBoxPerWords(statusRtxtbox, msg, textPropList, defaultTextProp.textFont, defaultTextProp.textColor);

            writeToLog(msg);
         }
         else
         {
            if (restartApplicationRequested)
            {
               if (setupSuccessful)
               {
                  if (!ConfigFileManager.ms_configGlobalSettings.suppressAllPrompts.alternateValue)
                     displayMessageBox(MessageBoxCustom.PopUpMsgType.INFO, null, "The application needs to be restarted.\n\n.Press OK to restart the application now.", "Info", -1);
               }
               else
                  restartApplicationRequested = false;
            }

            Properties.Settings.Default["CurrentSetupStep"] = currentSetupStep;
         }

         if (rebootRequested)
         {
            if (setupSuccessful)
            {
               if (!ConfigFileManager.ms_configGlobalSettings.suppressAllPrompts.alternateValue)
               {
                  msg = displayMessageBox(MessageBoxCustom.PopUpMsgType.YESNO, null, "Reboot is required for the previous changes to take effect.\n\nWould you like reboot now?", "Info", -1);

                  if (String.Equals(msg, "no", StringComparison.OrdinalIgnoreCase))
                  {
                     rebootRequested = false;
                  }
               }
            }
            else
               rebootRequested = false;
         }
      }

      private void bgwSetup_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
      {
         // if an exception is thrown
         if (e.Error != null)
         {

         }
         else
         {
            swSetupLog.Close();

            if (restartApplicationRequested || rebootRequested)
            {
               this.Close();
            }
         }
      }

      private bool getActualSetupStep(string strSetupStep, ref Common.enum_SETUP_STEPS enumSetupStep)
      {
         bool successful = false;
         enumSetupStep = Common.enum_SETUP_STEPS.NOT_VALID_STEP;

         foreach (Common.enum_SETUP_STEPS enumStep in Enum.GetValues(typeof(Common.enum_SETUP_STEPS)))
         {
            if (String.Equals(strSetupStep, enumStep.ToString(), StringComparison.OrdinalIgnoreCase))
            {
               successful = true;
               enumSetupStep = enumStep;
            }
         }

         return successful;
      }

      public bool applicationNeedsToBeRestarted()
      {
         bool restart = false;
         if (restartApplicationRequested || setupProcessNeedRestartToContinue)
            restart = true;

         return restart;
      }

      private bool verifySetupStepsInfo()
      {
         bool setupSuccessful = true;
         string msg;
         ConfigFileManager.Ini_KeyValue<string> iniVal = new ConfigFileManager.Ini_KeyValue<string>("");
         string indentation = 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>();

         // set font to default text and color
         textProp.textFont = defaultTextProp.textFont;
         textProp.textColor = Common.getSetupStepTitleColor();
         textProp.wordIndex = 0;
         textProp.wordCount = 10;
         // 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\n-=Verifying setup step information=-";
         FormControlsManipThreadSafe.ModifyRichTextBoxPerWords(statusRtxtbox, msg, textPropList, defaultTextProp.textFont, defaultTextProp.textColor);
         writeToLog(msg);

         if (configInfo.Count == 0)
         {
            indentation = Common.getIndentation(1);
            msg = "\n" + indentation + "- FAILED. "
               + "\n" + indentation + "File: " + ConfigFileManager.ms_configGeneralInfo.pathAndNameOfConfigFile
               + "\n" + indentation + "Error Description: The section " + SectionName.Setup_Step_Manager + " doesn't exist or have no entries.";

            Common.formatConfigIniFailureMessage(msg, textPropList);

            FormControlsManipThreadSafe.ModifyRichTextBoxPerWords(statusRtxtbox, msg, textPropList, defaultTextProp.textFont, defaultTextProp.textColor);
            swSetupLog.Write(msg);

            setupSuccessful = false;
         }

         if (setupSuccessful)
         {
            foreach (ConfigFileManager.Ini_KeyValue<string> entry in configInfo)
            {
               List<string> pair = new List<string>(entry.iniValue.Split(new string[] { "," }, StringSplitOptions.None));

               if (pair.Count <= 2)
               {
                  pair[0] = pair[0].Trim();

                  if (pair.Count == 1)
                     pair.Add("");

                  pair[1] = pair[1].Trim();

                  Common.enum_SETUP_STEPS actualSetupstep = Common.enum_SETUP_STEPS.NOT_VALID_STEP;

                  if (getActualSetupStep(pair[0], ref actualSetupstep))
                  {
                     configInfoFormatted.Add(new string[2] { pair[0], pair[1] });
                  }
                  else
                  {
                     indentation = Common.getIndentation(1);
                     msg = "\n" + indentation + "- FAILED. "
                        + "\n" + indentation + "File: " + ConfigFileManager.ms_configGeneralInfo.pathAndNameOfConfigFile
                        + "\n" + indentation + "Section: " + entry.iniSectionName
                        + "\n" + indentation + "Key: " + entry.iniKeyName
                        + "\n" + indentation + "Value: " + entry.iniValue
                        + "\n" + indentation + "Error Description: The setup step \"" + pair[0] + "\" specified in the value above is invalid";

                     Common.formatConfigIniFailureMessage(msg, textPropList);

                     FormControlsManipThreadSafe.ModifyRichTextBoxPerWords(statusRtxtbox, msg, textPropList, defaultTextProp.textFont, defaultTextProp.textColor);
                     writeToLog(msg);

                     setupSuccessful = false;

                     break;
                  }
               }
               else
               {
                  indentation = Common.getIndentation(1);
                  msg = "\n" + indentation + "- FAILED. "
                     + "\n" + indentation + "File: " + ConfigFileManager.ms_configGeneralInfo.pathAndNameOfConfigFile
                     + "\n" + indentation + "Section: " + entry.iniSectionName
                     + "\n" + indentation + "Key: " + entry.iniKeyName
                     + "\n" + indentation + "Value: " + entry.iniValue
                     + "\n" + indentation + "Error Description: The value is invalid the INI file. Expecting install step and associated section name separated by comma";

                  Common.formatConfigIniFailureMessage(msg, textPropList);

                  FormControlsManipThreadSafe.ModifyRichTextBoxPerWords(statusRtxtbox, msg, textPropList, defaultTextProp.textFont, defaultTextProp.textColor);
                  writeToLog(msg);

                  setupSuccessful = false;

                  break;
               }
            }
         }

         if (setupSuccessful)
         {
            // set font to default text and color
            textProp.textFont = defaultTextProp.textFont;
            textProp.textColor = defaultTextProp.textColor;

            textProp.wordIndex = 0;
            textProp.wordCount = 3;
            textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SUCCESS);
            textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
            textPropList.Add(textProp);

            indentation = Common.getIndentation(1);
            msg = "\n" + indentation + "- SUCCESS.";
            FormControlsManipThreadSafe.ModifyRichTextBoxPerWords(statusRtxtbox, msg, textPropList, defaultTextProp.textFont, defaultTextProp.textColor);
            writeToLog(msg);
         }

         return setupSuccessful;
      }

      private bool displayAndLogHeaderInfo()
      {
         bool setupSuccessful = true;
         CommonLib.Windows.Forms.TextFormat.TextFontAndColor defaultTextProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
         defaultTextProp.textFont = new Font(defaultTextProp.textFont.Name, 9);
         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>();

         string msg;

         if (ConfigFileManager.ms_configGeneralInfo.programName.iniValue.Length > 0)
         {
            // set font to default text and color
            textProp.textFont = defaultTextProp.textFont;
            textProp.textColor = defaultTextProp.textColor;

            textProp.wordIndex = 0;
            textProp.wordCount = 10;
            textProp.textColor = Color.BlueViolet;
            textProp.textFont = new Font("Tahoma", 17, FontStyle.Bold | FontStyle.Underline);
            textPropList.Add(textProp);

            msg = ConfigFileManager.ms_configGeneralInfo.programName.iniValue;
         }
         else
         {
            msg = "\n\nFAILURE ENCOUNTERED: "
                           + "\nFile: " + ConfigFileManager.ms_configGeneralInfo.pathAndNameOfConfigFile + " "
                           + "\nSection: " + ConfigFileManager.ms_configGeneralInfo.programName.iniSectionName + " "
                           + "\nKey: " + ConfigFileManager.ms_configGeneralInfo.programName.iniKeyName + " "
                           + "\nValue: " + ConfigFileManager.ms_configGeneralInfo.programName.iniValue + " "
                           + "\nError Description: Either one or a combination of Section, Key, or Value is not defined in the INI file.";

            Common.formatConfigIniFailureMessage(msg, textPropList);

            setupSuccessful = false;
         }
         FormControlsManipThreadSafe.ModifyRichTextBoxPerWords(statusRtxtbox, msg, textPropList, defaultTextProp.textFont, defaultTextProp.textColor);
         writeToLog(msg);

         if (setupSuccessful)
         {
            // set font to default text and color
            textProp.textFont = defaultTextProp.textFont;
            textProp.textColor = defaultTextProp.textColor;

            textProp.wordIndex = 0;
            textProp.wordCount = 3;
            textProp.textColor = Color.Brown;
            textProp.textFont = new Font("Courier New", 10, FontStyle.Regular);
            textPropList.Add(textProp);

            textProp.textColor = Color.Black;
            textProp.wordIndex = 3;
            textProp.wordCount = 100;
            textPropList.Add(textProp);

            DateTime dat1 = DateTime.Now;
            msg = StringManip.TextAlign("\nDate and Time: ", 25, StringManip.enumTextHorizontalAlignment.Left) + dat1.ToString(@"MM/dd/yyyy     hh:mm:ss tt", System.Globalization.CultureInfo.InvariantCulture);
            FormControlsManipThreadSafe.ModifyRichTextBoxPerWords(statusRtxtbox, msg, textPropList, defaultTextProp.textFont, defaultTextProp.textColor);

            writeToLog(msg);
         }

         if (setupSuccessful)
         {
            if (ConfigFileManager.ms_configGeneralInfo.applicationPlatform.iniValue.Length > 0)
            {
               // set font to default text and color
               textProp.textFont = defaultTextProp.textFont;
               textProp.textColor = defaultTextProp.textColor;

               textProp.wordIndex = 0;
               textProp.wordCount = 2;
               textProp.textColor = Color.Brown;
               textProp.textFont = new Font("Courier New", 10, FontStyle.Regular);
               textPropList.Add(textProp);

               textProp.textColor = Color.Black;
               textProp.wordIndex = 2;
               textProp.wordCount = 100;
               textPropList.Add(textProp);

               msg = StringManip.TextAlign("\nApplication Platform: ", 25, StringManip.enumTextHorizontalAlignment.Left) + ConfigFileManager.ms_configGeneralInfo.applicationPlatform.iniValue + "-Bit";
            }
            else
            {
               msg = "\n\nFAILURE ENCOUNTERED: "
                              + "\nFile: " + ConfigFileManager.ms_configGeneralInfo.pathAndNameOfConfigFile + " "
                              + "\nSection: " + ConfigFileManager.ms_configGeneralInfo.applicationPlatform.iniSectionName + " "
                              + "\nKey: " + ConfigFileManager.ms_configGeneralInfo.applicationPlatform.iniKeyName + " "
                              + "\nValue: " + ConfigFileManager.ms_configGeneralInfo.applicationPlatform.iniValue + " "
                              + "\nError Description: Either one or a combination of Section, Key, or Value is not defined in the INI file.";

               Common.formatConfigIniFailureMessage(msg, textPropList);

               setupSuccessful = false;
            }
            FormControlsManipThreadSafe.ModifyRichTextBoxPerWords(statusRtxtbox, msg, textPropList, defaultTextProp.textFont, defaultTextProp.textColor);

            writeToLog(msg);
         }

         return setupSuccessful;
      }

      private void btnCancel_Click(object sender, EventArgs e)
      {
         if (String.Equals(btnCancel.Text, "close", StringComparison.OrdinalIgnoreCase))
         {
            this.Close();
         }
      }
   }
}
