using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Text;
using System.Windows.Forms;
using Baza_Reklam.raportyTableAdapters;
using Microsoft.Reporting.WinForms;
using System.Drawing.Printing;
using System.Drawing.Imaging;
using System.IO;
using System.Reflection;
using Baza_Reklam.Classes.Helpers;
using Baza_Reklam.Classes.Interfaces;
using Baza_Reklam.Classes.Model;
using Baza_Reklam.Classes.Repositories;

namespace Baza_Reklam
{
    public partial class OrderViewer : Form
    {
        private int reklamaId;
        DataSet ds;

        public OrderViewer(int idReklamy)
        {
            InitializeComponent();
            reklamaId = idReklamy;
                     
            ds = new DataSet();

            zamowienieTableAdapter.Connection.ConnectionString = ConnString.getConnString().Value;

            Stream s = Assembly.GetExecutingAssembly().GetManifestResourceStream("Baza_Reklam.Raporty.zamowienie.xml");
            ds.ReadXml(s);
            reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("tlumaczenia", ds.Tables[0]));
            reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("zamowienie", zamowienieTableAdapter.GetDataByReklamaId(reklamaId)));

            SqlCommand cm = new SqlCommand();
            cm.Connection = new SqlConnection();
            cm.CommandText = 
                " declare @test varchar(800); " +
                " set @test = ''; " +
                " declare @nr_wyd int; " +
                " DECLARE kur2 CURSOR FOR SELECT [Nr Wydania] FROM [UKAŻE SIĘ W NR] WHERE (ReklamaId = @param) order by [Nr Wydania];" +
                " OPEN kur2; " +
                " FETCH NEXT from kur2 into @nr_wyd; " +
                " while @@fetch_status=0 " +
                "  begin " +
                "   set @test = @test + ', ' + CAST(@nr_wyd AS varchar); " +
                "   fetch next from kur2 into @nr_wyd; " +
                "  end " +
                " CLOSE kur2; " +
                " DEALLOCATE kur2; " +
                " select @test; ";

            cm.Parameters.AddWithValue("@param", reklamaId);
            cm.Connection.ConnectionString = ConnString.getConnString().Value;

            cm.Connection.Open();
            string emisje = (string)cm.ExecuteScalar();
            cm.Connection.Close();

            raporty r = new raporty();

            raporty.emisjeRow row = r.emisje.NewemisjeRow();
            row.ID = emisje;
            r.emisje.AddemisjeRow(row);

            reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("raporty_emisje", r.emisje)); 
                       
            jezykComboBox.SelectedIndex = 0;
        }

        public OrderViewer(int idZamowienia, int a)
        {
            InitializeComponent();
            reklamaId = idZamowienia;

            ds = new DataSet();

            zamowienie2TableAdapter.Connection.ConnectionString = ConnString.getConnString().Value;

            reportViewer1.LocalReport.ReportEmbeddedResource = "Baza_Reklam.Raporty.zamowienie2.rdlc";

            Stream s = Assembly.GetExecutingAssembly().GetManifestResourceStream("Baza_Reklam.Raporty.zamowienie.xml");
            ds.ReadXml(s);
            reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("tlumaczenia", ds.Tables[0]));
            
            DataTable dt = GetOrder(idZamowienia);
            reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("zamowienie2", dt));

            DataTable dtSubscription = GetOrderSubscription(idZamowienia);
            reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("zamowienieSubscription", dtSubscription));

            TitleRepository repository = new TitleRepository(ConnString.getConnString().Value);
            List<Title> _titles = repository.FindAllActive();

            bool bIsReklama = dt.Rows.Count > 0 && !dt.Rows[0].IsNull("ID REKLAMY");
            bool bIsSubscription = dtSubscription.Rows.Count > 0;

            int invoiceProvider = 1;

            if (dt.Rows.Count > 0)
            {
                Title title = _titles.Find(delegate(Title t) { return t.ShortName == dt.Rows[0]["TYTUŁ"].ToString(); });
                if (title != null)
                    invoiceProvider = title.InvoiceProvider;
            }

            List<ReportParameter> paramList = new List<ReportParameter>();
            paramList.Add(new ReportParameter("jezyk", "PL", true));
            paramList.Add(new ReportParameter("reklamaId", reklamaId.ToString(), true));

            paramList.Add(new ReportParameter("isReklama", bIsReklama.ToString(), false));
            paramList.Add(new ReportParameter("isSubscription", bIsSubscription.ToString(), false));

            reportViewer1.LocalReport.SetParameters(paramList);

            reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("Baza_Reklam_InvoiceProvider", 
                                                                           InvoiceProviderFactory.GetInvoiceProvidersById(invoiceProvider)));

            jezykComboBox.SelectedIndex = 0;
        }

        //TODO: Helper method to get the Order details...
        private static DataTable GetOrder(int orderId)
        {
            SqlConnection conn = null;
            SqlCommand cmd = null;
            DataTable dt = new DataTable();
            const string query = "sp_GetOrderDetails";
            try
            {
                conn = new SqlConnection(ConnString.getConnString().Value);
                conn.Open();
                cmd = new SqlCommand(query, conn);
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.AddWithValue("@orderId", orderId);

                SqlDataAdapter da = new SqlDataAdapter(cmd);
                da.Fill(dt);
            }
            finally
            {
                if (cmd != null) cmd.Dispose();
                if (conn != null) conn.Close();
            }
            return dt;
        }

        private DataTable GetOrderSubscription(int orderId)
        {
            SqlConnection conn = null;
            SqlCommand cmd = null;
            DataTable dt = new DataTable();
            const string query = "sp_GetOrderSubscription";
            try
            {
                conn = new SqlConnection(ConnString.getConnString().Value);
                conn.Open();
                cmd = new SqlCommand(query, conn);
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.AddWithValue("@orderId", orderId);

                SqlDataAdapter da = new SqlDataAdapter(cmd);
                da.Fill(dt);
            }
            finally
            {
                if (cmd != null) cmd.Dispose();
                if (conn != null) conn.Close();
            }
            return dt;
        }

        private void OrderViewer_Load(object sender, EventArgs e)
        {
            reportViewer1.RefreshReport();
        }

        private void zapiszButton_Click(object sender, EventArgs e)
        {
            Cursor = Cursors.WaitCursor;

            List<ReportParameter> paramList = new List<ReportParameter>();
            paramList.Add(new ReportParameter("jezyk", jezykComboBox.SelectedItem.ToString(), true));
            reportViewer1.LocalReport.SetParameters(paramList);
            reportViewer1.RefreshReport();

            Cursor = Cursors.Default;
        }

        // drukowanie
        private int m_currentPageIndex;
        private IList<Stream> m_streams;

        private Stream CreateStream(string name,
          string fileNameExtension, Encoding encoding,
          string mimeType, bool willSeek)
        {
            Stream stream = new FileStream(name +
               "." + fileNameExtension, FileMode.Create);
            m_streams.Add(stream);
            return stream;
        }

        private void Export(LocalReport report)
        {
            string deviceInfo =
              "<DeviceInfo>" +
              "  <OutputFormat>EMF</OutputFormat>" +
              "  <PageWidth>21cm</PageWidth>" +
              "  <PageHeight>29.7cm</PageHeight>" +
              "  <MarginTop>1cm</MarginTop>" +
              "  <MarginLeft>1.4cm</MarginLeft>" +
              "  <MarginRight>1.4cm</MarginRight>" +
              "  <MarginBottom>0cm</MarginBottom>" +
              "</DeviceInfo>";
            Warning[] warnings;
            m_streams = new List<Stream>();
            report.Render("Image", deviceInfo, CreateStream,
               out warnings);
            foreach (Stream stream in m_streams)
                stream.Position = 0;
        }

        private void PrintPage(object sender, PrintPageEventArgs ev)
        {
            Metafile pageImage = new
               Metafile(m_streams[m_currentPageIndex]);
            ev.Graphics.DrawImage(pageImage, ev.PageBounds);            
            m_currentPageIndex++;
            ev.HasMorePages = (m_currentPageIndex < m_streams.Count);
        }

        private void Print(PrinterSettings printerSettings)
        {
            if (m_streams == null || m_streams.Count == 0)
                return;

            PrintDocument printDoc = new PrintDocument();
            printDoc.PrinterSettings = printerSettings;
            printDoc.PrinterSettings.Duplex = Duplex.Vertical;
            printDoc.PrintPage += PrintPage;
            printDoc.Print();
        }

        private void Run()
        {
             PrintDialog printDialog = new PrintDialog();
             if (printDialog.ShowDialog() == DialogResult.OK)
             {
                 Export(reportViewer1.LocalReport);
                 m_currentPageIndex = 0;
                 Print(printDialog.PrinterSettings);
             }
        }

        public void Dispose()
        {
            if (m_streams != null)
            {
                foreach (Stream stream in m_streams)
                    stream.Close();
                m_streams = null;
            }
            Dispose();
        }

        public void HandlePrint(object sender, CancelEventArgs e)
        {
            Run();
            e.Cancel = true;
        }
    }
}