// PDF-Decrypt - Windows launcher (no console window, embedded icon).
//
// Drag one or more encrypted PDF files onto PDF-Decrypt.exe.
//
// This exe is a thin launcher: its only jobs are to be the drag-and-drop
// target in Explorer, carry the app icon, and start the branded Tkinter UI
// (app\ui.py) with the bundled runtime — with no console window flashing.
// All dialogs, the progress window, and the decryption run live in ui.py.
//
// The single native dialog shown here is the bootstrap error: if the bundled
// runtime is missing there is no UI available yet to report it, so a native
// message box is used for that case only.
//
// Build:
//   csc /nologo /target:winexe /out:PDF-Decrypt.exe /win32icon:icon.ico
//       /reference:System.Windows.Forms.dll /reference:System.Drawing.dll
//       PDFDecrypt.cs

using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Text;
using System.Windows.Forms;

namespace PdfDecrypt
{
    static class Program
    {
        const string Title = "PDF-Decrypt";

        static bool De
        {
            get
            {
                return CultureInfo.CurrentUICulture.TwoLetterISOLanguageName
                    .Equals("de", StringComparison.OrdinalIgnoreCase);
            }
        }

        static string Pick(string en, string de) { return De ? de : en; }

        [STAThread]
        static void Main(string[] argv)
        {
            Application.EnableVisualStyles();

            string appDir    = AppDir();
            string pythonwExe = Path.Combine(appDir, "runtime", "pythonw.exe");
            string pythonExe  = Path.Combine(appDir, "runtime", "python.exe");
            string script     = Path.Combine(appDir, "app", "ui.py");

            string launcher = File.Exists(pythonwExe) ? pythonwExe : pythonExe;

            if (!File.Exists(launcher) || !File.Exists(script))
            {
                MessageBox.Show(
                    string.Format(Pick(
                        "The bundled Python runtime was not found.\nExpected: {0}\n\nPlease run build.bat first, or re-install the app using Install.exe.",
                        "Die mitgelieferte Python-Umgebung wurde nicht gefunden.\nErwartet: {0}\n\nBitte zuerst build.bat ausführen oder die App mit Install.exe neu installieren."),
                        launcher),
                    Title, MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            var diagnostics = new StringBuilder();

            var args = new StringBuilder();
            args.Append('"').Append(script).Append('"');
            foreach (string a in argv)
            {
                if (string.IsNullOrEmpty(a)) continue;
                string full;
                try { full = Path.GetFullPath(a); }
                catch { full = a; }
                args.Append(" \"").Append(full).Append('"');
            }

            var psi = new ProcessStartInfo();
            psi.FileName               = launcher;
            psi.Arguments              = args.ToString();
            psi.UseShellExecute        = false;
            psi.CreateNoWindow         = true;
            psi.WorkingDirectory       = appDir;
            psi.RedirectStandardError  = true;
            psi.StandardErrorEncoding  = Encoding.UTF8;
            psi.EnvironmentVariables["PYTHONUTF8"]        = "1";
            psi.EnvironmentVariables["PYTHONIOENCODING"]  = "utf-8";

            try
            {
                Process proc = Process.Start(psi);
                if (proc != null)
                {
                    proc.ErrorDataReceived += delegate(object s, DataReceivedEventArgs e)
                    {
                        if (e.Data != null && diagnostics.Length < 8000)
                            diagnostics.AppendLine(e.Data);
                    };
                    proc.BeginErrorReadLine();
                    proc.WaitForExit();

                    if (proc.ExitCode != 0 && proc.ExitCode != 2
                        && diagnostics.Length > 0)
                    {
                        MessageBox.Show(
                            string.Format(Pick(
                                "PDF-Decrypt could not start.\n\n{0}",
                                "PDF-Decrypt konnte nicht gestartet werden.\n\n{0}"),
                                Tail(diagnostics.ToString(), 1200)),
                            Title, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(
                    string.Format(Pick(
                        "Could not start PDF-Decrypt.\n\n{0}",
                        "PDF-Decrypt konnte nicht gestartet werden.\n\n{0}"),
                        ex.Message),
                    Title, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        static string Tail(string text, int chars)
        {
            text = text.Trim();
            if (text.Length <= chars) return text;
            return "\u2026" + text.Substring(text.Length - chars);
        }

        static string AppDir()
        {
            return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
        }
    }
}
