using System;
using System.Collections;
using System.Diagnostics;
using System.IO;
using System.Windows;
using System.Xml;
using DataObjects;
using Telerik.Reporting;
using Telerik.Reporting.Processing;
using Telerik.Reporting.XmlSerialization;
using DataItem = Telerik.Reporting.DataItem;
using Path = System.IO.Path;
using Report = Telerik.Reporting.Report;
using SubReport = Telerik.Reporting.SubReport;
using Table = Telerik.Reporting.Table;

namespace ReportingSample
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            MyDataSource data = new MyDataSource();
            

            GenerateReport(@"C:\Users\MICHALN\source\repos\ReportingSample\Report1.trdx",
                "PPTX", @"C:\Users\MICHALN\Desktop\output", "test.pptx", data);
 
        }

        /// <summary>
        /// the methods gets path to template, report format and output details and generates the report
        /// </summary>
        /// <param name="templatePath"></param>
        /// <param name="format"></param>
        /// <param name="outputPath"></param>
        /// <param name="outputFileName"></param>
        /// <param name="data">The object with the data</param>
        /// <param name="dataMember"> The name of the function that used as DataSource, e.g. RfDetailsData (in RfPresentationData)</param>
        protected void GenerateReport(string templatePath, string format, string outputPath, string outputFileName, MyDataSource data)
        {
            try
            {
                var reportProcessor = new ReportProcessor();
                Report report;

                using (
                    var xmlReader = XmlReader.Create(templatePath, new XmlReaderSettings { IgnoreWhitespace = true }))
                {
                    var xmlSerializer = new ReportXmlSerializer();
                    report = (Report)xmlSerializer.Deserialize(xmlReader);
                }

                
                //set data source to the report
                var dataSource = new ObjectDataSource(data, report.Name);
                report.DataSource = dataSource;

                //for each table in the report, set the data source as well
                var tables = report.Items.Find(typeof(Table), true);
                foreach (var table in tables)
                {
                    if (table is DataItem dataItem)
                    {
                        if (dataItem.DataSource != null)
                        {
                            dataSource.DataMember = ((ObjectDataSource)dataItem.DataSource).DataMember;
                            foreach (var param in ((ObjectDataSource)dataItem.DataSource).Parameters)
                            {
                                dataSource.Parameters.Add(param);
                            }

                            dataItem.DataSource = dataSource;
                        }
                    }
                }

                //set the data source to sub reports as well
                foreach (var subReport in report.Items.Find(typeof(SubReport), true))
                {
                    if (subReport is SubReport)
                    {
                        BindDataToSubReports(new ObjectDataSource(data, subReport.Name), (SubReport) subReport);
                    }
                }


                //generate the report
                var reportSource = new InstanceReportSource() { ReportDocument = report };
                RenderingResult generatedReport = reportProcessor.RenderReport(format, reportSource, new Hashtable());

                //write the report to the file system
                string filePath = Path.Combine(outputPath, outputFileName);

                if (!Directory.Exists(outputPath))
                    Directory.CreateDirectory(outputPath);

                using (FileStream fs = new FileStream(filePath, FileMode.Create))
                {
                    fs.Write(generatedReport.DocumentBytes, 0, generatedReport.DocumentBytes.Length);
                }

                //open the report
                Process.Start(filePath);
            }
            catch (Exception ex)
            {
               //logger
            }
        }


        /// <summary>
        /// Bind between data source to sub reports.
        /// </summary>
        /// <param name="objectDataSource"></param>
        /// <param name="subReport"></param>
        protected void BindDataToSubReports(ObjectDataSource objectDataSource, SubReport subReport)
        {
            string subReportPath = Path.Combine(@"C:\Users\MICHALN\source\repos\ReportingSample\", subReport.ReportSource.ToString());
            using (var xmlReader = XmlReader.Create(subReportPath, new XmlReaderSettings { IgnoreWhitespace = true }))
            {
                var xmlSerializer = new ReportXmlSerializer();
                Telerik.Reporting.Report tempReport = (Telerik.Reporting.Report)xmlSerializer.Deserialize(xmlReader);

                var tempDataSource = (ObjectDataSource)tempReport.DataSource;
                var tempParameters = tempDataSource.Parameters;
                foreach (var parameter in tempParameters)
                {
                    objectDataSource.Parameters.Add(parameter);
                }
                tempReport.DataSource = objectDataSource;

                var instanceSubReport = new InstanceReportSource() {ReportDocument = tempReport};
                subReport.ReportSource = instanceSubReport;


            }

        }
    }
}
