using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;

using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Hosting;
using System.Drawing.Printing;

using PdfPrintDemo.Models;

// the PDF Print namespace
using EvoPdf.PdfPrint;

namespace PdfPrintDemo.Controllers
{

    public class Getting_StartedController : Controller
    {
        PdfPrintModel pdfPrintModel;

        private readonly IWebHostEnvironment m_hostingEnvironment;
        public Getting_StartedController(IWebHostEnvironment hostingEnvironment)
        {
            m_hostingEnvironment = hostingEnvironment;
        }

        public IActionResult Index()
        {
            if (pdfPrintModel == null)
                pdfPrintModel = new PdfPrintModel();

            if (pdfPrintModel.SelectedPrinterName == null)
            {
                if (PrinterSettings.InstalledPrinters.Count > 0)
                {
                    PrinterSettings defaultPrinterSettings = new PrinterSettings();

                    pdfPrintModel.SelectedPrinterName = defaultPrinterSettings.PrinterName;
                }
            }

            pdfPrintModel.PrinterNamesList = new List<SelectListItem>();
            for (int i = 0; i < PrinterSettings.InstalledPrinters.Count; i++)
            {
                string printerName = PrinterSettings.InstalledPrinters[i];
                pdfPrintModel.PrinterNamesList.Add(new SelectListItem(printerName, printerName,
                    pdfPrintModel.SelectedPrinterName != null && printerName == pdfPrintModel.SelectedPrinterName));
            }

            if (pdfPrintModel.SelectedPaperOrientation == null)
                pdfPrintModel.SelectedPaperOrientation = "Portrait";

            pdfPrintModel.PaperOrientationsList = new List<SelectListItem>();
            pdfPrintModel.PaperOrientationsList.Add(new SelectListItem("Portrait", "Portrait", pdfPrintModel.SelectedPaperOrientation == "Portrait"));
            pdfPrintModel.PaperOrientationsList.Add(new SelectListItem("Landscape", "Landscape", pdfPrintModel.SelectedPaperOrientation == "Landscape"));

            PrinterSettings printerSettings = new PrinterSettings();
            printerSettings.PrinterName = pdfPrintModel.SelectedPrinterName;

            pdfPrintModel.PaperSizeNamesList = new List<SelectListItem>();
            for (int i = 0; i < printerSettings.PaperSizes.Count; i++)
                pdfPrintModel.PaperSizeNamesList.Add(new SelectListItem(printerSettings.PaperSizes[i].PaperName,
                    printerSettings.PaperSizes[i].PaperName,
                    pdfPrintModel.SelectedPaperSizeName != null && printerSettings.PaperSizes[i].PaperName == pdfPrintModel.SelectedPaperSizeName));

            if (pdfPrintModel.SelectedColorSpace == null)
                pdfPrintModel.SelectedColorSpace = "Color";

            pdfPrintModel.ColorSpacesList = new List<SelectListItem>();
            pdfPrintModel.ColorSpacesList.Add(new SelectListItem("Color", "Color", pdfPrintModel.SelectedColorSpace == "Color"));
            pdfPrintModel.ColorSpacesList.Add(new SelectListItem("Gray", "Gray", pdfPrintModel.SelectedColorSpace == "Gray"));

            pdfPrintModel.SubmitAction = "printPdf";

            ViewData["PdfPrintModel"] = pdfPrintModel;

            if (ViewData["DemoFilePath"] == null)
                ViewData["DemoFilePath"] = m_hostingEnvironment.ContentRootPath + "/wwwroot" + "/DemoFiles/Input/Demo.pdf";

            return View("Index");
        }

        private void LoadViewData(IFormCollection collection)
        {
            pdfPrintModel = new PdfPrintModel();
            pdfPrintModel.SelectedPrinterName = collection["printerNameDropDownList"];
            pdfPrintModel.SelectedPaperSizeName = collection["paperSizeDropDownList"];
            pdfPrintModel.SelectedPaperOrientation = collection["paperOrientationDropDownList"];
            pdfPrintModel.SelectedPaperOrientation = collection["paperOrientationDropDownList"];
            pdfPrintModel.LeftMargin = collection["leftMarginTextBox"];
            pdfPrintModel.RightMargin = collection["rightMarginTextBox"];
            pdfPrintModel.TopMargin = collection["topMarginTextBox"];
            pdfPrintModel.BottomMargin = collection["bottomMarginTextBox"];
            pdfPrintModel.UseHardMargins = collection["useHardMarginsCheckBox"].Count > 0;
            pdfPrintModel.ShowStatusDialog = collection["showStatusDialogCheckBox"].Count > 0;
            pdfPrintModel.EnableColorPrinting = collection["enableColorPrintingCheckBox"].Count > 0;
            pdfPrintModel.SelectedColorSpace = collection["colorModesDropDownList"];
            pdfPrintModel.PrintResolution = collection["resolutionTextBox"];
            pdfPrintModel.StartPage = collection["startPageTextBox"];
            pdfPrintModel.EndPage = collection["endPageTextBox"];
            pdfPrintModel.SubmitAction = collection["submitAction"];

            ViewData["DemoFilePath"] = collection["filePathTextBox"];
        }

        [HttpPost]
        public ActionResult PrintPdf(IFormCollection collection)
        {
            LoadViewData(collection);

            if (pdfPrintModel.SubmitAction != "printPdf")
                return (ActionResult)Index();

            // the source pdf file
            string pdfFilePath = collection["filePathTextBox"][0].Trim();
            if (pdfFilePath.Equals(String.Empty))
            {
                pdfPrintModel.PdfPrintMessage = "Please choose a source PDF file";
                return (ActionResult)Index();
            }

            // start page number
            int startPageNumber = int.Parse(pdfPrintModel.StartPage.Trim());
            // end page number
            // when it is 0 the conversion will continue up to the end of document
            int endPageNumber = 0;
            if (pdfPrintModel.EndPage.Trim() != String.Empty)
                endPageNumber = int.Parse(pdfPrintModel.EndPage.Trim());

            // create the PDF printer 
            PdfPrint pdfPrint = new PdfPrint();

            // set the license key
            pdfPrint.LicenseKey = "oy08LDo/LDwsOiI8LD89Ij0+IjU1NTUsPA==";

            // set the document name
            pdfPrint.DocumentName = "PDF Silent Printing";

            // enable or disable color printing
            pdfPrint.DefaultPageSettings.Color = pdfPrintModel.EnableColorPrinting;

            // set the PDF printing color and resolution
            pdfPrint.Color = GetSelectedPrintColor(pdfPrintModel.SelectedColorSpace);
            pdfPrint.Resolution = int.Parse(pdfPrintModel.PrintResolution);

            // select the printer
            string selectedPrinterName = pdfPrintModel.SelectedPrinterName;
            if (selectedPrinterName != null)
                pdfPrint.PrinterSettings.PrinterName = selectedPrinterName;

            // set paper size
            PaperSize selectedPaperSize = GetSelectedPaperSize(pdfPrintModel.SelectedPrinterName, pdfPrintModel.SelectedPaperSizeName);
            if (selectedPaperSize != null)
                pdfPrint.DefaultPageSettings.PaperSize = selectedPaperSize;

            // set paper orientation
            pdfPrint.DefaultPageSettings.Landscape = pdfPrintModel.SelectedPaperOrientation == "Landscape";

            // set paper margins 
            pdfPrint.DefaultPageSettings.Margins = new Margins((int)(float.Parse(pdfPrintModel.LeftMargin) * 100),
                (int)(float.Parse(pdfPrintModel.RightMargin) * 100),
                (int)(float.Parse(pdfPrintModel.TopMargin) * 100),
                (int)(float.Parse(pdfPrintModel.BottomMargin) * 100));

            // enable or disable the usage of printer hard margins 
            // when calculating the space available for printing in paper
            pdfPrint.UseHardMargins = pdfPrintModel.UseHardMargins;

            // enable or disable the status dialog during printing
            pdfPrint.ShowStatusDialog = pdfPrintModel.ShowStatusDialog;

            try
            {
                // read the PDF file in a memory buffer
                byte[] sourcePdfBytes = System.IO.File.ReadAllBytes(pdfFilePath);

                // send PDF to printer
                pdfPrint.Print(sourcePdfBytes, startPageNumber, endPageNumber);
            }
            catch (Exception ex)
            {
                pdfPrintModel.PdfPrintMessage = String.Format("Error : {0})",
                    ex.Message.Replace("\\", "\\\\").Replace("'", "\\'").Replace("\"", "\\\""));
                return (ActionResult)Index();
            }

            pdfPrintModel.PdfPrintMessage = "Print Completed !";

            return (ActionResult)Index();
        }

        private PrintColor GetSelectedPrintColor(string colorSpace)
        {
            switch (colorSpace)
            {
                case "Color":
                    return PrintColor.Color;
                case "Gray":
                    return PrintColor.Gray;
                default:
                    return PrintColor.Color;
            }
        }

        private PaperSize GetSelectedPaperSize(string selectedPrinterName, string paperSizeName)
        {
            PrinterSettings printerSettings = new PrinterSettings();
            printerSettings.PrinterName = selectedPrinterName;


            for (int i = 0; i < printerSettings.PaperSizes.Count; i++)
                if (printerSettings.PaperSizes[i].PaperName == paperSizeName)
                {
                    return printerSettings.PaperSizes[i];
                }

            return null;
        }
    }
}