using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
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.Reflection;
using System.IO;


namespace Baza_Reklam
{
    public partial class FactureViewer : Form
    {
        private InvoiceProviderTableAdapter invoiceProviderTableAdapter;
        private int idFaktury;
        private readonly int idKorekty;
        private readonly int idPoprzedniejKorekty;

        /// <summary>
        /// true - faktura, false - proforma
        /// </summary>
        bool proforma;
        DataSet ds;

        public FactureViewer(int idFakt, bool rodzaj, int old)
        {
            InitializeComponent();

            idFaktury = idFakt;

            proforma = rodzaj;

            btnRefresh.Click += btnRefresh_Old_Click;

            fakturaTableAdapter1.Connection.ConnectionString = ConnString.getConnString().Value;
            fakturA_DETAILSTableAdapter1.Connection.ConnectionString = ConnString.getConnString().Value;
            fAKTURYTableAdapter.Connection.ConnectionString = ConnString.getConnString().Value;
            proformaTableAdapter.Connection.ConnectionString = ConnString.getConnString().Value;

            ds = new DataSet();

            //zczytuje dane z pliku z tlumaczeniami
            Stream s = Assembly.GetExecutingAssembly().GetManifestResourceStream("Baza_Reklam.Raporty.faktura.xml");
            ds.ReadXml(s);

            fAKTURYTableAdapter.FillByIdFaktury(rEKLAMADataSet.FAKTURY, idFakt);

            //ustawienie parametrów, nowych datasoure dla raportu

            //ustawianie danych dla raportu
            if (proforma)
            {
                jezykComboBox.Enabled = false;
                reportViewer1.LocalReport.ReportEmbeddedResource = "Baza_Reklam.Raporty.proformaReversed.rdlc";
                reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("Faktura", proformaTableAdapter.GetDataByIdFaktury(idFakt)));
            }
            else
            {
                typComboBox.Enabled = false;
                reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("Faktura", fakturaTableAdapter1.GetDataByIdFaktury(idFakt)));
                reportViewer1.LocalReport.ReportEmbeddedResource = "Baza_Reklam.Raporty.fakturaReversed.rdlc";
            }

            reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("FakturaDetails", fakturA_DETAILSTableAdapter1.GetDataByIdFaktury(idFakt)));
            reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("tlumaczenia", ds.Tables[0]));

            List<ReportParameter> paramList = new List<ReportParameter>();

            //Produkcja ma domyślnie bez podpisu 

            if (User.Instance().IsProdukcja)
            {
                podpisCheckBox.CheckState = CheckState.Unchecked;
                paramList.Add(new ReportParameter("podpis", podpisCheckBox.Checked.ToString(), true));
                reportViewer1.LocalReport.SetParameters(paramList);
            }

            jezykComboBox.SelectedIndex = 0;
            typComboBox.SelectedIndex = 1;
        }

        private static bool IsFakturaPoznanOrKatowice(string roz, int nabywca)
        {
            return roz.ToUpper() == "KAT" || roz.ToUpper() == "POZ" || nabywca == 678 || nabywca == 18845;
        }

        public FactureViewer(int idFakt, bool r)
        {
            Init(idFakt, r, string.Empty);
        }

        /// <param name="idFakt">ID_Faktury</param>
        /// <param name="r">true = proforma</param>
        /// <param name="kodKlienta"></param>
        public FactureViewer(int idFakt, bool r, string kodKlienta)
        {
            Init(idFakt, r, kodKlienta);
        }

        public void Init(int idFakt, bool r, string kodKlienta)
        {
            invoiceProviderTableAdapter = new InvoiceProviderTableAdapter();
            invoiceProviderTableAdapter.ClearBeforeFill = true;
            invoiceProviderTableAdapter.Connection.ConnectionString = ConnString.getConnString().Value;
            
            InitializeComponent();

            btnRefresh.Click += btnRefresh_Click;

            idFaktury = idFakt;
            proforma = r;

            fakturaTableAdapter1.Connection.ConnectionString = ConnString.getConnString().Value;
            fAKTURA_DETAILS2TableAdapter.Connection.ConnectionString = ConnString.getConnString().Value;
            fAKTURYTableAdapter.Connection.ConnectionString = ConnString.getConnString().Value;
            proformaTableAdapter.Connection.ConnectionString = ConnString.getConnString().Value;

            ds = new DataSet();

            //zczytuje dane z pliku z tlumaczeniami
            Stream s = Assembly.GetExecutingAssembly().GetManifestResourceStream("Baza_Reklam.Raporty.faktura.xml");
            ds.ReadXml(s);

            fAKTURYTableAdapter.FillByIdFaktury(rEKLAMADataSet.FAKTURY, idFakt);

            //ustawienie parametrów, nowych datasoure dla raportu

            //ustawianie danych dla raportu
            typComboBox.Enabled = false;

            raporty.FakturaDataTable fakturaDataTable = fakturaTableAdapter1.GetDataByIdFaktury(idFakt);
            raporty.FakturaRow faktura = (raporty.FakturaRow)fakturaDataTable.Rows[0];
            raporty.FAKTURA_DETAILS2DataTable fakturaDetails = fAKTURA_DETAILS2TableAdapter.GetDataIdFaktury(idFakt);


            bool isPoznanKatowice = IsFakturaPoznanOrKatowice(faktura.NUMER_ROZ, faktura.ID_NABYWCY);

            if (IsFakturaPoznanOrKatowice(faktura.NUMER_ROZ, faktura.ID_NABYWCY))
                reportViewer1.LocalReport.ReportEmbeddedResource = "Baza_Reklam.Raporty.fakturaKatowicePoznan.rdlc";
            else
            {
                object sumObject = fakturaDetails.Compute("Sum(ILOSC)", string.Empty);
                int numberOfTitles = GetDistinctCount(fakturaDetails, "SYMB");
                int numberOfAds = GetDistinctCount(fakturaDetails, "ReklamaId");
/*
                if (Convert.ToInt32(sumObject) > 5 || numberOfTitles > 1 || numberOfAds > 1) //raport, gdzie specyfikacja nie miesci sie na pierwszej stronie
                    reportViewer1.LocalReport.ReportEmbeddedResource = "Baza_Reklam.Raporty.fakturaReversed2.rdlc";
                else // specyfikacja zmiesci sie na pierwszej stronie
                    reportViewer1.LocalReport.ReportEmbeddedResource = "Baza_Reklam.Raporty.fakturaReversed2_1page.rdlc";
*/
                reportViewer1.LocalReport.ReportEmbeddedResource = "Baza_Reklam.Raporty.fakturaReversed2.rdlc";
            }            

            reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("Faktura", fakturaDataTable));
            reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("FakturaDetails2", fakturaDetails));
            reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("tlumaczenia", ds.Tables[0]));


            //SJ:
            //TODO: jak z Poznaniem i Katowicami, czy pobieranie SystemKsiegowyId nie jest błędem?
            //TODO: add InvoiceProviderId column to Invoices table
            int invoiceProviderId = Convert.ToInt32(rEKLAMADataSet.FAKTURY.Rows[0]["SystemKsiegowyId"]);


            //czy tu czasem nie zwraca złych danych
            reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("Baza_Reklam_InvoiceProvider",
                                                                           InvoiceProviderFactory.GetInvoiceProvidersById(invoiceProviderId)));

            List<ReportParameter> paramList = new List<ReportParameter>();

            //Produkcja ma domyślnie bez podpisu 
            if (User.Instance().IsProdukcja)
            {
                podpisCheckBox.CheckState = CheckState.Unchecked;
            }

            paramList.Add(new ReportParameter("podpis", podpisCheckBox.Checked.ToString(), true));

            if (!isPoznanKatowice)
            {
                if (faktura.Iswaluta_kursNull())
                    paramList.Add(new ReportParameter("kursWaluty", "1", true));
                else
                    paramList.Add(new ReportParameter("kursWaluty", faktura.waluta_kurs.ToString(), true));                
            }


            if (proforma)
            {
                paramList.Add(new ReportParameter("proforma", "True", true));
                paramList.Add(new ReportParameter("kodKlienta", kodKlienta, true));
            }
            else
            {
                paramList.Add(new ReportParameter("proforma", "False", true));
                paramList.Add(new ReportParameter("kodKlienta", string.Empty, true));
            }

            if (!faktura.Issuma_zaplatNull() && faktura.suma_zaplat > 0)
                zaplaconoCheckBox.Checked = true;

            paramList.Add(new ReportParameter("zaplacono", zaplaconoCheckBox.Checked.ToString(), true));

            reportViewer1.LocalReport.SetParameters(paramList);

            jezykComboBox.SelectedIndex = 0;
            typComboBox.SelectedIndex = 1;
        }

        private int GetDistinctCount(DataTable dataTable, string column)
        {
            List<string> titles = new List<string>();

            foreach(DataRow dataRow in dataTable.Rows)
            {
                if(!titles.Contains(dataRow[column].ToString()))
                    titles.Add(dataRow[column].ToString());
            }

            return titles.Count;
        }

        /// <summary>
        /// Przy pierwszej korekcie  idKorygowanejFaktury = idPoprzedniejKorekty
        /// </summary>
        public FactureViewer(int idKorekty, int idKorygowanejFaktury, int idPoprzedniejKorekty)
        {
            invoiceProviderTableAdapter = new InvoiceProviderTableAdapter();
            invoiceProviderTableAdapter.ClearBeforeFill = true;
            invoiceProviderTableAdapter.Connection.ConnectionString = ConnString.getConnString().Value;

            InitializeComponent();

            powodKorektyComboBox.Enabled = true;
            opisTextBox.ReadOnly = !User.Instance().IsKierownik;
            opisTextBox.BackColor = User.Instance().IsKierownik ? Color.White : Color.WhiteSmoke;

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

            idFaktury = idKorygowanejFaktury;
            this.idKorekty = idKorekty;
            this.idPoprzedniejKorekty = idPoprzedniejKorekty;

            btnRefresh.Click += zapiszKorektaButton_Click;

            fakturaTableAdapter1.Connection.ConnectionString = ConnString.getConnString().Value;
            fAKTURA_DETAILS2TableAdapter.Connection.ConnectionString = ConnString.getConnString().Value;
            fAKTURYTableAdapter.Connection.ConnectionString = ConnString.getConnString().Value;
            proformaTableAdapter.Connection.ConnectionString = ConnString.getConnString().Value;

            ds = new DataSet();

            //zczytuje dane z pliku z tlumaczeniami
            Stream s = Assembly.GetExecutingAssembly().GetManifestResourceStream("Baza_Reklam.Raporty.faktura.xml");
            ds.ReadXml(s);

            fAKTURYTableAdapter.FillByIdFaktury(rEKLAMADataSet.FAKTURY, idKorekty);

            //ustawienie parametrów, nowych datasoure dla raportu

            typComboBox.Enabled = false;

            reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("Korekta", fakturaTableAdapter1.GetDataByIdFaktury(idKorekty)));

            reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("Faktura_Original", fakturaTableAdapter1.GetDataByIdFaktury(idFaktury)));

            reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("Faktura", fakturaTableAdapter1.GetDataByIdFaktury(idPoprzedniejKorekty)));

            ////piersza korekta
            //if (idPoprzedniejKorekty == idFaktury)
            //    reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("FakturaDetails2",
            //                                                                   fAKTURA_DETAILS2TableAdapter.
            //                                                                       GetDataIdFaktury(idFaktury)));
            //else
            //    reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("FakturaDetails2",
            //                                                                   fAKTURA_DETAILS2TableAdapter.GetDataIdFaktury(idPoprzedniejKorekty)));

            reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("FakturaDetails2", fAKTURA_DETAILS2TableAdapter.GetDataIdFaktury(idPoprzedniejKorekty)));



            reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("FakturaDetailsKorekty", fAKTURA_DETAILS2TableAdapter.GetDataIdFaktury(idKorekty)));
            reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("tlumaczenia", ds.Tables[0]));

            //TODO: add InvoiceProviderId column to Invoices table
            int invoiceProviderId = Convert.ToInt32(rEKLAMADataSet.FAKTURY.Rows[0]["SystemKsiegowyId"]);

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

            List<ReportParameter> paramList = new List<ReportParameter>();

            //Produkcja ma domyślnie bez podpisu 

            if (User.Instance().IsProdukcja)
            {
                podpisCheckBox.CheckState = CheckState.Unchecked;
                paramList.Add(new ReportParameter("podpis", podpisCheckBox.Checked.ToString(), true));
                reportViewer1.LocalReport.SetParameters(paramList);
            }
            jezykComboBox.SelectedIndex = 0;
            typComboBox.SelectedIndex = 1;

        }

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

            nUMERTextBox.Enabled = User.Instance().IsKierownik;
        }

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

            //zapisanie zmian w polu "opis" faktury
            fAKTURYBindingSource.EndEdit();
            fAKTURYTableAdapter.Update(rEKLAMADataSet.FAKTURY);
            fAKTURYTableAdapter.FillByIdFaktury(rEKLAMADataSet.FAKTURY, idFaktury);

            reportViewer1.Reset();
            reportViewer1.LocalReport.ReportEmbeddedResource = proforma ? "Baza_Reklam.Raporty.proformaReversed.rdlc" : "Baza_Reklam.Raporty.fakturaReversed.rdlc";

            //ustawienie parametrów, nowych datasoure dla raportu
            List<ReportParameter> paramList = new List<ReportParameter>();

            if (proforma)
            {
                //paramList.Add(new ReportParameter("typ", typComboBox.SelectedItem.ToString(), true));
                paramList.Add(new ReportParameter("podpis", podpisCheckBox.Checked.ToString(), true));
                reportViewer1.LocalReport.SetParameters(paramList);
                reportViewer1.LocalReport.DataSources.Clear();
                reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("Faktura", proformaTableAdapter.GetDataByIdFaktury(idFaktury)));
            }
            else
            {
                paramList.Add(new ReportParameter("jezyk", jezykComboBox.SelectedItem.ToString(), true));
                paramList.Add(new ReportParameter("podpis", podpisCheckBox.Checked.ToString(), true));
                reportViewer1.LocalReport.SetParameters(paramList);
                reportViewer1.LocalReport.DataSources.Clear();
                reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("Faktura", fakturaTableAdapter1.GetDataByIdFaktury(idFaktury)));   
            }

            reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("FakturaDetails", fakturA_DETAILSTableAdapter1.GetDataByIdFaktury(idFaktury)));
            reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("tlumaczenia", ds.Tables[0]));

            reportViewer1.RefreshReport();
            //MessageBox.Show(reportViewer1.LocalReport.ReportEmbeddedResource);
            Cursor = Cursors.Default;

        }

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

            //zapisanie zmian w polu "opis" faktury
            fAKTURYBindingSource.EndEdit();
            fAKTURYTableAdapter.Update(rEKLAMADataSet.FAKTURY);
            fAKTURYTableAdapter.FillByIdFaktury(rEKLAMADataSet.FAKTURY, idKorekty);

            reportViewer1.LocalReport.DataSources.Clear();

            //ustawienie parametrów, nowych datasoure dla raportu
            List<ReportParameter> paramList = new List<ReportParameter>();
            paramList.Add(new ReportParameter("jezyk", jezykComboBox.SelectedItem.ToString(), true));
            paramList.Add(new ReportParameter("podpis", podpisCheckBox.Checked.ToString(), true));

            reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("Korekta", fakturaTableAdapter1.GetDataByIdFaktury(idKorekty)));
            reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("Faktura", fakturaTableAdapter1.GetDataByIdFaktury(idPoprzedniejKorekty)));
            reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("Faktura_Original", fakturaTableAdapter1.GetDataByIdFaktury(idFaktury)));
            reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("FakturaDetails2", fAKTURA_DETAILS2TableAdapter.GetDataIdFaktury(idPoprzedniejKorekty)));

            reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("FakturaDetailsKorekty", fAKTURA_DETAILS2TableAdapter.GetDataIdFaktury(idKorekty)));

            reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("tlumaczenia", ds.Tables[0]));

            //TODO: add InvoiceProviderId column to Invoices table
            int invoiceProviderId = Convert.ToInt32(rEKLAMADataSet.FAKTURY.Rows[0]["SystemKsiegowyId"]);

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

            paramList.Add(new ReportParameter("podpis", podpisCheckBox.Checked.ToString(), true));
            reportViewer1.LocalReport.SetParameters(paramList);

            reportViewer1.RefreshReport();
            //MessageBox.Show(reportViewer1.LocalReport.ReportEmbeddedResource);
            Cursor = Cursors.Default;

        }

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

            //zapisanie zmian w polu "opis" faktury
            fAKTURYBindingSource.EndEdit();
            fAKTURYTableAdapter.Update(rEKLAMADataSet.FAKTURY);
            fAKTURYTableAdapter.FillByIdFaktury(rEKLAMADataSet.FAKTURY, idFaktury);

            //ustawienie parametrów, nowych datasoure dla raportu
            List<ReportParameter> paramList = new List<ReportParameter>();

            paramList.Add(new ReportParameter("jezyk", jezykComboBox.SelectedItem.ToString(), true));
            paramList.Add(new ReportParameter("podpis", podpisCheckBox.Checked.ToString(), true));

            if (proforma)
            {
                paramList.Add(new ReportParameter("proforma", "True", true));
            }
            else
            {
                paramList.Add(new ReportParameter("proforma", "False", true));
            }

            paramList.Add(new ReportParameter("zaplacono", zaplaconoCheckBox.Checked.ToString(), true));

            reportViewer1.LocalReport.SetParameters(paramList);



            reportViewer1.LocalReport.DataSources.Clear();
            reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("Faktura", fakturaTableAdapter1.GetDataByIdFaktury(idFaktury)));
            reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("FakturaDetails2", fAKTURA_DETAILS2TableAdapter.GetDataIdFaktury(idFaktury)));
            reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("tlumaczenia", ds.Tables[0]));

            //TODO: add InvoiceProviderId column to Invoices table
            int invoiceProviderId = Convert.ToInt32(rEKLAMADataSet.FAKTURY.Rows[0]["SystemKsiegowyId"]);

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

            reportViewer1.RefreshReport();
            //MessageBox.Show(reportViewer1.LocalReport.ReportEmbeddedResource);
            Cursor = Cursors.Default;

        }

        // drukowanie raportu lokalnego
        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)
        {
            const string deviceInfo = "<DeviceInfo>" +
                                      "  <OutputFormat>EMF</OutputFormat>" +
                                      "  <PageWidth>19cm</PageWidth>" +
                                      "  <PageHeight>25cm</PageHeight>" +
                                      "  <MarginTop>1cm</MarginTop>" +
                                      "  <MarginLeft>1cm</MarginLeft>" +
                                      "  <MarginRight>1cm</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);
                Dispose();
            }
        }

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

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

        private void powodKorektyComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            DataRowView row = (DataRowView)fAKTURYBindingSource.Current;
            row["opis"] = powodKorektyComboBox.SelectedItem.ToString();
            fAKTURYBindingSource.EndEdit();

            opisTextBox.Text = powodKorektyComboBox.SelectedItem.ToString();
        }
    }
}