public MainWindow()
        {
            InitializeComponent();

            Width  = Math.Min(1700, Screen.FromControl(this).WorkingArea.Width - 600);
            Height = Math.Min(1000, Screen.FromControl(this).WorkingArea.Height - 300);

            PopulateLanguages();

            languageList.Dock = DockStyle.Fill;
            logBox.Dock       = DockStyle.Fill;
            logBox.Visible    = true;

            cancelButton.Top   = translateButton.Top;
            cancelButton.Left  = translateButton.Left;
            restartButton.Top  = translateButton.Top;
            restartButton.Left = translateButton.Left;

            cancelOneButton.Top  = translateTextButton.Top;
            cancelOneButton.Left = translateTextButton.Left;

            var settings  = new SettingsProvider();
            var inputPath = settings.Get("inputPath");

            if (string.IsNullOrEmpty(inputPath))
            {
                var args = Environment.GetCommandLineArgs();
                if (args.Length > 1)
                {
                    if (File.Exists(args[1]))
                    {
                        inputPath = args[1];
                    }
                }
            }

            if (!string.IsNullOrEmpty(inputPath))
            {
                inputBox.Text         = inputPath;
                analyzeSourceBox.Text = inputPath;
            }
        }
        private async void TranslateFile(object sender, EventArgs e)
        {
            LockControls();

            translateButton.Visible = false;
            cancelButton.Visible    = true;

            if (!compareBox.Checked)
            {
                // this is an estimate
                progressBar.Maximum = strings * languageList.CheckedIndices.Count;
            }

            var inputPath = Path.GetFullPath(inputBox.Text);
            var fromCode  = Translator.Codes[codeBox.SelectedIndex];

            var outputDir = outputBox.Text.Length > 0
                                ? Path.GetFullPath(outputBox.Text)
                                : Path.GetDirectoryName(inputPath);

            if (!Directory.Exists(outputDir))
            {
                Directory.CreateDirectory(outputDir);
            }

            string filepath = null;
            var    match    = Regex.Match(inputPath, FilePattern);

            if (match.Success)
            {
                filepath = match.Groups["file"].Value;
            }

            var translator = new Translator();

            cancellation = new CancellationTokenSource();

            foreach (var index in languageList.CheckedIndices)
            {
                var toCode = Translator.Codes[(int)index];

                var displayName = Translator.GetDisplayName(toCode);
                var cultureName = Translator.GetCultureName(toCode);
                var outputFile  = $"{filepath}.{cultureName}.resx";

                statusLabel.Text = $"Translating to {toCode} - {displayName} ({cultureName})";

                // load source resx for every target language
                // this will be translated in memory and stored for each language
                var root = XElement.Load(inputPath);

                var data = Translator.CollectData(root);

                if (compareBox.Checked && File.Exists(outputFile))
                {
                    data = Translator.FilterData(data, outputFile);
                    var span = new TimeSpan(0, 0, data.Count * (int)delayBox.Value);
                    estimationLabel.Text = $"{data.Count} {toCode} strings. Estimated completion in {span}";

                    // count per file
                    progressBar.Maximum = data.Count;
                    progressBar.Value   = 0;
                }

                try
                {
                    Log($"{NL}Translating {data.Count} strings to {toCode}{NL}", Color.Green);

                    translator.LoadHints($"{filepath}.{cultureName}-hints.xml");

                    var success = await translator.TranslateResx(
                        data, fromCode, toCode, (int)delayBox.Value, cancellation,
                        (message, color, increment) =>
                    {
                        Log(message, color);

                        if (increment)
                        {
                            progressBar.Increment(1);
                        }
                    });

                    if (cancellation.IsCancellationRequested)
                    {
                        break;
                    }

                    if (success)
                    {
                        SaveTranslations(root, data, inputPath, outputFile);
                        Log($"Saved {outputFile}{NL}", Color.Blue);
                    }
                }
                catch (HttpException exc)
                {
                    Log(exc.Message + NL, Color.Red);
                }
            }

            if (clearBox.Checked && !cancellation.IsCancellationRequested)
            {
                // we're done with this file so clear the EDIT markers
                var count = Translator.ClearMarkers(inputPath);
                if (count > 0)
                {
                    Log($"Cleared {count} EDIT markers{NL}");
                }
            }

            cancelButton.Visible  = false;
            restartButton.Visible = true;

            if (cancellation.IsCancellationRequested)
            {
                statusLabel.Text  = "Cancelled";
                progressBar.Value = progressBar.Maximum;
            }
            else
            {
                statusLabel.Text = "Done";
            }

            cancellation.Dispose();

            var settings = new SettingsProvider();

            settings.Set("inputPath", inputPath);
            settings.Save();
        }