//using Ghostscript.NET;
//using Ghostscript.NET.Processor;

using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Drawing.Printing;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using FastReport;
using FastReport.Data;
using FastReport.Export.Pdf;
using FastReport.Utils;
using InABox.Clients;
using InABox.Core;
using InABox.Core.Reports;
using InABox.Scripting;
using InABox.Wpf.Reports.CustomObjects;
using ScriptEditor = InABox.DynamicGrid.ScriptEditorWindow;
using XmlDocument = System.Xml.XmlDocument;

namespace InABox.Wpf.Reports
{
    public enum ReportExportType
    {
        PDF,
        HTML,
        RTF,
        Excel,
        Text,
        Image
    }

    public delegate void ReportExportDefinitionClicked();

    public class ReportExportDefinition
    {
        public ReportExportDefinition(string caption, Bitmap image, ReportExportType type, Action<DataModel, byte[]> action)
        {
            Caption = caption;
            Image = image;
            Type = type;
            Action = action;
        }

        public ReportExportDefinition(string caption, ContentControl control, ReportExportType type, Action<DataModel, byte[]> action)
        {
            Caption = caption;
            Type = type;
            Action = action;
            Control = control;
        }

        public event ReportExportDefinitionClicked OnReportDefinitionClicked;

        public string Caption { get; }

        public Bitmap Image { get; }

        public ContentControl Control { get; }

        public ReportExportType Type { get; }

        public Action<DataModel, byte[]> Action { get; }
    }

    [LibraryInitializer]
    public static class ReportUtils
    {
        public static List<ReportExportDefinition> ExportDefinitions { get; } = new();

        public static void RegisterClasses()
        {
            CoreUtils.RegisterClasses(typeof(ReportTemplate).Assembly, typeof(ReportUtils).Assembly);
            foreach (string printer in PrinterSettings.InstalledPrinters)
                ReportPrinters.Register(printer);

            RegisteredObjects.Add(typeof(MultiImageObject), "ReportPage",Wpf.Resources.multi_image, "Multi-Image");
            RegisteredObjects.Add(typeof(MultiSignatureObject), "ReportPage",Wpf.Resources.signature, "Multi-Signature");
        }

        public static void PreviewReport(ReportTemplate template, DataModel data, bool printandclose = false, bool allowdesigner = false)
        {
            if (template.IsRDL)
            {
                MessageBox.Show("RDL Reports are no longer supported!");
            }
            else
            {
                PreviewWindow window = new(template, data)
                {
                    AllowDesign = allowdesigner,
                    Title = string.Format("Report Preview - {0}", template.Name),
                    Height = 800,
                    Width = 1200,
                    WindowState = WindowState.Maximized,
                };
                window.Show();
            }

        }

        public static Report SetupReport(ReportTemplate? template, DataModel data, bool repopulate)
        {
            var templaterdl = template != null ? string.IsNullOrWhiteSpace(template.RDL) ? "" : template.RDL : "";
            var tables = new List<string>();
            if (!string.IsNullOrWhiteSpace(templaterdl))
            {
                var xml = new XmlDocument();
                xml.LoadString(templaterdl);
                var datasources = xml.GetElementsByTagName("TableDataSource");
                for (var i = 0; i < datasources.Count; i++)
                {
                    var datasource = datasources[i];
                    tables.Add(datasource.Attributes.GetNamedItem("Name").Value);
                }
            }
            else
            {
                foreach(var table in data.DefaultTables)
                {
                    tables.Add(table.TableName);
                }
            }

            var report = new Report();
            report.LoadFromString(templaterdl);
            report.FileName = template?.Name ?? "";

            foreach(var tableName in data.TableNames)
            {
                var modelTable = data.GetDataModelTable(tableName);
                var dataSource = report.GetDataSource(tableName);
                if (dataSource != null && modelTable.Type is not null)
                {
                    var columnNames = CoreUtils.GetColumnNames(modelTable.Type, x => true);
                    foreach (var column in dataSource.Columns)
                    {
                        if(column is FastReport.Data.Column col && !col.Enabled)
                        {
                            //columns.Add(col.Name.Replace('_','.'));
                            columnNames.Remove(col.Name.Replace('_', '.'));
                        }
                        /*if (column is FastReport.Data.Column col && col.DataType != null && col.DataType.IsAssignableTo(typeof(IEnumerable<byte[]>)))
                        {
                            col.BindableControl = ColumnBindableControl.Custom;
                            col.CustomBindableControl = "MultiImageObject";
                        }*/
                    }
                    var columns = Columns.Create(modelTable.Type);
                    foreach(var column in columnNames)
                    {
                        columns.Add(column);
                    }
                    modelTable.Columns = columns;
                }
            }

            ScriptDocument? script = null;
            bool ScriptOK = false;
            if (!string.IsNullOrWhiteSpace(template?.Script))
            {
                script = new ScriptDocument(template.Script);
                if (script.Compile())
                {
                    script.SetValue("Model", data);
                    ScriptOK = script.Execute("Report", "Init");
                }
            }

            if (repopulate)
                data.LoadModel(tables);

            if (ScriptOK && script is not null)
            {
                script.SetValue("RequireTables", tables);
                script.Execute("Report", "Populate");
            }

            var ds = data.AsDataSet();
            report.RegisterData(ds);

            foreach (var tableName in data.TableNames)
            {
                var columns = data.GetColumns(tableName)?.AsDictionary();
                var dataSource = report.GetDataSource(tableName);
                if(dataSource != null)
                {
                    foreach (var column in dataSource.Columns)
                    {
                        if (column is FastReport.Data.Column col)
                        {
                            if (col.DataType != null && col.DataType.IsAssignableTo(typeof(IEnumerable<byte[]>)))
                            {
                                col.BindableControl = ColumnBindableControl.Custom;
                                col.CustomBindableControl = "MultiImageObject";
                            }
                            col.Enabled = columns is null || columns.ContainsKey(col.Name.Replace('_', '.'));
                        }
                    }
                }
            }

            if (string.IsNullOrWhiteSpace(templaterdl))
            {
                foreach (var table in data.DefaultTables)
                {
                    var dataSource = report.GetDataSource(table.TableName);
                    dataSource.Enabled = true;
                }

                foreach (Relation relation in report.Dictionary.Relations)
                    if (data.DefaultTables.Any(x => x.TableName.Equals(relation.ParentDataSource.Alias)) &&
                        data.DefaultTables.Any(x => x.TableName.Equals(relation.ChildDataSource.Alias)))
                        relation.Enabled = true;
            }


            return report;
        }

        public static void DesignReport(ReportTemplate template, DataModel data, bool populate = false, Action<ReportTemplate>? saveTemplate = null)
        {
            var isrdl = template != null && template.IsRDL;
            var templaterdl = template != null ? string.IsNullOrWhiteSpace(template.RDL) ? "" : template.RDL : "";
            if (isrdl)
                MessageBox.Show("RDL Reports are not supported!");
            else
            {
                PreviewWindow window = new(template, data)
                {
                    AllowDesign = true,
                    Title = string.Format("Report Designer - {0}", template.Name),
                    Height = 800,
                    Width = 1200,
                    WindowState = WindowState.Maximized,
                    IsPreview = false,
                    ShouldPopulate = populate,
                    SaveTemplate = saveTemplate
                };
                window.Show();
            }
                
        }

        public static byte[] ReportToPDF(ReportTemplate template, DataModel data, bool repopulate = true)
        {
            byte[] result = null;
            if (template.IsRDL)
                MessageBox.Show("RDL Reports are not supported!");
            // using (var pdf = new MemoryStream())
            // {
            //     using (var ms = ReportUtils.SetupReportToStream(template.RDL, data.AsDictionary))
            //     {
            //         using (ReportWriter reportWriter = new ReportWriter(ms))
            //         {
            //             reportWriter.ReportProcessingMode = Syncfusion.ReportWriter.ProcessingMode.Local;
            //             reportWriter.Save(pdf, WriterFormat.PDF);
            //
            //             //String filename = Path.Combine(GetPath(), "report.pdf");
            //             //reportWriter.Save(filename, WriterFormat.PDF);
            //             //PdfLoadedDocument rpt = new PdfLoadedDocument(filename);
            //
            //             PdfLoadedDocument rpt = new PdfLoadedDocument(pdf);
            //             PdfDocument doc = new PdfDocument(PdfConformanceLevel.Pdf_A1B);
            //             PdfDocument.Merge(doc, rpt);
            //             var msFinal = new MemoryStream();
            //             doc.Save(msFinal);
            //             result = msFinal.GetBuffer();
            //         }
            //     }
            //     //result = GhostScriptIt(pdf.GetBuffer());
            //     //result = pdf.GetBuffer();
            // }
            else
                using (var report = SetupReport(template, data, repopulate))
                {
                    report.Prepare();
                    var ms = new MemoryStream();
                    report.Export(new PDFExport(), ms);
                    result = ms.GetBuffer();
                }

            return result;
        }

        public static IEnumerable<ReportTemplate> LoadReports(string sectionName, DataModel model)
        {
            return new Client<ReportTemplate>().Query(
                new Filter<ReportTemplate>(x => x.DataModel).IsEqualTo(model.Name)
                    .And(x => x.Section).IsEqualTo(sectionName),
                null,
                new SortOrder<ReportTemplate>(x => x.Name)).Rows.Select(x => x.ToObject<ReportTemplate>());
        }

        private static void PopulateMenu(ItemsControl menu, string sectionName, DataModel model, bool allowdesign, bool populate = false)
        {
            var reports = new Client<ReportTemplate>().Query(
                new Filter<ReportTemplate>(x => x.DataModel).IsEqualTo(model.Name)
                    .And(x => x.Section).IsEqualTo(sectionName),
                null,
                new SortOrder<ReportTemplate>(x => x.Name)
            );
            foreach (var row in reports.Rows)
            {
                var print = new MenuItem();
                print.Header = row.Get<ReportTemplate, string>(x => x.Name);
                print.Tag = row.ToObject<ReportTemplate>();
                print.Click += (sender, args) =>
                {
                    var template = (sender as MenuItem)!.Tag as ReportTemplate;
                    if (template != null)
                        PreviewReport(template, model, false, allowdesign);
                };
                menu.Items.Add(print);
            }

            if (allowdesign)
            {
                if (reports.Rows.Any())
                    menu.Items.Add(new Separator());
                var manage = new MenuItem();
                manage.Header = "Manage Reports";
                manage.Click += (sender, args) =>
                {
                    var manager = new ReportManager()
                    {
                        DataModel = model,
                        Section = sectionName,
                        Populate = populate
                    };
                    manager.ShowDialog();
                };
                menu.Items.Add(manage);
            }
        }

        public static void PopulateMenu(MenuItem menu, string sectionName, DataModel model, bool allowdesign, bool populate = false) => 
            PopulateMenu(menu as ItemsControl, sectionName, model, allowdesign, populate);
        public static void PopulateMenu(ContextMenu menu, string sectionName, DataModel model, bool allowdesign, bool populate = false) => 
            PopulateMenu(menu as ItemsControl, sectionName, model, allowdesign, populate);

        public static void PrintMenu(FrameworkElement? element, string sectionName, DataModel model, bool allowdesign, bool populate = false)
        {
            var menu = new ContextMenu();

            PopulateMenu(menu, sectionName, model, allowdesign, populate);

            if (menu.Items.Count > 0)
            {
                menu.PlacementTarget = element;
                menu.IsOpen = true;
            }
        }

        public static void PrintMenu<TType>(FrameworkElement? element, string sectionName, DataModel<TType> model, bool allowdesign, bool populate = false)
            where TType : Entity, IRemotable, IPersistent, new()
        {
            PrintMenu(element, sectionName, model, allowdesign, populate);
        }      

        #region Old RDL Stuff (Deprecated)

        // private static ReportDefinition SetupReportDefinition(String rdl, Dictionary<System.Type, CoreTable> dataenvironment = null)
        // {
        //     ReportDefinition report = null;
        //     if (String.IsNullOrWhiteSpace(rdl))
        //         report = CreateReport();
        //     else
        //         report = DeserialiseReport(rdl);
        //
        //     if (dataenvironment != null)
        //         SetupReportData(report, dataenvironment);
        //     return report;
        // }

        // public static String SetupReport(String rdl, Dictionary<System.Type, CoreTable> dataenvironment = null)
        // {
        //     var defn = SetupReportDefinition(rdl, dataenvironment);
        //     return SerialiseReport(defn);
        // }
        //
        // public static MemoryStream SetupReportToStream(String rdl, Dictionary<System.Type, CoreTable> dataenvironment = null)
        // {
        //     var defn = SetupReportDefinition(rdl, dataenvironment);
        //     return SerialiseReportToStream(defn);
        // }

        //       public static String CleanupReport(String rdl)
        // {
        // 	ReportDefinition report = null;
        // 	if (String.IsNullOrWhiteSpace(rdl))
        // 		report = CreateReport();
        // 	else
        // 		report = DeserialiseReport(rdl);
        //
        // 	CleanupReportData(report);
        //
        // 	return SerialiseReport(report);
        //
        // }

// 		private static ReportDefinition CreateReport()
// 		{
// 			ReportDefinition rd = new ReportDefinition();
// 			rd.DataSources = new DataSources();
// 			rd.DataSets = new DataSets();
//
// 			rd.ReportSections = new ReportSections();
// 			rd.ReportSections.Add(
// 				new ReportSection()
// 				{
// 					Width = new Syncfusion.RDL.DOM.Size("7.5in"),
// 					Body = new Body()
// 					{
// 						Style = new Syncfusion.RDL.DOM.Style() { BackgroundColor = "White", Border = new Syncfusion.RDL.DOM.Border() },
// 						Height = new Syncfusion.RDL.DOM.Size("10in"),
//
// 					},
// 					Page = new Syncfusion.RDL.DOM.Page()
// 					{
// 						PageHeight = new Syncfusion.RDL.DOM.Size("11in"),
// 						PageWidth = new Syncfusion.RDL.DOM.Size("8.5in"),
// 						Style = new Syncfusion.RDL.DOM.Style() { BackgroundColor = "White", Border = new Syncfusion.RDL.DOM.Border() },
// 					}
// 				}
// 			);
// 			rd.EmbeddedImages = new EmbeddedImages();
//
// 			rd.RDLType = RDLType.RDL2010;
// 			rd.CodeModules = new CodeModules();
// 			rd.CodeModules.Add(new CodeModule() { Value = "System.Drawing, Version = 2.0.0.0, Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a" });
// 			rd.CodeModules.Add(new CodeModule() { Value = "Syncfusion.Pdf.Base, Version = 13.3350.0.7, Culture = neutral, PublicKeyToken = 3d67ed1f87d44c89" });
// 			rd.CodeModules.Add(new CodeModule() { Value = "Syncfusion.Linq.Base, Version = 13.3350.0.7, Culture = neutral, PublicKeyToken = 3d67ed1f87d44c89" });
//
// 			rd.Classes = new Classes();
// 			rd.Classes.Add(new Class() { ClassName = "Syncfusion.Pdf.Barcode.PDFCode39Barcode", InstanceName = "Code39" });
// 			rd.Classes.Add(new Class() { ClassName = "Syncfusion.Pdf.Barcode.PdfQRBarcode", InstanceName = "QRCode" });
//
// 			rd.Code = @"
// Public Function Code39BarCode(Text As String) As String
//  Dim _msg as String
//  try
//    Code39.BarHeight = 100
//    Code39.Text = Text 
//    Code39.EnableCheckDigit = True
//    Code39.EncodeStartStopSymbols = True
//    Code39.ShowCheckDigit = False
//    Code39.TextDisplayLocation = 0
//    Dim _img As System.Drawing.Image = Code39.ToImage()
//    Dim ms As New System.IO.MemoryStream()
//    _img.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp)
//    Dim _bytes = ms.ToArray() 
//     Return System.Convert.ToBase64String(_bytes, 0, _bytes.Length)
//   Catch ex As Exception
//    _msg = ex.toString()
//   End Try
//    return Nothing
// End Function
//
// Public Function QRBarCode(Text As String) As String
//  Dim _msg as String
//  try
//    QRCode.Text = Text 
//    QRCode.XDimension = 4
//    Dim _img As System.Drawing.Image = QRCode.ToImage()
//    Dim ms As New System.IO.MemoryStream()
//    _img.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp)
//    Dim _bytes = ms.ToArray() 
//     Return System.Convert.ToBase64String(_bytes, 0, _bytes.Length)
//   Catch ex As Exception
//    _msg = ex.toString()
//   End Try
//    return Nothing
// End Function
//
// ";
// 			return rd;
//
// 			//MemoryStream memoryStream = new MemoryStream();
// 			//TextWriter ws2 = new StreamWriter(memoryStream);
// 			//xs2.Serialize(ws2, rd, serialize);
// 			//memoryStream.Position = 0;
// 			////To save to a file.
// 			//StringWriter ws3 = new StringWriter
// 			//TextWriter ws3 = new StreamWriter(_tempfile);
// 			//xs2.Serialize(ws3, rd, serialize);
// 			//ws2.Close();
// 			//ws3.Close();
// 			//memoryStream.Close();
//
// 		}

        private static string DataTableToXML(Type type, CoreTable table)
        {
            var doc = new XmlDocument();

            var root = doc.CreateElement(string.Empty, type.Name.ToLower() + "s", string.Empty);
            doc.AppendChild(root);

            //var properties = CoreUtils.PropertyList(type, x => true, true);
            if (table != null)
            {
                if (table.Rows.Any())
                {
                    foreach (var datarow in table.Rows)
                    {
                        var row = doc.CreateElement(string.Empty, type.Name.ToLower(), string.Empty);
                        foreach (var column in table.Columns)
                        {
                            var field = doc.CreateElement(string.Empty, column.ColumnName.Replace('.', '_'), string.Empty);
                            var oVal = datarow[column.ColumnName];
                            var value = doc.CreateTextNode(oVal != null ? oVal.ToString() : "");
                            field.AppendChild(value);
                            row.AppendChild(field);
                        }

                        root.AppendChild(row);
                    }
                }
                else
                {
                    var row = doc.CreateElement(string.Empty, type.Name.ToLower(), string.Empty);
                    foreach (var column in table.Columns)
                    {
                        var field = doc.CreateElement(string.Empty, column.ColumnName.Replace('.', '_'), string.Empty);
                        var value = doc.CreateTextNode("");
                        field.AppendChild(value);
                        row.AppendChild(field);
                    }

                    root.AppendChild(row);
                }
            }

            var xmlString = "";
            using (var wr = new StringWriter())
            {
                doc.Save(wr);
                xmlString = wr.ToString();
            }

            return xmlString.Replace("<?xml version=\"1.0\" encoding=\"utf-16\"?>\r\n", "");
        }

        public static DataSet CreateReportDataSource(Dictionary<Type, CoreTable> dataenvironment)
        {
            var ds = new DataSet();
            foreach (var key in dataenvironment.Keys)
            {
                var table = dataenvironment[key];
                var dt = new DataTable(key.EntityName().Split('.').Last());
                foreach (var column in table.Columns)
                    dt.Columns.Add(column.ColumnName);
                foreach (var row in table.Rows)
                    dt.Rows.Add(row.Values.ToArray());
                ds.Tables.Add(dt);
            }

            return ds;
        }

        // private static void SetupReportData(ReportDefinition report, Dictionary<System.Type,CoreTable> dataenvironment)
        // {
        //
        //           report.DataSets.Clear();
        //           report.DataSources.Clear();
        //           foreach (System.Type type in dataenvironment.Keys)
        //           {
        //               String _tempfile = Path.GetTempFileName();
        //               String xml = DataTableToXML(type, dataenvironment[type]);
        //               File.WriteAllText(_tempfile, xml);
        //               // Create DataSource(s)
        //               DataSource datasource = new DataSource()
        //               {
        //                   Name = type.Name,
        //                   ConnectionProperties = new ConnectionProperties()
        //                   {
        //                       DataProvider = "XML",
        //                       IntegratedSecurity = true,
        //                       ConnectString = _tempfile
        //                   },
        //                   SecurityType = SecurityType.None,
        //               };
        //               report.DataSources.Add(datasource);
        //
        //               Syncfusion.RDL.DOM.DataSet dataset = new Syncfusion.RDL.DOM.DataSet() { Name = type.Name };
        //               dataset.Fields = new Fields();
        //
        //               CoreTable table = dataenvironment[type];
        //               foreach (var column in table.Columns)
        //               {
        //                   dataset.Fields.Add(
        //                       new Field()
        //                       {
        //                           Name = column.ColumnName.Replace('.', '_'),
        //                           DataField = column.ColumnName.Replace('.', '_'),
        //                           TypeName = column.DataType.Name
        //                       }
        //                   );
        //               }
        //
        //               //var properties = CoreUtils.PropertyList(type, x => true, true);
        //
        //               //// Create DataSet(s)
        //               //foreach (String key in properties.Keys)
        //               //{
        //               //    dataset.Fields.Add(
        //               //        new Field()
        //               //        {
        //               //            Name = key.Replace('.', '_'),
        //               //            DataField = key.Replace('.', '_'),
        //               //            TypeName = properties[key].Name
        //               //        }
        //               //    );
        //               //}
        //               dataset.Query = new Query()
        //               {
        //                   DataSourceName = type.Name,
        //                   CommandType = Syncfusion.RDL.DOM.CommandType.Text,
        //                   CommandText = String.Format("{0}s/{0}", type.Name.ToLower())
        //               };
        //               report.DataSets.Add(dataset);
        //           }
        //       }
        //
        // private static void CleanupReportData(ReportDefinition report)
        // {
        // 	foreach (var ds in report.DataSources)
        // 	{
        // 		String _tempfile = ds.ConnectionProperties.ConnectString;
        // 		if (File.Exists(_tempfile))
        // 			File.Delete(_tempfile);
        // 		ds.ConnectionProperties.ConnectString = "";
        // 	}
        // 	report.DataSources[0].ConnectionProperties.ConnectString = "";
        // }
        //
        // private static ReportDefinition DeserialiseReport(String rdl)
        // {
        //           String data = rdl;
        //           try
        //           {
        //               byte[] debase64 = Convert.FromBase64String(rdl);
        //               data = Encoding.UTF8.GetString(debase64);
        //           }
        //           catch (Exception e)
        //           {
        //               Logger.Send(LogType.Error, "", String.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
        //           }
        //           ReportDefinition report = null;
        // 	XmlSerializer xs = new XmlSerializer(typeof(ReportDefinition), "http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition");
        // 	using (StringReader stringreader = new StringReader(data)) // root.ToString()))
        // 	{
        // 		report = (ReportDefinition)xs.Deserialize(stringreader);
        // 	}
        // 	return report;
        // }
        //
        //       [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times")]
        //       private static String SerialiseReport(ReportDefinition report)
        //       {
        //           var stream = SerialiseReportToStream(report);
        //           return Encoding.UTF8.GetString(stream.ToArray());
        //
        //       }
        //
        //       [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times")]
        //       private static MemoryStream SerialiseReportToStream(ReportDefinition report)
        //       {
        //
        //           string nameSpace = "http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition";
        //
        //           if (report.RDLType == RDLType.RDL2010)
        //               nameSpace = "http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition";
        //
        //           XmlSerializerNamespaces serialize = new XmlSerializerNamespaces();
        //           serialize.Add("rd", "http://schemas.microsoft.com/SQLServer/reporting/reportdesigner");
        //           XmlSerializer xs2 = new XmlSerializer(typeof(Syncfusion.RDL.DOM.ReportDefinition), nameSpace);
        //           MemoryStream memoryStream = new MemoryStream();
        //           TextWriter ws2 = new StreamWriter(memoryStream);
        //           xs2.Serialize(ws2, report, serialize);
        //           memoryStream.Position = 0;
        //           return memoryStream;
        //           //return Encoding.UTF8.GetString(memoryStream.ToArray());
        //
        //       }

        //    private static byte[] GhostScriptIt(byte[] pdf)
        //    {
        //        String input = Path.GetTempFileName();
        //        File.WriteAllBytes(input, pdf);

        //        byte[] result = new byte[] { };

        //        GhostscriptVersionInfo gv = new GhostscriptVersionInfo(
        //            new Version(0, 0, 0),
        //            "gsdll32.dll",
        //            string.Empty,
        //            GhostscriptLicense.GPL
        //        );

        //        GhostscriptPipedOutput gsPipedOutput = new GhostscriptPipedOutput();

        //        // pipe handle format: %handle%hexvalue
        //        string outputPipeHandle = "%handle%" + int.Parse(gsPipedOutput.ClientHandle).ToString("X2");
        //        using (GhostscriptProcessor processor = new GhostscriptProcessor(gv, true))
        //        {
        //            List<string> switches = new List<string>();
        //            switches.Add("-empty");
        //            switches.Add("-dQUIET");
        //            switches.Add("-dSAFER");
        //            switches.Add("-dBATCH");
        //            switches.Add("-dNOPAUSE");
        //            switches.Add("-dNOPROMPT");
        //            switches.Add("-dCompatibilityLevel=1.4");
        //            switches.Add("-sDEVICE=pdfwrite");
        //            switches.Add("-o" + outputPipeHandle);
        //            switches.Add("-q");
        //            switches.Add("-f");
        //            switches.Add(input);

        //            try
        //            {
        //                processor.StartProcessing(switches.ToArray(), null);
        //                result = gsPipedOutput.Data;

        //            }
        //            catch (Exception ex)
        //            {
        //                Console.WriteLine(ex.Message);
        //            }
        //            finally
        //            {
        //                gsPipedOutput.Dispose();
        //                gsPipedOutput = null;
        //            }
        //        }
        //        File.Delete(input);
        //        return result;
        //    }

        #endregion
    }
}