using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Windows.Media.Imaging;
using Telerik.Windows.Documents.Fixed.FormatProviders.Pdf;
using Telerik.Windows.Documents.Fixed.Model;
using Telerik.Windows.Documents.Fixed.Model.Common;
using Telerik.Windows.Documents.Fixed.Model.Objects;
using Telerik.Windows.Documents.Fixed.Model.Resources;

namespace PdfProcessing_SampleApp
{
    internal class Program
    {
        private static readonly string outputDirectoryName = "Images";
        private static int counter = 0;

        private static void Main(string[] args)
        {
            RadFixedDocument document = ImportPdf("SampleDocument.pdf");
            Directory.CreateDirectory(outputDirectoryName);

            foreach (RadFixedPage page in document.Pages)
            {
                foreach (ContentElementBase contentElement in page.Content)
                {
                    if (contentElement is Image image)
                    {
                        ExtractImages(image);
                    }
                    else if (contentElement is Form formObject)
                    {
                        foreach (ContentElementBase contentElement2 in formObject.FormSource.Content)
                        {
                            image = contentElement2 as Image;
                            ExtractImages(image);
                        }
                    }
                }
            }

            Process.Start(outputDirectoryName);
        }

        private static RadFixedDocument ImportPdf(string path)
        {
            RadFixedDocument document;

            using (Stream input = File.OpenRead(path))
            {
                PdfFormatProvider provider = new PdfFormatProvider();
                document = provider.Import(input);
            }

            return document;
        }

        private static int ExtractImages(Image image)
        {
            EncodedImageData encodedImageData = image.ImageSource.GetEncodedImageData();
            byte[] data = encodedImageData.Data;

            bool isTransperant = image.ImageSource.GetEncodedImageData().AlphaChannel != null;
            if (encodedImageData.Filters.Contains("DCTDecode") && !isTransperant)
            {
                File.WriteAllBytes(Path.Combine(outputDirectoryName, $"fileName{++counter}.jpeg"), data);
            }
            else if (encodedImageData.Filters.Contains("FlateDecode") | isTransperant)
            {
                BitmapSource bitmapSource = image.GetBitmapSource();
                using (FileStream fileStream = new FileStream(Path.Combine(outputDirectoryName, $"fileName{++counter}.png"), FileMode.Create))
                {
                    BitmapEncoder encoder = new PngBitmapEncoder();
                    encoder.Frames.Add(BitmapFrame.Create(bitmapSource));
                    encoder.Save(fileStream);
                }
            }
            else if (encodedImageData.Filters.Contains("JPXDecode"))
            {
                File.WriteAllBytes(Path.Combine(outputDirectoryName, $"fileName{++counter}.jp2"), data);
            }

            return counter;
        }
    }
}
