using Fonet;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Windows;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.XPath;
using System.Xml.Xsl;
using Telerik.Windows.Documents.Fixed;

namespace RadPdfViewerHyperlink
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        ViewModel model = new ViewModel();
        public MainWindow()
        {
            InitializeComponent();
            DataContext = model;
            Documents test = new Documents();
            test.Document = new List<DocumentAttribute>();
            
            // Assemblies available in dll folder******/

            /******** All file available in Document folder***********/
            string xsltcontent = System.IO.File.ReadAllText(@"C:\Users\Srinivasanav\source\repos\RadPdfViewerHyperlink\RadPdfViewerHyperlink\Document\DocumentsXslt.xslt");

            /******Pdf file *****/
            var doc = new DocumentAttribute();
            doc.Name = "Click Here - PdfFile Not open";
            doc.FileName = @"RadPdfViewerHyperlink\RadPdfViewerHyperlink\Document\TestPdf.pdf";
            test.Document.Add(doc);


            /******Text file *****/
            var doc1 = new DocumentAttribute();
            doc1.Name = " Click Here -  Textfile open";
            doc1.FileName = @"RadPdfViewerHyperlink\RadPdfViewerHyperlink\Document\Test.txt";
            test.Document.Add(doc1);

            string xmlContent = null;
            XmlDocument xmlDoc = null;
            XsltArgumentList args = new XsltArgumentList();
            xmlDoc = GetXmlDocument<Documents>(test);
            xmlContent = xmlDoc.OuterXml;
            byte[] result = Trasnformpdf(xsltcontent, xmlDoc, args);               
           model.Source = new MemoryStream(result);
        }
        public static XmlDocument GetXmlDocument<T>(T value) where T : class
        {
            XmlDocument document = null;
            StringBuilder xmlContent = new StringBuilder();
            using (var writer = new StringWriter(xmlContent))
            {

                XmlSerializer serializer = new XmlSerializer(typeof(T));
                serializer.Serialize(writer, value);

                string xml = xmlContent.ToString();
                document = new XmlDocument();
                document.LoadXml(xml);
            }
            return document;
        }

        public byte[] MakePdf(XmlDocument xslFoDocument)
        {
            FonetDriver driver = FonetDriver.Make();

            driver.CloseOnExit = true;         
            driver.Options = new Fonet.Render.Pdf.PdfRendererOptions()
            {
                FontType = Fonet.Render.Pdf.FontType.Embed
            };
            byte[] pdfBytes = new byte[0];

            if (xslFoDocument != null)
            {
                using (MemoryStream ms = new MemoryStream())
                {
                    driver.Render(xslFoDocument, ms);
                    pdfBytes = ms.ToArray();
                }
            }
            return pdfBytes;
        }

        private byte[] Trasnformpdf(string xsltContent, XmlDocument xmlDoc, XsltArgumentList args)
        {
            var foDocument = TransformToXmlDocument(xsltContent, xmlDoc, args);
            return MakePdf(foDocument);
        }

        private XmlDocument TransformToXmlDocument(string xsltContent, XmlDocument xmlDoc, XsltArgumentList args = null)
        {
            IXPathNavigable xslt = null;
            xslt = getxslt(xsltContent);
            XmlDocument foDocument = Transform(xslt, xmlDoc, args);
            return foDocument;
        }

        private XmlDocument Transform(IXPathNavigable xsltTemplate, XmlDocument xmlContent, XsltArgumentList xsltExtensions)
        {
            using (MemoryStream xslFoStream = new MemoryStream())
            {
                XmlWriterSettings settings = new System.Xml.XmlWriterSettings();
                settings.Encoding = new UTF8Encoding(false);
                settings.ConformanceLevel = ConformanceLevel.Auto;
                settings.Indent = true;
                using (XmlWriter xwriter = XmlWriter.Create(xslFoStream, settings))
                {
                    XslCompiledTransform transformer = new XslCompiledTransform(false);
                    XmlReader reader = new XmlTextReader(new StringReader(xmlContent.DocumentElement.OuterXml));
                    XsltSettings xslSettings = new XsltSettings();
                    xslSettings.EnableScript = true;
                    transformer.Load(xsltTemplate, xslSettings, null);
                    transformer.Transform(reader, xsltExtensions, xwriter);
                    xwriter.Flush();
                }

                string transformedXml = Encoding.UTF8.GetString(xslFoStream.ToArray());
                XmlDocument transformedXmlDoc = new XmlDocument();
                if (!String.IsNullOrEmpty(transformedXml))
                    transformedXmlDoc.LoadXml(transformedXml);

                return transformedXmlDoc;
            }
        }

        private IXPathNavigable getxslt(string xsltContent)
        {
            using (StringReader reader = new StringReader(xsltContent))
            {
                return new XPathDocument(reader);
            }
        }

        [XmlRoot("Documents")]
        public class Documents
        {
            [XmlArray("Document"), XmlArrayItem(typeof(DocumentAttribute), ElementName = "DocumentDetail")]
            public List<DocumentAttribute> Document { get; set; }
      
        }

        public class DocumentAttribute
        {
            [XmlAttribute("Name")]
            public string Name { get; set; }

            [XmlAttribute("FileName")]
            public string FileName { get; set; }
        }
    }

    public class ViewModel
    {
        public Stream Source { get; set; } 
    }
}
