using iTextSharp.text;
using iTextSharp.text.pdf;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Threading.Tasks;

namespace ImageToPdfHiRes
{
    public static class Program
    {
        public static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                Console.WriteLine("Usage: ImageToPdfHiRes <output.pdf> <inputFolderOrFile>");
                Console.WriteLine("Example: ImageToPdfHiRes out.pdf C:\\images");
                return;
            }
            var str = args[0].Split(',');
            string outputPdf = str[0];
            string outfilename = Path.GetFileName(outputPdf);
            string highoutputPdf = Path.GetFileNameWithoutExtension(outputPdf);
            highoutputPdf = highoutputPdf + "_High";
            highoutputPdf = Path.Combine(Path.GetDirectoryName(outputPdf), highoutputPdf) + Path.GetExtension(outputPdf);
            string inputPath = str[1];
            string[] extensions = new[] { ".jpg", ".jpeg", ".png", ".tif", ".tiff", ".bmp", ".gif", ".webp" };
            string[] imagePaths;

            if (File.Exists(inputPath))
            {
                imagePaths = new[] { inputPath };
            }
            else if (Directory.Exists(inputPath))
            {
                imagePaths = Directory.GetFiles(inputPath, "*.*", SearchOption.TopDirectoryOnly)
                                 .Where(f => extensions.Contains(Path.GetExtension(f).ToLowerInvariant()))
                                 .OrderBy(f => f) // alphabetical order, change if needed
                                 .ToArray();
            }
            else
            {
                Console.WriteLine("Input path not found: " + inputPath);
                return;
            }
            //string outputPdfPath = @"C:\Output\ImagesToPdf.pdf";

            try
            {
                Convert(imagePaths, outputPdf, 300f, "low");
                string compressedfile = GhostscriptCompressor.CompressPdf(outputPdf);
                if (!string.IsNullOrEmpty(compressedfile) && File.Exists(compressedfile))
                {
                    File.Delete(outputPdf);
                    File.Move(compressedfile, Path.GetDirectoryName(compressedfile) +"\\" +outfilename);
                }
                Convert(imagePaths, highoutputPdf, 300f, "High");
                Console.WriteLine("PDF created successfully: " + outputPdf);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error: " + ex.Message);
            }
        }
        public static void Convert(string[] imagePaths, string outputPdfPath, float targetDpi, string type)
        {
            if (imagePaths == null || imagePaths.Length == 0)
                throw new ArgumentException("No images provided.");
            using (var fs = new FileStream(outputPdfPath, FileMode.Create, FileAccess.Write, FileShare.None))
            {
                var doc = new Document(new iTextSharp.text.Rectangle(100, 100), 0, 0, 0, 0);
                var writer = PdfWriter.GetInstance(doc, fs);
                writer.SetFullCompression();
                writer.CompressionLevel = PdfStream.BEST_COMPRESSION;
                doc.Open();

                foreach (var imgPath in imagePaths)
                {
                    Console.WriteLine("Processing " + type + ": " + Path.GetFileName(imgPath));
                    using (var gdiImg = (Bitmap)System.Drawing.Image.FromFile(imgPath))
                    {
                        int pxW = gdiImg.Width;
                        int pxH = gdiImg.Height;

                        // Convert pixels to points at chosen DPI
                        float pageWpt = pxW * 72f / targetDpi;
                        float pageHpt = pxH * 72f / targetDpi;

                        // Set new page size
                        doc.SetPageSize(new iTextSharp.text.Rectangle(pageWpt, pageHpt));
                        doc.NewPage();

                        var pdfImg = iTextSharp.text.Image.GetInstance(imgPath);

                        // Instead of ScaleAbsolute, use ScaleToFit
                        pdfImg.ScaleToFit(pageWpt, pageHpt);

                        // Position at bottom-left
                        float x = (pageWpt - pdfImg.ScaledWidth) / 2;   // center horizontally
                        float y = (pageHpt - pdfImg.ScaledHeight) / 2; // center vertically
                        pdfImg.SetAbsolutePosition(x, y);

                        pdfImg.SetDpi((int)targetDpi, (int)targetDpi);
                        if (type == "low")
                        {
                            pdfImg.CompressionLevel = PdfStream.DEFAULT_COMPRESSION;
                        }
                        else
                        {
                            pdfImg.CompressionLevel = PdfStream.NO_COMPRESSION;
                        }
                        doc.Add(pdfImg);
                    }
                }

                doc.Close();
            }

            //using (var fs = new FileStream(outputPdfPath, FileMode.Create, FileAccess.Write, FileShare.None))
            //{
            //    // Temp doc; page size will be changed per image
            //    var doc = new Document(new iTextSharp.text.Rectangle(100, 100), 0, 0, 0, 0);
            //    var writer = PdfWriter.GetInstance(doc, fs);
            //    writer.SetFullCompression();
            //    writer.CompressionLevel = PdfStream.BEST_COMPRESSION;
            //    doc.Open();

            //    foreach (var imgPath in imagePaths)
            //    {
            //        Console.WriteLine("Processing: " + Path.GetFileName(imgPath));
            //        using (var gdiImg = (Bitmap)System.Drawing.Image.FromFile(imgPath))
            //        {
            //            int pxW = gdiImg.Width;
            //            int pxH = gdiImg.Height;

            //            float pageWpt = pxW * 72f / targetDpi;
            //            float pageHpt = pxH * 72f / targetDpi;

            //            // Set page size for this image
            //            doc.SetPageSize(new iTextSharp.text.Rectangle(pageWpt, pageHpt));
            //            doc.NewPage();

            //            var pdfImg = iTextSharp.text.Image.GetInstance(imgPath);
            //            pdfImg.ScaleAbsolute(pageWpt, pageHpt);
            //            pdfImg.SetAbsolutePosition(0, 0);
            //            pdfImg.SetDpi((int)targetDpi, (int)targetDpi);
            //            pdfImg.CompressionLevel = PdfStream.BEST_COMPRESSION;


            //            doc.Add(pdfImg);
            //        }
            //    }

            //    doc.Close();
            //}
        }       
    }

}
