using System;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Reflection;

using Hiperscan.PdfLib;
using Hiperscan.Unix;
using Hiperscan.AnalysisModule;
using static Hiperscan.Common.I18n.CatalogLocale;

namespace Hiperscan.UpdateCertificate
{
    public class UpdateCertificateDrawer
    {
        public static void Run(string version,
                               DateTime date,
                               AnalysisType analysis_type,
                               LocaleType locale,
                               string file = null,
                               bool show_after_drawing = true)
        {
            UpdateCertificateDrawer tmp = new UpdateCertificateDrawer(version,
                                                                      date,
                                                                      analysis_type,
                                                                      locale);

            tmp.Draw(file, show_after_drawing);
        }

        public static string GetOutFilename(string version,
                                            DateTime date,
                                            AnalysisType analysis_type,
                                           LocaleType locale)
        {
            UpdateCertificateDrawer tmp = new UpdateCertificateDrawer(version,
                                                                      date,
                                                                      analysis_type,
                                                                      locale);

            return tmp.FileName;
        }



        private UpdateCertificateDrawer(string version,
                                        DateTime date,
                                        AnalysisType analysis_type,
                                        LocaleType locale)
        {
            this.AnalysisType = analysis_type;
            this.Locale = locale;

            this.Date = date;

            string[] tmp1 = version.Split(new char[] { '-' });
            string[] tmp2 = tmp1[0].Split(new char[] { '.' });
            this.Version = tmp2[0] + "." + tmp2[1] + "-" + tmp1[1] + "-" + tmp1[2];
        }

        private void Draw(string file, bool show_after_drawing)
        {
            string pdf_file = this.CreateSavePath(file);

            this.Layout = new Layout(PdfPageSizes.A4_PORTRAIT, pdf_file);
            this.Layout.PDF.SetAuthor("HiperScan GmbH");
            this.Layout.PDF.SetTitle(Catalog.GetString("Update Certificate"));
            this.Layout.PDF.SetSubject(Catalog.GetString("Update Certificate"));
            this.Layout.SimulateDrawing = false;

            int color = PdfColors.Red;
            if (this.AnalysisType == AnalysisType.Quantification)
                color = 0x00109010;

            this.Layout.LeftMargin = this.Layout.RightMargin;
            this.Layout.LowerMargin = this.Layout.UpperMargin;

            PdfRect rectange = new PdfRect(0, 0, this.Layout.InnerPageWidth, this.Layout.InnerPageHeight);
            this.Layout.AddRectangle(rectange, 2, color);

            Assembly assembly = Assembly.GetExecutingAssembly();

            double width = 0;
            double x_position = 0;
            double y_position = 0;

            Bitmap bitmap = null;

            PdfPoint pdf_point = new PdfPoint(0, 0);

            using (Stream stream = assembly.GetManifestResourceStream("logo.png"))
            {
                width = this.Layout.InnerPageWidth - 200;
                x_position = (this.Layout.InnerPageWidth - width) / 2;
                y_position = 20;

                pdf_point.X = x_position;
                pdf_point.Y = y_position;

                bitmap = (Bitmap)Image.FromStream(stream);
                this.Layout.AddBitmap(bitmap, pdf_point, PdfBitmapScales.X, width);
                bitmap.Clone();
            }

            this.Layout.SetFont(PdfFontTypes.HELVETICA_BOLD, 65, PdfColors.Black);
            this.Layout.XPosition = 0;
            this.Layout.YPosition = 150;
            this.Layout.AddParagraph(this.CertificateField, PdfTextAlignments.Center);

            this.Layout.SetFont(PdfFontTypes.HELVETICA, 20, PdfColors.Black);
            this.Layout.XPosition = 0;
            this.Layout.YPosition = 270;
            this.Layout.AddParagraph(this.SoftwareUpdateField, PdfTextAlignments.Center);




            this.Layout.SetFont(PdfFontTypes.HELVETICA, 35, color);
            this.Layout.XPosition = 0;
            this.Layout.YPosition = 350;
            this.Layout.AddParagraph(this.ModuleField, PdfTextAlignments.Center);

            this.Layout.SetFont(PdfFontTypes.HELVETICA, 35, color);
            this.Layout.XPosition = 0;
            this.Layout.YPosition = 450;
            this.Layout.AddParagraph(this.Version, PdfTextAlignments.Center);

            this.Layout.SetFont(PdfFontTypes.HELVETICA, 20, PdfColors.Black);
            this.Layout.XPosition = 0;
            this.Layout.YPosition = 550;
            this.Layout.AddParagraph(this.InstalledField, PdfTextAlignments.Center);


            width = this.Layout.InnerPageWidth - 100;
            x_position = (this.Layout.InnerPageWidth - width) / 2;
            y_position = this.Layout.InnerPageHeight - 50;


            using (Stream stream = assembly.GetManifestResourceStream("mth.png"))
            {
                pdf_point.X = x_position + 30;
                pdf_point.Y = y_position - 70;

                bitmap = (Bitmap)Image.FromStream(stream);
                this.Layout.AddBitmap(bitmap, pdf_point, PdfBitmapScales.X, 125);
                bitmap.Clone();
            }

            this.Layout.AddHorizontalLine(x_position, y_position, width, 1);

            this.Layout.SetFont(PdfFontTypes.HELVETICA, 12, PdfColors.Black);
            this.Layout.XPosition = this.Layout.InnerPageWidth - 180;
            this.Layout.YPosition = y_position - 17;
            this.Layout.AddParagraph(this.DateField);


            width = this.Layout.MeasureString(this.DateField);
            this.Layout.XPosition += width + 5;
            this.Layout.AddParagraph(this.InstallationDateField);


            width = this.Layout.InnerPageWidth - 100;
            x_position = (this.Layout.InnerPageWidth - width) / 2;
            this.Layout.XPosition = x_position;
            this.Layout.YPosition += 18;
            this.Layout.AddParagraph(this.CeoField);

            this.Layout.YPosition += 15;
            this.Layout.AddParagraph(this.BossField);

            this.Layout.Save();

            if (show_after_drawing)
                Process.OpenUri(new Uri(pdf_file));
        }

        private string CreateSavePath(string file)
        {
            if (String.IsNullOrEmpty(file) == false)
                return file;

            string dir = Path.GetTempFileName();
            dir = Path.GetFileNameWithoutExtension(dir);
            dir = Path.Combine(Path.GetTempPath(), dir);

            FileIO.RecreateDirectory(dir);
            return Path.Combine(dir, this.FileName);
        }

        private string FileName
        {
            get
            {
                return String.Format("{0}-{1}-Update-{2}.pdf",
                                        this.ModuleField,
                                        this.Version,
                                        this.CertificateField);
            }
        }

        private string CertificateField
        {
            get
            {
                switch (this.Locale)
                {
                case LocaleType.de_DE:
                    return "Zertifikat";

                case LocaleType.pt_BR:
                    return "Certificado";

                default:
                    return "Certificate";
                }
            }
        }

        private String ModuleField
        {
            get
            {
                switch (this.Locale)
                {
                case LocaleType.de_DE:
                    if (this.AnalysisType == AnalysisType.Identification)
                        return "IdentModul";
                    else
                        return "QuantifierModul";

                default:
                    if (this.AnalysisType == AnalysisType.Identification)
                        return "IdentModule";
                    else
                        return "QuantifierModule";
                }
            }
        }

        private string SoftwareUpdateField
        {
            get
            {
                switch (this.Locale)
                {
                case LocaleType.de_DE:
                    return "Das Software-Update";

                case LocaleType.pt_BR:
                    return "Atualização de software";

                default:
                    return "Software-Update";
                }
            }
        }

        private string InstalledField
        {
            get
            {
                switch (this.Locale)
                {
                case LocaleType.de_DE:
                    return "wurde erfolgreich installiert.";

                case LocaleType.pt_BR:
                    return "instalado com sucesso.";

                default:
                    return "successfully installed";
                }
            }
        }

        public string InstallationDateField
        {
            get
            {
                CultureInfo culture = new CultureInfo("en-GB");
                switch (this.Locale)
                {
                case LocaleType.de_DE:
                    culture = new CultureInfo("de-DE");
                    break;

                case LocaleType.pt_BR:
                    culture = new CultureInfo("pt-BR");
                    break;

                default:
                    break;
                }

                return this.Date.ToString("d", culture);
            }
        }

        private string CeoField
        {
            get
            {
                switch (this.Locale)
                {
                case LocaleType.de_DE:
                    return "Geschäftsleitung HiperScan GmbH";

                case LocaleType.pt_BR:
                    return "Diretor administrativo da HiperScan";

                default:
                    return "Managing Director HiperScan GmbH";
                }
            }
        }

        private string DateField
        {
            get
            {
                switch (this.Locale)
                {
                case LocaleType.de_DE:
                    return "Datum";

                case LocaleType.pt_BR:
                    return "Data";

                default:
                    return "Date";
                }
            }
        }

        private string BossField { get; set; } = "Michael Thoma";



        private LocaleType Locale { get; set; }
        private AnalysisType AnalysisType { get; set; }
        private string Version { get; set; }
        private DateTime Date { get; set; }

        private Layout Layout { get; set; }

    }
}
