/// <summary>
        /// Downloads the driver and some other stuff
        /// </summary>
        private static void DownloadDriver()
        {
            DriverDialog.ShowGUI();

            if (DriverDialog.selectedBtn == DriverDialog.SelectedBtn.DLEXTRACT)
            {
                // download and save (and extract)
                Console.WriteLine();
                bool error = false;
                driverFileName = downloadURL.Split('/').Last(); // retrives file name from url

                try {
                    string message = "Where do you want to save the drivers?";

                    if (SettingManager.ReadSettingBool("Minimal install"))
                    {
                        message += " (you should select a empty folder)";
                    }

                    FolderSelectDialog folderSelectDialog = new FolderSelectDialog();
                    folderSelectDialog.Title = message;

                    if (folderSelectDialog.Show())
                    {
                        savePath = folderSelectDialog.FileName + @"\";
                    }
                    else
                    {
                        Console.WriteLine("User closed dialog!");
                        return;
                    }

                    if (File.Exists(savePath + driverFileName) && !DoesDriverFileSizeMatch(savePath + driverFileName))
                    {
                        LogManager.Log($"Deleting {savePath}{driverFileName} because its length doesn't match!", LogManager.Level.INFO);
                        File.Delete(savePath + driverFileName);
                    }

                    // don't download driver if it already exists
                    Console.Write("Downloading the driver . . . ");
                    if (showUI && !File.Exists(savePath + driverFileName))
                    {
                        using (WebClient webClient = new WebClient()) {
                            var notifier = new AutoResetEvent(false);
                            var progress = new Handlers.ProgressBar();

                            webClient.DownloadProgressChanged += delegate(object sender, DownloadProgressChangedEventArgs e)
                            {
                                progress.Report((double)e.ProgressPercentage / 100);
                            };

                            // Only set notifier here!
                            webClient.DownloadFileCompleted += delegate(object sender, AsyncCompletedEventArgs e)
                            {
                                if (e.Cancelled || e.Error != null)
                                {
                                    File.Delete(savePath + driverFileName);
                                }
                                else
                                {
                                    notifier.Set();
                                }
                            };

                            webClient.DownloadFileAsync(new Uri(downloadURL), savePath + driverFileName);

                            notifier.WaitOne(); // sync with the above
                            progress.Dispose(); // get rid of the progress bar
                        }
                    }
                    // show the progress bar gui
                    else if (!showUI && !File.Exists(savePath + driverFileName))
                    {
                        using (DownloaderForm dlForm = new DownloaderForm()) {
                            dlForm.Show();
                            dlForm.Focus();
                            dlForm.DownloadFile(new Uri(downloadURL), savePath + driverFileName);
                            dlForm.Close();
                        }
                    }
                    else
                    {
                        LogManager.Log("Driver is already downloaded", LogManager.Level.INFO);
                    }
                } catch (Exception ex) {
                    error = true;
                    Console.Write("ERROR!");
                    Console.WriteLine();
                    Console.WriteLine(ex.ToString());
                    Console.WriteLine();
                }

                if (!error)
                {
                    Console.Write("OK!");
                    Console.WriteLine();
                }

                if (debug)
                {
                    Console.WriteLine($"savePath: {savePath}");
                }

                if (SettingManager.ReadSettingBool("Minimal install"))
                {
                    MakeInstaller(false);
                }
            }
            else if (DriverDialog.selectedBtn == DriverDialog.SelectedBtn.DLINSTALL)
            {
                DownloadDriverQuiet(false);
            }
        }
        private static void Main(string[] args)
        {
            string message = "TinyNvidiaUpdateChecker v" + offlineVer;

            LogManager.Log(message, LogManager.Level.INFO);
            Console.Title = message;

            CheckArgs(args);

            RunIntro(); // will run intro if no args needs to output stuff

            if (showUI)
            {
                AllocConsole();

                if (!debug)
                {
                    GenericHandler.DisableQuickEdit();
                }
            }

            SettingManager.ConfigInit();

            CheckDependencies();

            CheckWinVer();

            GetLanguage();

            if (SettingManager.ReadSettingBool("Check for Updates"))
            {
                SearchForUpdates();
            }

            GpuInfo();

            bool hasSelected = false;
            int  iOffline    = 0;

            try {
                iOffline = Convert.ToInt32(OfflineGPUVersion.Replace(".", string.Empty));
            } catch (Exception ex) {
                OfflineGPUVersion = "Unknown";
                Console.WriteLine("Could not retrive OfflineGPUVersion!");
                Console.WriteLine(ex.ToString());
            }

            int iOnline = Convert.ToInt32(OnlineGPUVersion.Replace(".", string.Empty));

            if (iOnline == iOffline)
            {
                Console.WriteLine("Your GPU drivers are up-to-date!");
            }
            else
            {
                if (iOffline > iOnline)
                {
                    Console.WriteLine("Your current GPU driver is newer than remote!");
                }
                if (iOnline < iOffline)
                {
                    Console.WriteLine("Your GPU drivers are up-to-date!");
                }
                else
                {
                    Console.WriteLine("There are new drivers available to download!");
                    hasSelected = true;

                    if (confirmDL)
                    {
                        DownloadDriverQuiet(true);
                    }
                    else
                    {
                        DownloadDriver();
                    }
                }
            }

            if (!hasSelected && forceDL)
            {
                if (confirmDL)
                {
                    DownloadDriverQuiet(true);
                }
                else
                {
                    DownloadDriver();
                }
            }

            Console.WriteLine();
            Console.WriteLine("Job done! Press any key to exit.");
            if (showUI)
            {
                Console.ReadKey();
            }
            LogManager.Log("BYE!", LogManager.Level.INFO);
            Environment.Exit(0);
        }
        /// <summary>
        /// Check if dependencies are all OK
        /// </summary>
        private static void CheckDependencies()
        {
            // Check internet connection
            Console.Write("Verifying internet connection . . . ");
            switch (NetworkInterface.GetIsNetworkAvailable())
            {
            case true:
                Console.Write("OK!");
                Console.WriteLine();
                break;

            default:
                Console.Write("ERROR!");
                Console.WriteLine();
                Console.WriteLine("No internet connection was found, the application will now terminate!");
                if (showUI)
                {
                    Console.ReadKey();
                }
                Environment.Exit(2);
                break;
            }

            var hap = "HtmlAgilityPack.dll";

            if (File.Exists(hap))
            {
                Console.WriteLine();
                Console.Write("Verifying HAP hash . . . ");
                var hash = HashHandler.CalculateMD5(hap);

                if (hash.md5 != HashHandler.HAP_HASH && hash.error == false)
                {
                    Console.Write("ERROR!");
                    Console.WriteLine();
                    Console.WriteLine("Deleting the invalid HAP file.");

                    try {
                        //fFile.Delete(hap);
                    } catch (Exception ex) {
                        Console.WriteLine(ex.ToString());
                    }

                    // delete HAP file as it couldn't be verified
                }
                else if (hash.error)
                {
                    try {
                        File.Delete(hap);
                    } catch (Exception ex) {
                        Console.WriteLine(ex.ToString());
                    }
                }
                else
                {
                    Console.Write("OK!");
                    Console.WriteLine();
                }

                if (debug)
                {
                    Console.WriteLine("Generated hash: " + hash.md5);
                    Console.WriteLine("Known hash:     " + HashHandler.HAP_HASH);
                }
            }

            if (!File.Exists(hap))
            {
                Console.WriteLine();
                Console.Write("Attempting to download HtmlAgilityPack.dll . . . ");

                try {
                    using (WebClient webClient = new WebClient()) {
                        webClient.DownloadFile($"https://github.com/ElPumpo/TinyNvidiaUpdateChecker/releases/download/v{offlineVer}/HtmlAgilityPack.dll", "HtmlAgilityPack.dll");
                    }
                    Console.Write("OK!");
                    Console.WriteLine();
                } catch (Exception ex) {
                    Console.Write("ERROR!");
                    Console.WriteLine();
                    Console.WriteLine(ex.ToString());
                    Console.WriteLine();
                }
            }
            var currentHapVersion = AssemblyName.GetAssemblyName(hap).Version.ToString();

            // compare HAP version too
            if (new Version(HashHandler.HAP_VERSION).CompareTo(new Version(currentHapVersion)) > 0)
            {
                Console.WriteLine("ERROR: The current HAP libary v{0} does not match the wanted v{1}", currentHapVersion, HashHandler.HAP_VERSION);
                Console.WriteLine("The application has been terminated to prevent a error message by .NET");
                if (showUI)
                {
                    Console.ReadKey();
                }
                Environment.Exit(1);
            }

            if (SettingManager.ReadSettingBool("Minimal install"))
            {
                if (LibaryHandler.EvaluateLibary() == null)
                {
                    Console.WriteLine("Doesn't seem like either WinRAR or 7-Zip is installed!");
                    DialogResult dialogUpdates = MessageBox.Show("Do you want to disable the minimal install feature and use the traditional way?", "TinyNvidiaUpdateChecker", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                    if (dialogUpdates == DialogResult.Yes)
                    {
                        SettingManager.SetSetting("Minimal install", "false");
                    }
                    else
                    {
                        Console.WriteLine("The application will terminate itself");
                        if (showUI)
                        {
                            Console.ReadKey();
                        }
                        Environment.Exit(1);
                    }
                }
            }

            Console.WriteLine();
        }
        /// <summary>
        /// Downloads and installs the driver without user interaction
        /// </summary>
        private static void DownloadDriverQuiet(bool minimized)
        {
            driverFileName = downloadURL.Split('/').Last(); // retrives file name from url
            savePath       = Path.GetTempPath();

            string FULL_PATH_DIRECTORY = savePath + OnlineGPUVersion + @"\";
            string FULL_PATH_DRIVER    = FULL_PATH_DIRECTORY + driverFileName;

            savePath = FULL_PATH_DIRECTORY;

            Directory.CreateDirectory(FULL_PATH_DIRECTORY);

            if (File.Exists(FULL_PATH_DRIVER) && !DoesDriverFileSizeMatch(FULL_PATH_DRIVER))
            {
                LogManager.Log("Deleting " + FULL_PATH_DRIVER + " because its length doesn't match!", LogManager.Level.INFO);
                File.Delete(savePath + driverFileName);
            }

            if (!File.Exists(FULL_PATH_DRIVER))
            {
                Console.Write("Downloading the driver . . . ");

                if (showUI || confirmDL)
                {
                    using (WebClient webClient = new WebClient()) {
                        var  notifier = new AutoResetEvent(false);
                        var  progress = new Handlers.ProgressBar();
                        bool error    = false;

                        webClient.DownloadProgressChanged += delegate(object sender, DownloadProgressChangedEventArgs e)
                        {
                            progress.Report((double)e.ProgressPercentage / 100);
                        };

                        // Only set notifier here!
                        webClient.DownloadFileCompleted += delegate(object sender, AsyncCompletedEventArgs e)
                        {
                            if (e.Cancelled || e.Error != null)
                            {
                                File.Delete(savePath + driverFileName);
                            }
                            else
                            {
                                notifier.Set();
                            }
                        };

                        try {
                            webClient.DownloadFileAsync(new Uri(downloadURL), FULL_PATH_DRIVER);
                            notifier.WaitOne();
                        } catch (Exception ex) {
                            error = true;
                            Console.Write("ERROR!");
                            Console.WriteLine();
                            Console.WriteLine(ex.ToString());
                            Console.WriteLine();
                        }

                        progress.Dispose(); // dispone the progress bar

                        if (!error)
                        {
                            Console.Write("OK!");
                            Console.WriteLine();
                        }
                    }
                }
                else
                {
                    using (DownloaderForm dlForm = new DownloaderForm()) {
                        dlForm.Show();
                        dlForm.Focus();
                        dlForm.DownloadFile(new Uri(downloadURL), FULL_PATH_DRIVER);
                        dlForm.Close();
                    }
                }
            }

            if (SettingManager.ReadSettingBool("Minimal install"))
            {
                MakeInstaller(minimized);
            }

            try {
                Console.WriteLine();
                Console.Write("Running installer . . . ");
                if (SettingManager.ReadSettingBool("Minimal install"))
                {
                    Process.Start(FULL_PATH_DIRECTORY + "setup.exe", "/s /noreboot").WaitForExit();
                }
                else
                {
                    if (minimized)
                    {
                        Process.Start(FULL_PATH_DRIVER, "/s /noreboot").WaitForExit();
                    }
                    else
                    {
                        Process.Start(FULL_PATH_DRIVER, "/noeula").WaitForExit();
                    }
                }

                Console.Write("OK!");
            } catch {
                Console.WriteLine("Could not run driver installer!");
            }

            Console.WriteLine();

            try {
                Directory.Delete(FULL_PATH_DIRECTORY, true);
                Console.WriteLine("Cleaned up: " + FULL_PATH_DIRECTORY);
            } catch {
                Console.WriteLine("Could not cleanup: " + FULL_PATH_DIRECTORY);
            }
        }
        /// <summary>
        /// Downloads the driver and some other stuff
        /// </summary>
        private static void DownloadDriver()
        {
            int    DateDiff = (DateTime.Now - releaseDate).Days; // how many days between the two dates
            string theDate  = null;

            if (DateDiff == 1)
            {
                theDate = DateDiff + " day ago";
            }
            else if (DateDiff < 1)
            {
                theDate = "today"; // we only have the date and not time :/
            }
            else
            {
                theDate = DateDiff + " days ago";
            }

            string message = "Graphics card drivers are available, do you want to update now?" + Environment.NewLine + Environment.NewLine;

            string key = "Show Driver Description";
            string val = null;

            // loop
            while (val != "true" & val != "false")
            {
                val = SettingManager.ReadSetting(key); // refresh value each time

                if (val == "true")
                {
                    message = message + "Description: " + releaseDesc + Environment.NewLine + Environment.NewLine;
                }
                else if (val == "false")
                {
                    break;
                }
                else
                {
                    // invalid value
                    SettingManager.SetupSetting(key);
                }
            }

            message += "Driver version: " + OnlineGPUVersion + " (you're running " + OfflineGPUVersion + ")" + Environment.NewLine +
                       "Driver released: " + theDate + " (" + releaseDate.ToShortDateString() + ")";

            DialogResult dialog = MessageBox.Show(message, "TinyNvidiaUpdateChecker", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

            if (dialog == DialogResult.Yes)
            {
                Console.WriteLine();

                bool error = false;
                driverFileName = downloadURL.Split('/').Last(); // retrives file name from url

                try {
                    message = "Where do you want to save the drivers?";

                    key = "Minimal install";
                    val = null; // reset value

                    // loop
                    while (val != "true" & val != "false")
                    {
                        val = SettingManager.ReadSetting(key); // refresh value each time
                        if (val == "true")
                        {
                            message += " (you should select a empty folder)";
                        }
                        else if (val == "false")
                        {
                            break;
                        }
                        else
                        {
                            // invalid value
                            SettingManager.SetupSetting(key);
                        }
                    }

                    DialogResult result;
                    using (FolderBrowserDialog folderDialog = new FolderBrowserDialog()) {
                        folderDialog.Description = message;

                        result = folderDialog.ShowDialog(); // show dialog and get status (will wait for input)
                        switch (result)
                        {
                        case DialogResult.OK:
                            savePath = folderDialog.SelectedPath;
                            break;

                        default:
                            Console.WriteLine("User closed dialog!");
                            return;
                        }
                    }

                    // don't download driver if it already exists
                    Console.Write("Downloading the driver . . . ");
                    if (showUI && !File.Exists(savePath + @"\" + driverFileName))
                    {
                        using (WebClient webClient = new WebClient()) {
                            var notifier = new AutoResetEvent(false);
                            var progress = new ProgressBar();

                            webClient.DownloadProgressChanged += delegate(object sender, DownloadProgressChangedEventArgs e)
                            {
                                progress.Report((double)e.ProgressPercentage / 100);

                                if (e.BytesReceived >= e.TotalBytesToReceive)
                                {
                                    notifier.Set();
                                }
                            };

                            webClient.DownloadFileAsync(new Uri(downloadURL), savePath + @"\" + driverFileName);

                            notifier.WaitOne(); // sync with the above
                            progress.Dispose(); // get rid of the progress bar
                        }
                    }
                    // show the progress bar gui
                    else if (!showUI && !File.Exists(savePath + @"\" + driverFileName))
                    {
                        DownloaderForm dlForm = new DownloaderForm();

                        dlForm.Show();
                        dlForm.Focus();
                        dlForm.DownloadFile(new Uri(downloadURL), savePath + @"\" + driverFileName);
                        dlForm.Close();
                    }
                    else
                    {
                        LogManager.Log("Driver is already downloaded", LogManager.Level.INFO);
                    }
                }
                catch (Exception ex)
                {
                    error = true;
                    Console.Write("ERROR!");
                    LogManager.Log(ex.Message, LogManager.Level.ERROR);
                    Console.WriteLine();
                    Console.WriteLine(ex.StackTrace);
                    Console.WriteLine();
                }

                if (error == false)
                {
                    Console.Write("OK!");
                    Console.WriteLine();
                }

                if (debug == true)
                {
                    Console.WriteLine("savePath: " + savePath);
                }

                dialog = MessageBox.Show("Do you want view the release PDF?", "TinyNvidiaUpdateChecker", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (dialog == DialogResult.Yes)
                {
                    try {
                        Process.Start(pdfURL);
                    }
                    catch (Exception ex) {
                        Console.WriteLine(ex.StackTrace);
                    }
                }

                key = "Minimal install";
                val = null; // reset value
                // loop
                while (val != "true" & val != "false")
                {
                    val = SettingManager.ReadSetting(key); // refresh value each time
                    if (val == "true")
                    {
                        MakeInstaller();
                    }
                    else if (val == "false")
                    {
                        break;
                    }
                    else
                    {
                        // invalid value
                        SettingManager.SetupSetting(key);
                    }
                }

                dialog = MessageBox.Show("Do you wish to run the driver installer?", "TinyNvidiaUpdateChecker", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (dialog == DialogResult.Yes)
                {
                    try {
                        if (val == "true")
                        {
                            // extracted
                            Process.Start(savePath + @"\setup.exe");
                        }
                        else
                        {
                            Process.Start(savePath + @"\" + driverFileName);
                        }
                    } catch (Exception ex) {
                        Console.WriteLine(ex.StackTrace);
                    }
                }
            }
        }
        /// <summary>
        /// Check if dependencies are all OK
        /// </summary>
        private static void CheckDependencies()
        {
            // Check internet connection
            Console.Write("Searching for a network connection . . . ");
            switch (NetworkInterface.GetIsNetworkAvailable())
            {
            case true:
                Console.Write("OK!");
                Console.WriteLine();
                break;

            default:
                Console.Write("ERROR!");
                Console.WriteLine();
                Console.WriteLine("No network connection was found, the application will now determinate!");
                if (showUI == true)
                {
                    Console.ReadKey();
                }
                Environment.Exit(2);
                break;
            }

            if (!File.Exists("HtmlAgilityPack.dll"))
            {
                Console.WriteLine();
                Console.Write("Attempting to download HtmlAgilityPack.dll . . . ");

                try {
                    using (WebClient webClient = new WebClient()) {
                        webClient.DownloadFile("https://github.com/ElPumpo/TinyNvidiaUpdateChecker/releases/download/v" + offlineVer + "/HtmlAgilityPack.dll", "HtmlAgilityPack.dll");
                    }
                    Console.Write("OK!");
                    Console.WriteLine();
                } catch (Exception ex) {
                    Console.Write("ERROR!");
                    Console.WriteLine();
                    Console.WriteLine(ex.StackTrace);
                    Console.WriteLine();
                }
            }

            string val      = null;
            string key      = "Minimal install";
            bool   checkLib = false;

            // loop
            while (val != "true" & val != "false")
            {
                val = SettingManager.ReadSetting(key); // refresh value each time
                if (val == "true")
                {
                    checkLib = true;
                }
                else if (val == "false")
                {
                    break;
                }
                else
                {
                    // invalid value
                    SettingManager.SetupSetting(key);
                }
            }
            if (checkLib)
            {
                if (LibaryHandler.EvaluateLibary() == null)
                {
                    Console.WriteLine("Doesn't seem like either WinRAR or 7-Zip is installed!");
                    DialogResult dialogUpdates = MessageBox.Show("Do you want to disable the minimal install feature and use the traditional way?", "TinyNvidiaUpdateChecker", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                    if (dialogUpdates == DialogResult.Yes)
                    {
                        SettingManager.SetSetting(key, "false");
                    }
                    else
                    {
                        Console.WriteLine("The application will determinate itself");
                        if (showUI == true)
                        {
                            Console.ReadKey();
                        }
                        Environment.Exit(2);
                    }
                }
            }


            Console.WriteLine();
        }
        /// <summary>
        /// A lot of things going on inside: gets current gpu driver, fetches latest gpu driver from NVIDIA server and fetches download link for latest drivers.
        /// </summary>
        private static void GpuInfo()
        {
            Console.Write("Retrieving GPU information . . . ");
            int    error      = 0;
            string processURL = null;
            string confirmURL = null;
            string gpuURL     = null;
            string gpuName    = null;

            // query local driver version
            try {
                while (string.IsNullOrEmpty(gpuName))
                {
                    gpuName = SettingManager.ReadSetting("GPU Name");
                    if (string.IsNullOrEmpty(gpuName))
                    {
                        SettingManager.SetupSetting("GPU Name");
                    }
                }

                ManagementObjectSearcher objectSearcher = new ManagementObjectSearcher("SELECT * FROM Win32_VideoController");

                // TODO: this is not the optimal code
                foreach (ManagementObject obj in objectSearcher.Get())
                {
                    if (obj["Description"].ToString() == gpuName)
                    {
                        OfflineGPUVersion = obj["DriverVersion"].ToString().Replace(".", string.Empty).Substring(5);
                        OfflineGPUVersion = OfflineGPUVersion.Substring(0, 3) + "." + OfflineGPUVersion.Substring(3); // add dot
                        break;
                    }
                    else
                    {
                        // gpu not found
                    }
                }
            } catch (Exception ex) {
                error++;
                OfflineGPUVersion = "000.00";
                Console.Write("ERROR!");
                LogManager.Log(ex.ToString(), LogManager.Level.ERROR);
                Console.WriteLine();
                Console.WriteLine(ex.StackTrace);
            }

            /// In order to proceed, we must input what GPU we have.
            /// Looking at the supported products on NVIDIA website for desktop and mobile GeForce series,
            /// we can see that they're sharing drivers with other GPU families, the only thing we have to do is tell the website
            /// if we're running a mobile or desktop GPU.

            int psID = 0;
            int pfID = 0;

            /// Get correct gpu drivers:
            /// you do not have to choose the exact GPU,
            /// looking at supported products, we see that the same driver package includes
            /// drivers for the majority GPU family.
            if (gpuName.Contains("M"))
            {
                // mobile | notebook
                psID = 99;  // GeForce 900M-series (M for Mobile)
                pfID = 758; // GTX 970M
            }
            else
            {
                // desktop
                psID = 98;  // GeForce 900-series
                pfID = 756; // GTX 970
            }

            // finish request
            try {
                gpuURL = "http://www.nvidia.com/Download/processDriver.aspx?psid=" + psID.ToString() + "&pfid=" + pfID.ToString() + "&rpf=1&osid=" + osID.ToString() + "&lid=" + langID.ToString() + "&ctk=0";

                WebClient    client = new WebClient();
                Stream       stream = client.OpenRead(gpuURL);
                StreamReader reader = new StreamReader(stream);
                processURL = reader.ReadToEnd();
                reader.Close();
                stream.Close();
            } catch (Exception ex) {
                if (error == 0)
                {
                    Console.Write("ERROR!");
                    Console.WriteLine();
                    error++;
                }
                Console.WriteLine(ex.StackTrace);
            }

            try
            {
                // HTMLAgilityPack
                // thanks to http://www.codeproject.com/Articles/691119/Html-Agility-Pack-Massive-information-extraction-f for a great article

                HtmlWeb htmlWeb = new HtmlWeb();
                HtmlAgilityPack.HtmlDocument htmlDocument = htmlWeb.Load(processURL);

                // get version
                HtmlNode tdVer = htmlDocument.DocumentNode.Descendants().SingleOrDefault(x => x.Id == "tdVersion");
                OnlineGPUVersion = tdVer.InnerHtml.Trim().Substring(0, 6);

                // get release date
                HtmlNode tdReleaseDate = htmlDocument.DocumentNode.Descendants().SingleOrDefault(x => x.Id == "tdReleaseDate");
                var      dates         = tdReleaseDate.InnerHtml.Trim();

                // not the best code, but does the job, might come back to cleanup in the future
                int status = 0;
                int year   = 0;
                int month  = 0;
                int day    = 0;

                foreach (var substring in dates.Split('.'))
                {
                    status++; // goes up starting from 1, being the year, followed by month then day.
                    switch (status)
                    {
                    // year
                    case 1:
                        year = Convert.ToInt32(substring);
                        break;

                    // month
                    case 2:
                        month = Convert.ToInt32(substring);
                        break;

                    // day
                    case 3:
                        day = Convert.ToInt32(substring);
                        break;

                    default:
                        LogManager.Log("The status: '" + status + "' is not a recognized status!", LogManager.Level.ERROR);
                        break;
                    }
                }

                releaseDate = new DateTime(year, month, day); // follows the ISO 8601 standard

                IEnumerable <HtmlNode> links = htmlDocument.DocumentNode.Descendants("a").Where(x => x.Attributes.Contains("href"));
                foreach (var link in links)
                {
                    // get driver URL
                    if (link.Attributes["href"].Value.Contains("/content/DriverDownload-March2009/"))
                    {
                        confirmURL = "http://www.nvidia.com" + link.Attributes["href"].Value.Trim();
                    }

                    // get release notes URL
                    if (link.Attributes["href"].Value.Contains("release-notes.pdf"))
                    {
                        pdfURL = link.Attributes["href"].Value.Trim();
                    }
                }

                if (pdfURL == null)
                {
                    if (psID == 98)   // if desktop
                    {
                        pdfURL = "http://us.download.nvidia.com/Windows/" + OnlineGPUVersion + "/" + OnlineGPUVersion + "-win10-win8-win7-desktop-release-notes.pdf";
                    }
                    else
                    {
                        pdfURL = "http://us.download.nvidia.com/Windows/" + OnlineGPUVersion + "/" + OnlineGPUVersion + "-win10-win8-win7-notebook-release-notes.pdf";
                    }
                    LogManager.Log("No release notes found, but a link to the notes has been crafted by following the template Nvidia uses.", LogManager.Level.INFO);
                }

                // get driver desc
                releaseDesc = htmlDocument.DocumentNode.SelectSingleNode("//div[@id='tab1_content']").InnerHtml.Trim();
                releaseDesc = HtmlToText.ConvertHtml(releaseDesc + ".", gpuName.Contains("M"));

                // Remove not needed information
                if (psID == 98)  // desktop
                {
                    releaseDesc = releaseDesc.Substring(297, releaseDesc.Length - 297).Trim();
                }
                else     // mobile
                {
                    releaseDesc = releaseDesc.Substring(878, releaseDesc.Length - 878).Trim();
                }


                // get download link
                htmlDocument = htmlWeb.Load(confirmURL);
                links        = htmlDocument.DocumentNode.Descendants("a").Where(x => x.Attributes.Contains("href"));
                foreach (var link in links)
                {
                    if (link.Attributes["href"].Value.Contains("download.nvidia"))
                    {
                        downloadURL = link.Attributes["href"].Value.Trim();
                        break; // don't need to keep search after we've found what we searched for
                    }
                }
            } catch (Exception ex) {
                OnlineGPUVersion = "000.00";
                LogManager.Log(ex.Message, LogManager.Level.ERROR);
                if (error == 0)
                {
                    Console.Write("ERROR!");
                    Console.WriteLine();
                    error++;
                }
                Console.WriteLine(ex.StackTrace);
            }

            if (error == 0)
            {
                Console.Write("OK!");
                Console.WriteLine();
            }

            if (debug == true)
            {
                Console.WriteLine("gpuURL:      " + gpuURL);
                Console.WriteLine("processURL:  " + processURL);
                Console.WriteLine("confirmURL:  " + confirmURL);
                Console.WriteLine("downloadURL: " + downloadURL);
                Console.WriteLine("pdfURL:      " + pdfURL);
                Console.WriteLine("releaseDate: " + releaseDate.ToShortDateString());
                Console.WriteLine("OfflineGPUVersion: " + OfflineGPUVersion);
                Console.WriteLine("OnlineGPUVersion:  " + OnlineGPUVersion);
            }
        }
        private static void Main(string[] args)
        {
            string message = "TinyNvidiaUpdateChecker v" + offlineVer;

            LogManager.Log(message, LogManager.Level.INFO);
            Console.Title = message;

            CheckArgs(args);

            RunIntro(); // will run intro if no args needs to output stuff

            if (showUI == true)
            {
                AllocConsole();
            }

            ConfigInit();

            CheckDependencies();

            CheckWinVer();

            GetLanguage();

            string val = null;
            string key = "Check for Updates";

            while (val != "true" & val != "false")
            {
                val = SettingManager.ReadSetting(key); // refresh value each time

                if (val == "true")
                {
                    SearchForUpdates();
                    break;
                }
                else if (val == "false")
                {
                    break;
                }
                else
                {
                    // invalid value
                    SettingManager.SetupSetting(key);
                }
            }

            GpuInfo();

            bool hasSelected = false;
            int  iOffline    = 0;

            try {
                iOffline = Convert.ToInt32(OfflineGPUVersion.Replace(".", string.Empty));
            } catch (Exception ex) {
                OfflineGPUVersion = "Unknown";
                Console.WriteLine(ex);
            }

            int iOnline = Convert.ToInt32(OnlineGPUVersion.Replace(".", string.Empty));

            if (iOnline == iOffline)
            {
                Console.WriteLine("Your GPU drivers are up-to-date!");
            }
            else
            {
                if (iOffline > iOnline)
                {
                    Console.WriteLine("Your current GPU driver is newer than remote!");
                }
                if (iOnline < iOffline)
                {
                    Console.WriteLine("Your GPU drivers are up-to-date!");
                }
                else
                {
                    Console.WriteLine("There are new drivers available to download!");
                    hasSelected = true;
                    DownloadDriver();
                }
            }

            if (hasSelected == false)
            {
                if (forceDL == true)
                {
                    DownloadDriver();
                }
            }

            Console.WriteLine();
            Console.WriteLine("Job done! Press any key to exit.");
            if (showUI == true)
            {
                Console.ReadKey();
            }
            LogManager.Log("BYE!", LogManager.Level.INFO);
            Environment.Exit(0);
        }