// Created with MonoDevelop
//
//    QuickStep: Acquire, view and identify spectra 
//    Copyright (C) 2022 Hiperscan GmbH Dresden, Germany
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Collections.Generic;
using System.Drawing.Printing;
using Hiperscan.Unix;
using Hiperscan.ApoIdentCore.Reporting.ReportData;
using Hiperscan.ApoIdentCommon.ApoConfig;
using Hiperscan.ApoIdentCommon.ApoConfig.Enums;
using Hiperscan.AnalysisModule;
using Hiperscan.ApoIdentCommon.ApoConfig.Internationalization;

namespace Hiperscan.ApoIdentCore.Reporting.LabelPrint
{
    public partial class LabelPrinter
    {
        public static event EventHandler PrinterProcessExited = null;

        public static void Print(LabelPrinterSettings settings, ReportInfo info)
        {
            LabelPrinter label_printer = null;

            string message = String.Format(Catalog.GetString("label print is not supported for {0}"),
                                           I18n.GetReportCountryName(info.ReportCountry));

            if (info.AnalysisType != AnalysisType.Quantification)
            {

                switch (info.ReportCountry)
                {
                    case ReportCountryTypes.Germany:
                        label_printer = new LabelPrinterGermanyIM(settings);
                        break;

                    case ReportCountryTypes.Austria:
                        label_printer = new LabelPrinterAustriaIM(settings);
                        break;

                    case ReportCountryTypes.Switzerland:
                        label_printer = new LabelPrinterSwitzerlandIM(settings);
                        break;

                    case ReportCountryTypes.GreatBritain:
                        label_printer = new LabelPrinterGreatBritainIM(settings);
                        break;

                    case ReportCountryTypes.Brazil:
                        label_printer = new LabelPrinterGreatBritainIM(settings);
                        break;

                    default:
                        throw new NotSupportedException(message);
                }
            }
            else
            {
                switch (info.ReportCountry)
                {
                    case ReportCountryTypes.Germany:
                        label_printer = new LabelPrinterGermanyQM(settings);
                        break;

                    case ReportCountryTypes.Austria:
                        label_printer = new LabelPrinterAustriaQM(settings);
                        break;

                    case ReportCountryTypes.Switzerland:
                        label_printer = new LabelPrinterSwitzerlandQM(settings);
                        break;

                    case ReportCountryTypes.GreatBritain:
                        label_printer = new LabelPrinterGreatBritainQM(settings);
                        break;

                    case ReportCountryTypes.Brazil:
                        label_printer = new LabelPrinterGreatBritainQM(settings);
                        break;

                    default:
                        throw new NotSupportedException(message);
                }
            }

            label_printer.PrintLabel(new LabelInfo(info));
        }

        public static void StartLabelPrinterSettingsDialog(string printer_name, string paper_name)
        {
            System.Diagnostics.Process print_dialog_process = new System.Diagnostics.Process();

            PlatformID osversion = Environment.OSVersion.Platform;
            if (osversion == PlatformID.Win32NT ||
                osversion == PlatformID.Win32S ||
                osversion == PlatformID.Win32Windows ||
                osversion == PlatformID.WinCE)
            {
                print_dialog_process.StartInfo.FileName = "rundll32.exe";
                print_dialog_process.StartInfo.Arguments = "printui.dll,PrintUIEntry /e /n\"" + printer_name + "\"";
            }
            else
            {
                print_dialog_process.StartInfo.FileName = "system-config-printer";                   
                print_dialog_process.StartInfo.Arguments = "--configure-printer=\"" + printer_name + "\"";
            }

            string[] parameters = new string[] { printer_name, paper_name };

            print_dialog_process.StartInfo.CreateNoWindow = false;
            print_dialog_process.StartInfo.UseShellExecute = false;
            print_dialog_process.StartInfo.RedirectStandardOutput = false;
            print_dialog_process.EnableRaisingEvents = true;
            print_dialog_process.Exited += (sender, e) =>
            {
                if (LabelPrinter.PrinterProcessExited != null)
                    LabelPrinter.PrinterProcessExited(parameters, EventArgs.Empty);
            };

            print_dialog_process.Start();
        }

        public static List<string> PrinterNames
        {
            get
            {
                List<string> printers = new List<string>();
                try
                {

                    foreach (string name in System.Drawing.Printing.PrinterSettings.InstalledPrinters)
                        printers.Add(name);
                }
                catch (Exception)
                {
                    printers = new List<string>();
                }

                printers.Sort();
                printers.Insert(0, Catalog.GetString("None"));
                return printers;
            }
        }

        public static Dictionary<string, PaperSize> GetPaperSizes(string printer_name)
        {
            var printer = System.Drawing.Printing.PrinterSettings.InstalledPrinters; //work around for refresh paper names

            Dictionary<string, PaperSize> tmp = new Dictionary<string, PaperSize>();

            try
            {
                PrintDocument pd = new PrintDocument();
                pd.PrinterSettings.PrinterName = printer_name;

                foreach (PaperSize paper_size in pd.PrinterSettings.PaperSizes)
                    tmp.Add(paper_size.PaperName, paper_size);
                pd.Dispose();
            }
            catch (Exception) { }

            if (tmp.Count == 0)
            {
                PaperSize user_defined = new PaperSize();
                user_defined.PaperName = LabelPrinter.USER_DEFINED_SIZE_NAME;
                user_defined.Width = (int)(LabelPrinter.USER_DEFINED_DEFAULT_WIDTH * 100 / 25.4);
                user_defined.Height = (int)(LabelPrinter.USER_DEFINED_DEFAULT_HEIGHT * 100 / 25.4);
                tmp.Add(user_defined.PaperName, user_defined);
            }

            List<string> paper_sizes = new List<string>(tmp.Keys);
            paper_sizes.Sort();

            Dictionary<string, PaperSize> sorted = new Dictionary<string, PaperSize>();
            foreach (string paper_size in paper_sizes)
                sorted.Add(paper_size, tmp[paper_size]);

            return sorted;
        }
    }
}
