using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.Globalization;
using System.Threading;
using Amib.Threading;
using LogFilePDF;
using PDFGenerator.BusinessLayer;
using PipelineLib;
using NUnit.Framework;
using System.IO;
using ContrattoSei.Utilities;
using DataAccessLayer;
using System.Collections;

namespace PDFGenerator
{
    public class PDFGenerator
    {
        private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
        private SmartThreadPool _smartThreadPool;

        private DataThread _dataThread;
        private ReportType _reportType;
        private string _tipoReport;
        private int _maxPDFGeneratorThreads;
        private List<SessionStruct> _tabelleSessione;



        public PDFGenerator(List<SessionStruct> tabelleSessione, DataThread dataThread)
        {
            string sCulture = UtilityManager.getAppSetting("CultureToUse");

            //System.Globalization.CultureInfo.CreateSpecificCulture(sCulture);
            Thread.CurrentThread.CurrentCulture = new CultureInfo(sCulture);
            Thread.CurrentThread.CurrentUICulture = new CultureInfo(sCulture);

            _dataThread = dataThread;
            _tipoReport = dataThread.TipoReport;
            _reportType = dataThread.ReportType();
            //.Find(delegate(ReportType r) { return r.Descrizione.ToUpper() == _tipoReport.ToUpper(); });
            //_dataThread = new DataSectionParameter();
            _tabelleSessione = tabelleSessione;
            //pk change remove multiThreadingPDFGeneratorThreads
            int multiT = 0;// int.Parse(UtilityManager.getAppSetting("multiThreadingPDFGeneratorThreads"));

            #region CHIAMATA MT CON GESTIONE ERRORI

            if (multiT.Equals(1))
            {
                try
                {
                    //IWorkItemResult[] workItemThread = new IWorkItemResult[4];
                    //int i = 0;


                    _maxPDFGeneratorThreads = Convert.ToInt32(UtilityManager.getAppSetting("maxPDFGeneratorThreads"));
                    STPStartInfo stpStartInfo = new STPStartInfo();
                    stpStartInfo.StartSuspended = true;
                    stpStartInfo.MaxWorkerThreads = _maxPDFGeneratorThreads;
                    stpStartInfo.MinWorkerThreads = 0;
                    stpStartInfo.IdleTimeout = 60000;

                    _smartThreadPool = new SmartThreadPool(stpStartInfo);
                    _smartThreadPool.Start();
                    StringCollection _queries = UtilityBusinessLayer.getMTQueries(_reportType, _dataThread.DataAccess);

                    WIGStartInfo wigStartInfo = new WIGStartInfo();
                    wigStartInfo.StartSuspended = true;

                    Pipeline group = new Pipeline(_smartThreadPool, int.MaxValue);


                    foreach (string query in _queries)
                    {
                        //dataThread.ArgomentiCawToErrore = argomentiCawToErrore;
                        Worker worker = new Worker(query, _dataThread, tabelleSessione);
                        group.AddTask(worker);
                    }
                    Debug.WriteLine(String.Format("PDF getting data thread: {0} started.", _dataThread.CodiceFiscale)); // PATRYK
                    group.execute();
                    Debug.WriteLine(String.Format("PDF getting data for thread: {0} ended.", _dataThread.CodiceFiscale)); // PATRYK
                    if (group.inException)
                    {
                        ScriviErroreNelDB(_dataThread.DataAccess, -292929, "Errore nel PDFGenerator group.inException INIZIO", -292929, "Gestore PDF", "Gestore PDF");
                        foreach (Task t in group.tasks)
                        {
                            if (t.taskData.innerException != null)
                            {
                                Console.WriteLine(t.taskData.name + " eccezione=" + t.taskData.innerException.Message);
                                ScriviErroreNelDB(_dataThread.DataAccess, -292929, "Errore nel PDFGenerator group.inException DENTRO: " + t.taskData.name + " __ " + getException(t.taskData.innerException), -292929, "Gestore PDF", "Gestore PDF");
                            }
                        }
                        ScriviErroreNelDB(_dataThread.DataAccess, -292929, "Errore nel PDFGenerator group.inException FINE", -292929, "Gestore PDF", "Gestore PDF");


                        //StartTng(ambiente, cawTo_Bin, argomentiCawToErrore);
                        //return 1;
                    }
                }
                catch (Exception e)
                {
                    try
                    {
                        logger.Error(String.Concat(e.Message, dataThread.CodiceFiscale));
                    }
                    catch { }

                    throw e;
                }
                finally
                {
                    _smartThreadPool.Shutdown();
                }
            }
            #endregion
        }


        public int Create()
        {
            string ambiente = ConfigurationManager.AppSettings["ambiente"];
            string cawTo_Bin = ConfigurationManager.AppSettings["cawTo_Bin"];
            string sPeriodico = ConfigurationManager.AppSettings["Periodico"];
            string includeCommercialLetter = ConfigurationManager.AppSettings["IncludeCommercialLetter"];

            DocumentPDF docPDF = null;

            //if (_dataThread.UtenteInfo != null)
            //    docPDF.setUtenteSession(_dataThread.UtenteInfo);

            try
            {

                docPDF = new DocumentPDF(_dataThread, _tipoReport);
                //PORCATA DI FABRIZIO PER POTER AVERE DENTRO DATATHREAD tutto quello che occorre
                _dataThread.DocumentPDF = docPDF;


                //Thread POOL PER LE QUERY

                docPDF.insertCliente();
                bool bCreaReport = this.createReport(docPDF);

                docPDF.inserisciLettera();
                if (includeCommercialLetter == "1")
                {
                    docPDF.inserisciCommercialeLettera();
                }

                int identificativo = docPDF.insertIntoDB();
                //string scriviLog = UtilityManager.getAppSetting("scriviLog");
                if (identificativo > 0 && !_dataThread.Periodico)
                {
                    GestoreLogPDF gLog = new GestoreLogPDF(identificativo);
                    gLog.scriviLog(LogFilePDF.EventLog.C6_GenerazioneAutomaticaDiagnosiIniziale);
                }

                // FC MOdifica per gestione parallelizzazione processi
                // Il vaore "identificativo" � gestito dalla SP di inserimento in Gestione_PDF_FTP

                int identityReport = 0;
                //gestione Rigenerazione Report
                if (sPeriodico == "1")
                {
                    // lettura IDentityReport
                    identityReport = docPDF.getIdentityReport(_dataThread.Rete, _dataThread.CodiceFiscale, _dataThread.TipoReport.Substring(0, 1));
                    // Verifca e Cancellazione Del Report
                    docPDF.deleteReportSuFileSystem(identityReport, _dataThread.NomeFileReport);
                    // Fine Gestione rigenerazione Report
                }
                bool bScrittoPDf = false;
                identificativo = UtilityBusinessLayer.setEndThread(_dataThread, identificativo, docPDF.NumPage);
                //if (identificativo == 0)
                //{
                //    identificativo = UtilityBusinessLayer.getEndThread(_dataThread, identificativo, docPDF.NumPage);

                //}


                if (identityReport < 0)
                {
                    try
                    {
                        logger.Error(identityReport.ToString());
                        List<Parametro> par = new List<Parametro>();
                        par.Add(new Parametro() { ParameterName = "FiscalCode", Value = _dataThread.CodiceFiscale });
                        par.Add(new Parametro() { ParameterName = "Rete", Value = _dataThread.Rete });
                        using (DataAccessDE de = new DataAccessDE(DBProvider.SqlServerStampeC6))
                        {
                            de.ExecuteNonQueryStoredProcedure(DBProvider.SqlServerStampeC6, ConfigurationManager.AppSettings.Get("SP_GESTIONE_PDF_REVERT_FISCAL_CODE"), par);
                        }
                    }
                    catch (Exception ex)
                    {
                        logger.Error(ex.Message);
                    }
                }
                else
                {
                    bScrittoPDf = docPDF.scriviSuFileSystem(identificativo);
                }
                if (!bScrittoPDf)
                    return -1;
                return 0;
            }
            catch (DataBaseException ex)
            {
                try
                {
                    logger.Error(String.Concat(ex.Message, _dataThread.CodiceFiscale, _dataThread.Rete));
                    logger.Error(getException(ex));
                }
                catch { }

                //StartTng(ambiente, cawTo_Bin, _dataThread.ArgomentiCawToErrore);
                Console.WriteLine(ex.Message);
                ScriviErroreNelDB(_dataThread.DataAccess, -292929, "Errore nel PDFGeneretor: " + getDataBaseException(ex), -292929, "Gestore PDF", "Gestore PDF");

                // Marian Zaki: trial
                string message = ex.Message;
                message += "Cliente: " + _dataThread.CodiceFiscale + "; PB_Rete: " + _dataThread.Rete + _dataThread.Agente;

                Exception newThrownexception = new Exception(message);
                throw newThrownexception;
            }
            catch (Exception ex)
            {
                try
                {
                    logger.Error(String.Concat(ex.Message, _dataThread.CodiceFiscale, _dataThread.Rete));
                    logger.Error(getException(ex));
                }
                catch { }

                //StartTng(ambiente, cawTo_Bin, _dataThread.ArgomentiCawToErrore);
                Console.WriteLine(ex.Message);
                ScriviErroreNelDB(_dataThread.DataAccess, -292929, "Errore nel PDFGeneretor: " + getException(ex), -292929, "Gestore PDF", "Gestore PDF");

                // Marian Zaki: trial
                string message = ex.Message;
                message += "Cliente: " + _dataThread.CodiceFiscale + "; PB_Rete: " + _dataThread.Rete + _dataThread.Agente;

                Exception newThrownexception = new Exception(message);
                throw newThrownexception;

                //Exception e = new Exception("Errore nel PDFGeneretor: " + ex.Message);
                //throw e;
            }
            finally
            {
                docPDF = null;
            }
        }

        private static string getDataBaseException(DataBaseException ecc)
        {
            const string aCapo = "#/n#";
            string ritorno = "";
            ritorno += aCapo;
            ritorno += "  Informazioni Comando SQL:" + aCapo;
            ritorno += "    sql file name: " + ecc.SqlFileName + aCapo;
            ritorno += "    connection string: " + ecc.ConnectionStringWithoutCredentials + aCapo;
            //ritorno += "    command text: " + ecc.CommandText + aCapo;
            //controllo se ci sono i parametri
            if (ecc.Parameters != null)
            {
                foreach (Parametro parametro in ecc.Parameters)
                {
                    ritorno += aCapo;
                    ritorno += "     parametro: " + parametro.ParameterName + aCapo;
                    ritorno += "     dimensione: " + parametro.Size.ToString() + aCapo;
                    ritorno += "     direzione: " + parametro.Direction.ToString() + aCapo;
                    ritorno += "     tipo: " + parametro.DbType.ToString() + aCapo;

                    if (parametro.Value == null)
                        ritorno += "     valore: null" + aCapo;
                    else
                    {
                        string valoreParametro = "";
                        if (parametro.Size > 500)
                        {
                            valoreParametro = "     valore: null(sono visualizzati solo i primi 500 bytes): " + parametro.Value.ToString().Substring(0, 500);
                        }
                        else
                        {
                            valoreParametro = "     valore: " + parametro.Value.ToString();
                        }
                        ritorno += valoreParametro + aCapo;
                    }
                }
            }
            ritorno += aCapo;
            ritorno += "    tipo: DataBaseException" + aCapo;
            ritorno += "    descrizione: " + ecc.Eccezione.Message + aCapo;
            ritorno += "    sorgente: " + ecc.Eccezione.Source + aCapo;
            ritorno += "    traccia: " + FormattaErrore(ecc.StackTrace) + aCapo;
            return ritorno;

        }

        private static string getException(Exception ecc)
        {
            const string aCapo = "#/n#";
            string ritorno = "";
            ritorno += aCapo;
            ritorno += "    tipo: " + ecc.GetType().ToString() + aCapo;
            ritorno += "    descrizione: " + ecc.Message + aCapo;
            ritorno += "    sorgente: " + ecc.Source + aCapo;
            if (ecc.InnerException != null)
            {
                ritorno += "    descrizione Inner: " + ecc.InnerException.Message + aCapo;
                ritorno += "    sorgente Inner: " + ecc.InnerException.Source + aCapo;
            }
            ritorno += "    traccia: " + FormattaErrore(ecc.StackTrace) + aCapo;
            return ritorno;

        }

        private static string FormattaErrore(string errore)
        {
            const string aCapo = "#/n#";
            const string spazio = "      ";
            string separatore1 = " at ";
            string separatore2 = " in ";
            string separatore3 = ":line ";
            string erroreInterno = errore.Replace(separatore1, "@");
            string ritorno = aCapo;


            //nome metodo e tutto il resto
            string[] messaggioErrore = erroreInterno.Split('@');
            string messaggioSenzaSpazi;
            string[] messaggioInterno;

            foreach (string messaggio in messaggioErrore)
            {
                messaggioSenzaSpazi = messaggio.Trim();

                if (messaggioSenzaSpazi != "")
                {
                    messaggioSenzaSpazi = messaggioSenzaSpazi.Replace(separatore2, "@");
                    messaggioInterno = messaggioSenzaSpazi.Split('@');
                    if (messaggioInterno.GetUpperBound(0) == 1)
                    {
                        ritorno += spazio + "metodo: " + messaggioInterno[0] + aCapo;
                        string fileLineaSingolo = messaggioInterno[1].Replace(separatore3, "@");
                        string[] fileLinea = fileLineaSingolo.Split('@');
                        ritorno += spazio + "percorsoFile: " + fileLinea[0] + aCapo;
                        ritorno += spazio + "linea: " + fileLinea[1] + aCapo;
                        ritorno += aCapo;
                    }
                    else
                    {
                        ritorno += spazio + "metodo: " + messaggioInterno[0] + aCapo;
                    }
                }
            }

            return ritorno;
        }

        private void ScriviErroreNelDB(DataAccessDE dataAccess, int codiceErrore, string descrizioErrore, int localeId, string nomePackage, string descrizionePackage)
        {
            int scriviErroreNelDB = int.Parse(ConfigurationManager.AppSettings["scriviErroreNelDB"]);
            if (scriviErroreNelDB == 1)
            {
                try
                {
                    List<Parametro> parametri = new List<Parametro>();
                    Parametro parametro = new Parametro();
                    parametro.DbType = DbType.Int32;
                    parametro.ParameterName = "codiceErrore";
                    parametro.Value = codiceErrore;
                    parametri.Add(parametro);

                    parametro = new Parametro();
                    parametro.DbType = DbType.String;
                    parametro.ParameterName = "descrizioErrore";
                    parametro.Value = descrizioErrore;
                    parametri.Add(parametro);

                    parametro = new Parametro();
                    parametro.DbType = DbType.DateTime;
                    parametro.ParameterName = "dataTime";
                    parametro.Value = DateTime.Now;
                    parametri.Add(parametro);

                    parametro = new Parametro();
                    parametro.DbType = DbType.String;
                    parametro.ParameterName = "localeID";
                    if (localeId == 0)
                        parametro.Value = System.DBNull.Value;
                    else
                        parametro.Value = localeId;
                    parametri.Add(parametro);

                    parametro = new Parametro();
                    parametro.DbType = DbType.String;
                    parametro.ParameterName = "descrizionePackage";
                    parametro.Value = descrizionePackage;
                    parametri.Add(parametro);

                    parametro = new Parametro();
                    parametro.DbType = DbType.String;
                    parametro.ParameterName = "nomePackage";
                    parametro.Value = nomePackage;
                    parametri.Add(parametro);

                    DataAccess.ExecuteNonQueryStoredProcedure(DBProvider.SqlServerStampeC6, "[C6Mart].[UT_INSERT_ERROR]", parametri);
                }
                catch (Exception ex)
                {
                    DataBaseException dataBaseException = (DataBaseException)ex;
                    Console.WriteLine(dataBaseException.Message);
                }
            }
        }

        private static void StartTng(string ambiente, string cawTo_Bin, string argomentiCaw)
        {
            if (!ambiente.Equals("SVILUPPO"))
            {
                Process processTng = new Process();
                try
                {
                    processTng = Process.Start(cawTo_Bin, argomentiCaw);
                    while (!processTng.HasExited) ;
                }
                catch (Exception ex)
                {
                    throw new Exception("cawTo_Bin: Non riesco ad eseguire " + cawTo_Bin + " sulla macchina " + System.Environment.MachineName + ":" + ex.Message);
                }
                finally
                {
                    processTng.Close();
                    processTng.Dispose();
                }
            }
        }


        /// <summary>
        /// Popola l'oggetto Report.
        /// </summary>
        /// <param name="doc"></param>
        /// <returns></returns>
        private bool createReport(DocumentPDF doc)
        {
            // Creo l'oggetto REPORT al quale aggiungero i Capitoli 
            Report report = new Report(_reportType.TipoReport);

            // recupero gli eventuali intermediari
            DataTable dtIntermediari = new DataTable();
            dtIntermediari = GetIntermediari();

            DataSet dsProdottiProtetti = new DataSet();
            if (report.Tipo == TipoReport.MONITORAGGIO)
            {
                DataTable dtProdottiProtetti = GetProdottiProtetti();
                dtProdottiProtetti.TableName = "ProdottiProtetti";

                dsProdottiProtetti.Tables.Add(dtProdottiProtetti.Copy());
            }

            DataSet dsBonus = new DataSet();
            if (report.Tipo == TipoReport.MONITORAGGIO)
            {
                DataTable dtBonus = GetBonus();
                dtBonus.TableName = "Bonus";

                dsBonus.Tables.Add(dtBonus.Copy());
            }

            DataSet dsAreeBisognoProgetto = new DataSet();
            if (report.Tipo == TipoReport.MONITORAGGIO)
            {
                // recupero le aree/progetto da stampare per il dettaglio del monitoraggio
                DataTable dtAreeProgettiMonitorati = GetAreeMonitorate();
                dtAreeProgettiMonitorati.TableName = "AreeMonitorate";

                //MIFID2 20180529 inserimento del numero delle aree nel document
                doc.AreasCount = dtAreeProgettiMonitorati.Rows.Count;
                doc.Areas = dtAreeProgettiMonitorati;
                //--MIFID2

                dsAreeBisognoProgetto.Tables.Add(dtAreeProgettiMonitorati.Copy());
            }

            //Recupero tutti i dati sia dei capitoli, sia dei paragrafi che delle sezioni
            DataTable tabellaDati = getData(_reportType.IdReport, _reportType.IdModello);



            /********************************** Fix Ramo parallelo per SP delle Percentuali 23/10/2020 --Pino *********************************************/
            foreach (var item in tabellaDati.AsEnumerable())
            {
                if ((item.Field<int>("idSezione") == 13) && (item.Field<string>("codiceSezione") == "S80ALT"))
                {
                    string Banca = "";
                    if (_dataThread.Rete == "W")
                        Banca = "IW Private Investments.";
                    else if (_dataThread.Rete == "S")
                        Banca = "Fideuram S.p.A., commercializzato tramite la rete di private banker Sanpaolo Invest.";
                    else
                        Banca = "Fideuram.";
                    item.SetField<string>("querySqlSezione", "[C6MartPeriodico].PL_S80Alternativa_perc");
                    string testoSezione = string.Concat("Nella tabella pu� verificare come si � evoluto l�ammontare del Suo patrimonio dall�attivazione del monitoraggio. Sono inoltre riportate, per ogni area di bisogno, l'allocazione ottimale (",@"""Piramide Modello""",") corrente, al precedente invio del report e all�attivazione del monitoraggio, delle risorse finanziarie che lei detiene presso " + Banca);
                    item.SetField<string>("testoSezione", testoSezione);
                }
            }
            /***********************************************************************************************************************************************/

            ///******************************* ESG - Per test modifica al valore del campo IndicizzazioneSezione da false a true -- Pino ***********************************/
            //foreach (var item in tabellaDati.AsEnumerable())
            //{
            //    //if ((item.Field<int>("idCapitolo") == 53) && (item.Field<int>("idSezione") == 307))
            //    //{
            //    //    item.SetField<string>("indicizzatoSezione", "true");
            //    //}

            //    //if ((item.Field<int>("idCapitolo") == 53) && (item.Field<int>("idSezione") == 308))
            //    //{
            //    //    item.SetField<string>("indicizzatoSezione", "true");
            //    //}
            //    //if (item.Field<int>("idSezione") == 128)
            //    //{
            //    //    item.SetField<string>("ordineParagrafo", "20");
            //    //}
            //}
            ///********************************************************************************************************************************************************/

            /*** ATTENZIONE DA TOGLIERE ***/
            //DataRow rigaiCapital = tabellaDati.NewRow();

            //rigaiCapital.SetField<string>("idCapitolo", "52");
            //rigaiCapital.SetField<string>("ordineCapitolo", "10");
            //rigaiCapital.SetField<string>("titoloCapitolo", "Dettaglio prodotti per area di bisogno");
            //rigaiCapital.SetField<string>("testoCapitolo", "In questo capitolo vengono riportate nel dettaglio le posizioni che lei detiene presso $/Banca/$, raggruppate secondo l�area di bisogno a cui i relativi prodotti sono stati destinati.");
            //rigaiCapital.SetField<string>("testoCapitoloAlternativo", "In questo capitolo vengono riportate nel dettaglio le posizioni che Lei detiene presso $/Banca/$, raggruppate secondo l�area di bisogno a cui i relativi prodotti sono stati destinati.");
            //rigaiCapital.SetField<string>("nuovaPaginaCapitolo", "False");
            //rigaiCapital.SetField<string>("querySqlCapitolo", "");
            //rigaiCapital.SetField<string>("idParagrafo", "73");
            //rigaiCapital.SetField<string>("ordineParagrafo", "10");
            //rigaiCapital.SetField<string>("titoloParagrafo", "");
            //rigaiCapital.SetField<string>("sottoTitoloParagrafo", "");
            //rigaiCapital.SetField<string>("testoParagrafo", "Di seguito vengono elencati i prodotti che non � stato possibile rappresentare nella distribuzione per Asset class.");
            //rigaiCapital.SetField<int>("spazioNecessarioSezioneSuccessiva", 0);
            //rigaiCapital.SetField<string>("querySqlParagrafo", "");
            //rigaiCapital.SetField<string>("indicizzatoParagrafo", "True");
            //rigaiCapital.SetField<string>("ordineSezione", "10");
            //rigaiCapital.SetField<string>("idSezione", "140");
            //rigaiCapital.SetField<string>("codiceSezione", "FD60");
            //rigaiCapital.SetField<string>("querySqlSezione", "[C6Mart].[PL_D_S160DettaglioProdottiBF]");
            //rigaiCapital.SetField<string>("indicizzatoSezione", "True");
            //rigaiCapital.SetField<string>("filtroSezione", "");
            //rigaiCapital.SetField<string>("titoloSezione", "");
            //rigaiCapital.SetField<string>("testoSezione", "");
            //rigaiCapital.SetField<string>("testoSezioneAlternativo", "");
            //rigaiCapital.SetField<string>("notaSezione", "");
            //rigaiCapital.SetField<string>("notaSezioneAlternativo", "");
            //rigaiCapital.SetField<string>("nuovaPaginaDopo", "False");

            //tabellaDati.Rows.Add(rigaiCapital);
            /***************************************************************************************/

            _dataThread.Schema = tabellaDati;

            //Recupero tutti i vincoli delle sezioni
            DataTable tabellaVincoli = getDataVincoli(_reportType.IdModello);


            // Associo l'oggetto DocumentPDF gi� creato alla propriet� DocumentPDF del Report.
            report.DocumentPDF = doc;

            //Recupero i capitoli.
            DataView viewCapitoli = new DataView(tabellaDati);
            DataTable tabellaCapitoli = viewCapitoli.ToTable(true, "idCapitolo", "titoloCapitolo", "testoCapitolo", "testoCapitoloAlternativo", "querySqlCapitolo", "nuovaPaginaCapitolo");

            //Aggiungo tutti i capitoli al report.
            foreach (DataRow rowCapitoli in tabellaCapitoli.Rows)
            {
                CapitoloReport capitolo;
                if (rowCapitoli["querySqlCapitolo"].ToString().ToLower() == "intermediario")
                {
                    if (dtIntermediari.Rows.Count == 1)
                    {
                        capitolo = new CapitoloReport(Convert.ToInt32(rowCapitoli["idCapitolo"]), rowCapitoli);
                        capitolo.Intermediario = dtIntermediari.Rows[0]["Intermediario"].ToString();

                        if (capitolo.Intermediario.ToLower() == "altro")
                            capitolo.Titolo = "Dettaglio Altro intermediario";
                        else
                        {
                            capitolo.Titolo = "Dettaglio " + capitolo.Intermediario;
                            capitolo.TestoIntroduttivo = "Questo capitolo fornisce una rappresentazione del patrimonio finanziario che Lei detiene presso " + capitolo.Intermediario + ".";
                        }

                        AddParagrafiToCapitolo(capitolo, tabellaDati, tabellaVincoli, null);
                        // aggiunge il capitolo al report
                        report.Add(capitolo);
                    }
                    else
                    {
                        capitolo = new CapitoloReport(Convert.ToInt32(rowCapitoli["idCapitolo"]), rowCapitoli);
                        AddParagrafiToCapitolo(capitolo, tabellaDati, tabellaVincoli, null);
                        // aggiunge il capitolo al report
                        report.Add(capitolo);
                    }
                }

                //Adriano 20171109 per gestire l'esclusione dei prodotto a capitale protetto se non esistono per il cliente corrente.
                else if (rowCapitoli["querySqlCapitolo"].ToString().ToLower().Equals("prodottiprotetti"))
                {

                    if (dsProdottiProtetti.Tables[0].Rows.Count > 0)
                    {
                        capitolo = new CapitoloReport(Convert.ToInt32(rowCapitoli["idCapitolo"]), rowCapitoli);
                        capitolo.Intermediario = string.Empty;
                        AddParagrafiToCapitolo(capitolo, tabellaDati, tabellaVincoli, dsProdottiProtetti);
                        // aggiunge il capitolo al report
                        report.Add(capitolo);
                    }

                }
                //--Adriano

                //Adriano 20171117 per gestire l'esclusione dei bonus se non esistono per il cliente corrente.
                else if (rowCapitoli["querySqlCapitolo"].ToString().ToLower().Equals("bonus"))
                {

                    if (dsBonus.Tables[0].Rows.Count > 0)
                    {
                        capitolo = new CapitoloReport(Convert.ToInt32(rowCapitoli["idCapitolo"]), rowCapitoli);
                        capitolo.Intermediario = string.Empty;
                        AddParagrafiToCapitolo(capitolo, tabellaDati, tabellaVincoli, dsBonus);
                        // aggiunge il capitolo al report
                        report.Add(capitolo);
                    }

                }
                //--Adriano

                else if (rowCapitoli["querySqlCapitolo"].ToString() == string.Empty)
                {
                    capitolo = new CapitoloReport(Convert.ToInt32(rowCapitoli["idCapitolo"]), rowCapitoli);
                    capitolo.Intermediario = string.Empty;
                    AddParagrafiToCapitolo(capitolo, tabellaDati, tabellaVincoli, dsAreeBisognoProgetto);
                    // aggiunge il capitolo al report
                    report.Add(capitolo);
                }
            }

            // Disegno il Report.
            report.Disegna();
            return true;

        }

        /// <summary>
        /// Aggiunge i paragrafi al capitolo passato in input.
        /// </summary>
        /// <param name="capitolo"></param>
        /// <param name="tabellaDati"></param>
        /// <param name="tabellaVincoli"></param>
        /// <param name="dsAreeBisognoProgetto"></param>
        private void AddParagrafiToCapitolo(CapitoloReport capitolo, DataTable tabellaDati, DataTable tabellaVincoli, DataSet dsAreeBisognoProgetto)
        {
            //Recupero i paragrafi per ogni capitolo.
            DataView viewParagrafo = new DataView(tabellaDati);
            viewParagrafo.RowFilter = "idCapitolo = " + capitolo.Id.ToString();
            DataTable tabellaParagrafi = viewParagrafo.ToTable(true, "idParagrafo", "ordineParagrafo", "titoloParagrafo", "sottoTitoloParagrafo", "testoParagrafo", "querySqlParagrafo", "indicizzatoParagrafo", "SpazioNecessarioSezioneSuccessiva");

            ParagrafoReport paragrafo = null;
            int idParagrafo = -1;

            foreach (DataRow rowParagrafi in tabellaParagrafi.Rows)
            {
                idParagrafo = Convert.ToInt32(rowParagrafi["idParagrafo"]);
                paragrafo = new ParagrafoReport(Convert.ToInt32(rowParagrafi["idParagrafo"]), rowParagrafi);
                paragrafo.SpazioNecessarioSezioneSuccessiva = rowParagrafi["SpazioNecessarioSezioneSuccessiva"] == DBNull.Value ? 0 : Convert.ToInt32(rowParagrafi["SpazioNecessarioSezioneSuccessiva"]);

                #region Rischio Credito
                if (rowParagrafi["querySqlParagrafo"].ToString().ToLower() == "rischiocredito")
                {
                    if (_tipoReport.ToUpper() == "DIAGNOSI")
                    {
                        // recupero gli eventuali intermediari
                        DataTable dtIntermediari = new DataTable();
                        dtIntermediari = GetIntermediari();

                        //Se ho solo un intermediario faccio vedere solo la 102 e 103 per fideuram, altrimenti devo mostrare complessivo, fideuram e altri instituti
                        if (dtIntermediari.Rows.Count >= 1)
                        {
                            //COMPLESSIVO
                            paragrafo = new ParagrafoReport(Convert.ToInt32(rowParagrafi["idParagrafo"]), rowParagrafi);
                            //Per come � fatto il paragrafo del rischio credito il titolo lo metto a codice altrimenti dovevo aggiungere un capitolo non indicizzato
                            paragrafo.Titolo = "Approfondimento Rischio Credito";
                            paragrafo.SpazioNecessarioSezioneSuccessiva = rowParagrafi["SpazioNecessarioSezioneSuccessiva"] == DBNull.Value ? 0 : Convert.ToInt32(rowParagrafi["SpazioNecessarioSezioneSuccessiva"]);
                            paragrafo.IntermediarioPar = "Complessivo";
                            AddSezioniToParagrafo(capitolo, paragrafo, tabellaDati, tabellaVincoli);
                            capitolo.Add(paragrafo);

                            //FIDEURAM
                            paragrafo = new ParagrafoReport(Convert.ToInt32(rowParagrafi["idParagrafo"]), rowParagrafi);
                            paragrafo.SpazioNecessarioSezioneSuccessiva = rowParagrafi["SpazioNecessarioSezioneSuccessiva"] == DBNull.Value ? 0 : Convert.ToInt32(rowParagrafi["SpazioNecessarioSezioneSuccessiva"]);
                            paragrafo.IntermediarioPar = "BF";
                            AddSezioniToParagrafo(capitolo, paragrafo, tabellaDati, tabellaVincoli);
                            capitolo.Add(paragrafo);

                            foreach (DataRow inter in dtIntermediari.Rows)
                            {
                                paragrafo = new ParagrafoReport(Convert.ToInt32(rowParagrafi["idParagrafo"]), rowParagrafi);
                                paragrafo.SpazioNecessarioSezioneSuccessiva = rowParagrafi["SpazioNecessarioSezioneSuccessiva"] == DBNull.Value ? 0 : Convert.ToInt32(rowParagrafi["SpazioNecessarioSezioneSuccessiva"]);
                                paragrafo.IntermediarioPar = inter["Intermediario"].ToString();
                                AddSezioniToParagrafo(capitolo, paragrafo, tabellaDati, tabellaVincoli);
                                capitolo.Add(paragrafo);
                            }
                        }
                        else
                        {
                            paragrafo.Titolo = "Approfondimento Rischio Credito";
                            paragrafo.IntermediarioPar = "BF";
                            AddSezioniToParagrafo(capitolo, paragrafo, tabellaDati, tabellaVincoli);
                            // aggiunge il paragrafo al capitolo
                            capitolo.Add(paragrafo);
                        }
                    }
                    else //Monitoraggio
                    {
                        paragrafo.Titolo = "Approfondimento Rischio Credito";

                        AddSezioniToParagrafo(capitolo, paragrafo, tabellaDati, tabellaVincoli);
                        // aggiunge il paragrafo al capitolo
                        capitolo.Add(paragrafo);
                    }
                }
                #endregion

                #region Rischio Credito New

                else if (rowParagrafi["querySqlParagrafo"].ToString().ToLower() == "rischiocreditonew")
                {
                    if (_tipoReport.ToUpper() == "DIAGNOSI")
                    {
                        // recupero gli eventuali intermediari
                        DataTable dtIntermediari = new DataTable();
                        dtIntermediari = GetIntermediari();

                        //Se ho solo un intermediario faccio vedere solo la 102 e 103 per fideuram, altrimenti devo mostrare complessivo, fideuram e altri instituti
                        if (dtIntermediari.Rows.Count >= 1)
                        {


                            //FIDEURAM
                            paragrafo = new ParagrafoReport(Convert.ToInt32(rowParagrafi["idParagrafo"]), rowParagrafi);
                            paragrafo.SpazioNecessarioSezioneSuccessiva = rowParagrafi["SpazioNecessarioSezioneSuccessiva"] == DBNull.Value ? 0 : Convert.ToInt32(rowParagrafi["SpazioNecessarioSezioneSuccessiva"]);
                            paragrafo.IntermediarioPar = "BF";
                            AddSezioniToParagrafo(capitolo, paragrafo, tabellaDati, tabellaVincoli);
                            capitolo.Add(paragrafo);

                            //foreach (DataRow inter in dtIntermediari.Rows)
                            //{
                            paragrafo = new ParagrafoReport(Convert.ToInt32(rowParagrafi["idParagrafo"]), rowParagrafi);
                            paragrafo.SpazioNecessarioSezioneSuccessiva = rowParagrafi["SpazioNecessarioSezioneSuccessiva"] == DBNull.Value ? 0 : Convert.ToInt32(rowParagrafi["SpazioNecessarioSezioneSuccessiva"]);
                            //paragrafo.IntermediarioPar = inter["Intermediario"].ToString();
                            paragrafo.IntermediarioPar = "Altri Istituti";
                            AddSezioniToParagrafo(capitolo, paragrafo, tabellaDati, tabellaVincoli);
                            capitolo.Add(paragrafo);
                            //}

                            //COMPLESSIVO
                            paragrafo = new ParagrafoReport(Convert.ToInt32(rowParagrafi["idParagrafo"]), rowParagrafi);
                            //Per come � fatto il paragrafo del rischio credito il titolo lo metto a codice altrimenti dovevo aggiungere un capitolo non indicizzato
                            paragrafo.Titolo = "Approfondimento Rischio Credito";
                            paragrafo.SpazioNecessarioSezioneSuccessiva = rowParagrafi["SpazioNecessarioSezioneSuccessiva"] == DBNull.Value ? 0 : Convert.ToInt32(rowParagrafi["SpazioNecessarioSezioneSuccessiva"]);
                            paragrafo.IntermediarioPar = "Complessivo";
                            AddSezioniToParagrafo(capitolo, paragrafo, tabellaDati, tabellaVincoli);
                            capitolo.Add(paragrafo);
                        }
                        else
                        {
                            paragrafo.Titolo = "Approfondimento Rischio Credito";
                            paragrafo.IntermediarioPar = "BF";
                            AddSezioniToParagrafo(capitolo, paragrafo, tabellaDati, tabellaVincoli);
                            // aggiunge il paragrafo al capitolo
                            capitolo.Add(paragrafo);
                        }
                    }
                    else //Monitoraggio
                    {
                        paragrafo.Titolo = "Approfondimento Rischio Credito";

                        AddSezioniToParagrafo(capitolo, paragrafo, tabellaDati, tabellaVincoli);
                        // aggiunge il paragrafo al capitolo
                        capitolo.Add(paragrafo);
                    }
                }
                #endregion

                #region Aree Monitorate
                else if (rowParagrafi["querySqlParagrafo"].ToString().ToLower() == "areemonitorate") // duplica i paragrafi per ogni area monitorata.
                {
                    int numeroProgettiInvestimento = 0;
                    DataRow[] drTotaleProgettiInvestimento = dsAreeBisognoProgetto.Tables["AreeMonitorate"].Select(" Need_Area = 'Inv'");
                    int totaleProgettiInvestimento = drTotaleProgettiInvestimento.Length;
                    // 28/10/2015 federicaluca
                    //int titoloParagrafoInvestimento = 0;
                    //
                    foreach (DataRow rAreeeMonitorate in dsAreeBisognoProgetto.Tables["AreeMonitorate"].Rows)
                    {
                        paragrafo = new ParagrafoReport(idParagrafo, rowParagrafi);
                        // MIOFOGLIO 20181205 per le Self
                        paragrafo.Titolo = rAreeeMonitorate["Need_Estesa"].ToString();
                        paragrafo.AreaProgettoDescrizione = rAreeeMonitorate["Need_Estesa"].ToString();
                        paragrafo.CodiceAreaSelf = rAreeeMonitorate["Nome_Progetto"].ToString()!=null? rAreeeMonitorate["Nome_Progetto"].ToString():"";
                        //paragrafo.Titolo = rAreeeMonitorate["Need_Estesa"].ToString();
                        //paragrafo.AreaProgettoDescrizione = rAreeeMonitorate["Need_Estesa"].ToString();
                        //--MIOFOGLIO 20181205 per le Self
                        paragrafo.AreaProgettoCodice = rAreeeMonitorate["Need_Area"].ToString();
                        paragrafo.AreaProgettoSottoMonitoraggio = rAreeeMonitorate["areaprogettosottomonitoraggio"] == DBNull.Value ? false : Convert.ToBoolean(rAreeeMonitorate["areaprogettosottomonitoraggio"]);

                        //V Spostasto fuori dall'IF se l'area � inv
                        //Ordinamento progetto (ambito Aree Monitorate) ZINZERI:
                        if (//V Il filtro va fatto anche per le aree senza monit altrimenti la S86 non pu� filtrare correttamente paragrafo.AreaProgettoSottoMonitoraggio &&
                            rAreeeMonitorate["Ordinamento_Progetto"] != null &&
                            !rAreeeMonitorate["Ordinamento_Progetto"].Equals(System.DBNull.Value))
                            paragrafo.OrdinamentoProgettoPerAreeMonitorate = Convert.ToInt32(rAreeeMonitorate["Ordinamento_Progetto"]);


                        if (rAreeeMonitorate["Need_Area"].ToString().ToLower() != "inv")
                            paragrafo.NomeProgetto = "Default";// string.Empty;
                        else // � un area di investimento quindi mi recupero anche il nome del progetto.                       
                        {
                            //Nome progetto:
                            paragrafo.NomeProgetto = rAreeeMonitorate["Nome_Progetto"].ToString();


                            // Se c'� un solo progetto in investimento chiamato "progetto investimento" 
                            // non deve essere stampato il nome di questo progetto come intestazione del paragrafo (propriet� SottoTitolo dell'oggettp paragrafo)
                            //if ((totaleProgettiInvestimento == 1 && rAreeeMonitorate["Nome_Progetto"].ToString().ToLower() == "progetto investimento") || (rAreeeMonitorate == null))
                            if ((totaleProgettiInvestimento == 1 && rAreeeMonitorate["Nome_Progetto"].ToString().ToLower() == "progetto investimento"))

                                paragrafo.SottoTitolo = string.Empty;
                            else
                                paragrafo.SottoTitolo = rAreeeMonitorate["Nome_Progetto"].ToString();

                            //Le sezioni useranno questo valore per impostare titoletti ed aspetti vari connessi:
                            paragrafo.NumeroProgettiInvestimento = drTotaleProgettiInvestimento.Length;

                            // va indicizzato solo il primo dei paragrafi di investimento nel caso ci siano + progetti.
                            // ogni progetto di investimento � considerato un paragrafo nuovo.

                            //Modifica per S43BIS, S43 e per Tipo Contratto != 0 
                            if (numeroProgettiInvestimento > 0)
                                paragrafo.Indicizzato = false;

                            //if (numeroProgettiInvestimento > 0)
                            //{
                            //    switch (_dataThread.TipoReport.ToUpper())
                            //        {

                            //        case "DIAGNOSI":
                            //        if (numeroProgettiInvestimento > 0)  
                            //            paragrafo.Indicizzato = false;
                            //            break;
                            //        default:
                            //            if ((numeroProgettiInvestimento > 0) && (capitolo.Titolo == "Dettaglio Prodotti per Area di Bisogno"))
                            //                paragrafo.Indicizzato = true;
                            //            else
                            //                paragrafo.Indicizzato = true;//false
                            //            break;
                            //        }
                            //}

                            /*modifica federicaluca 27/10/2015: la modifica � dovuta ad una segnalazione del QC nella 3� reportistica 2015 
                             * identificata con id2. Il problema riguardava una casistica particolare di clienti per i quali nella sezione 
                             * Monitoraggio per aree di bisogno' quando il primo progetto risultava non monitorato non veniva scritto il titoto 
                             * dell'area (ovvero del pargrafo stesso, esempio: '2.3 Investimento'. Per circoscrivere la modifica e non impattare 
                             * le altre sezioni abbiamo sottoposto l'intervento all'id 61 che identifica la sezione.

                            */


                            if (paragrafo.Id == 61)
                            {
                                if (paragrafo.AreaProgettoSottoMonitoraggio == true)
                                {
                                    numeroProgettiInvestimento++;
                                }
                            }
                            else
                            {

                                numeroProgettiInvestimento++;
                            }





                        }

                        AddSezioniToParagrafo(capitolo, paragrafo, tabellaDati, tabellaVincoli);

                        // aggiunge il paragrafo al capitolo
                        capitolo.Add(paragrafo);
                    }
                }

                #endregion

                // Adriano 20171117 Gestione del capitale protetto
                #region Prodotti Protetti
                else
                {
                    if (rowParagrafi["querySqlParagrafo"].ToString().ToLower() == "prodottiprotetti") // duplica i paragrafi per ogni prodotto protetto.
                    {



                        foreach (DataRow rProdotti in dsAreeBisognoProgetto.Tables["ProdottiProtetti"].Rows)
                        {
                            if (rowParagrafi["SottoTitoloParagrafo"].ToString().Equals(rProdotti["TipoParagrafo"]))
                            {
                                paragrafo = new ParagrafoReport(idParagrafo, rowParagrafi);
                                paragrafo.Titolo = (!string.IsNullOrEmpty(rProdotti["Contratto"].ToString())) ?
                                    string.Concat(rProdotti["DescrizioneProdotto"].ToString(), " - contratto ", rProdotti["Contratto"].ToString()) :
                                    rProdotti["DescrizioneProdotto"].ToString();
                                paragrafo.AreaProgettoCodice = rProdotti["TipoProdotto"].ToString();
                                paragrafo.TestoIntroduttivo = paragrafo.TestoIntroduttivo.Replace("$/Prodotto/$", paragrafo.Titolo);
                                paragrafo.AreaProgettoDescrizione = rProdotti["Contratto"].ToString();
                                AddSezioniToParagrafo(capitolo, paragrafo, tabellaDati, tabellaVincoli);
                                // aggiunge il paragrafo al capitolo
                                capitolo.Add(paragrafo);

                            }

                            //int numeroProdotti = 0;
                            //DataRow[] drTotaleProdotti = dsAreeBisognoProgetto.Tables["ProdottiProtetti"].Select(" Need_Area = 'Inv'");
                            //int totaleProdotti = drTotaleProdotti.Length;
                            //// 28/10/2015 federicaluca
                            ////int titoloParagrafoInvestimento = 0;
                            ////
                            //foreach (DataRow rAreeeMonitorate in dsAreeBisognoProgetto.Tables["AreeMonitorate"].Rows)
                            //{
                            //    numeroProdotti++;
                            //}


                            //AddSezioniToParagrafo(capitolo, paragrafo, tabellaDati, tabellaVincoli);

                            //// aggiunge il paragrafo al capitolo
                            //capitolo.Add(paragrafo);
                        }
                    }
                    #endregion
                    //--Adriano

                    else
                    {
                        AddSezioniToParagrafo(capitolo, paragrafo, tabellaDati, tabellaVincoli);
                        // aggiunge il paragrafo al capitolo
                        capitolo.Add(paragrafo);
                    }
                }


            }
            //capitolo.
        }

        /// <summary>
        /// Aggiunge le sezioni al paragrafo.
        /// Di ciascuna sezione recupera e imposta i vincoli settati a livello di database.
        /// </summary>
        /// <param name="capitolo"></param>
        /// <param name="paragrafo"></param>
        /// <param name="tabellaDati"></param>
        /// <param name="tabellaVincoli"></param>
        private void AddSezioniToParagrafo(CapitoloReport capitolo, ParagrafoReport paragrafo, DataTable tabellaDati, DataTable tabellaVincoli)
        {
            //Recupero le sezioni per ogni paragrafo 
            DataView viewSezioni = new DataView(tabellaDati);
            viewSezioni.RowFilter = "idParagrafo = " + paragrafo.Id.ToString() + " AND idCapitolo= " + capitolo.Id.ToString(); // aggiungere il filtro del capitolo
            DataTable tabellaSezioni =
                viewSezioni.ToTable(true, "idSezione", "codiceSezione", "titoloSezione", "testoSezione",
                                    "testoSezioneAlternativo", "notaSezione", "notaSezioneAlternativo", "querySqlSezione",
                                    "indicizzatoSezione", "filtroSezione", "nuovaPaginaDopo");
            foreach (DataRow rowSezioni in tabellaSezioni.Rows)
            {
                SezioneReport sezione;
                string codiceSez = rowSezioni["codiceSezione"].ToString();

                sezione = new SezioneReport(_dataThread, _tabelleSessione, rowSezioni["codiceSezione"].ToString(), rowSezioni);
                sezione.FiltroSezione = rowSezioni["filtroSezione"].ToString();
                //Assegno alla sezione (dovrebbero essere la 102 e 103) l'intermediario definito nel paragrafop
                if (paragrafo.IntermediarioPar != null)
                    sezione.IntermediarioSez = paragrafo.IntermediarioPar;
                sezione.AreaProgettoDescrizione = paragrafo.AreaProgettoDescrizione;
                sezione.AreaProgettoCodice = paragrafo.AreaProgettoCodice;
                sezione.NomeProgetto = paragrafo.NomeProgetto;
                sezione.AreaProgettoSottoMonitoraggio = paragrafo.AreaProgettoSottoMonitoraggio;
                sezione.NumeroProgettiInvestimento = paragrafo.NumeroProgettiInvestimento;
                sezione.OrdinamentoProgettoPerAreeMonitorate = paragrafo.OrdinamentoProgettoPerAreeMonitorate;
                sezione.NuovaPaginaDopo = (Boolean)rowSezioni["nuovaPaginaDopo"];

                // TUOFOGLIO 20181213
                sezione.CodiceAreaSelf = paragrafo.CodiceAreaSelf;
                //--TUOFOGLIO 20181213

                // recupero i vincoli della sezione e setto la propriet� vincolo della stessa.
                if (tabellaVincoli != null)
                {
                    DataView viewVincoli = new DataView(tabellaVincoli);
                    viewVincoli.RowFilter = ("SezioneFisica = '" + sezione.Codice.Replace("'", "''") + "'");
                    DataTable datatableVincoli = viewVincoli.ToTable("datatableVincoli");

                    // Aggiungo i vincoli alla Sezione.
                    sezione.ImpostaVincoli(datatableVincoli);
                }

                //Bido Jan 2011 release
                if (paragrafo.AreaProgettoCodice.ToLower() == "cc")
                {
                    //paragrafo.Titolo = "Conti correnti a saldo negativo";
                    if (sezione.Codice == "S43BIS")
                    {
                        sezione.Titolo = string.Empty;
                        paragrafo.Add(sezione);
                    }
                }
                //End of Bido Jan 2011 release

                else
                    // aggiunge la sezione al paragrafo.                    
                    if (paragrafo.AreaProgettoCodice.ToLower() == "na")
                {
                    paragrafo.Titolo = "Risorse non allocate";
                    paragrafo.TestoIntroduttivo = "Nella tabella sono elencati i prodotti non ancora allocati sulle aree di bisogno.";

                    if (sezione.Codice == "S43BIS")
                    {
                        sezione.Titolo = string.Empty;
                        if (capitolo.Children.Count > 0)
                        {
                            ParagrafoReport pervParagrafo = capitolo.Children[capitolo.Children.Count - 1];
                            SezioneReport lastSezione = pervParagrafo.Children[pervParagrafo.Children.Count - 1];
                            lastSezione.NuovaPaginaDopo = false;
                        }
                        paragrafo.Add(sezione);
                    }
                }

                else

                    // Per il progetto d'investimento "Prodotti non associati a progetti" stampo solo la S43BIS                    
                    if (sezione.AreaProgettoCodice.ToLower() == "inv" && sezione.NomeProgetto.ToLower() == "prodotti non associati a progetti")
                {
                    if (sezione.Codice == "S43BIS")
                        paragrafo.Add(sezione);
                }
                //else
                //{
                //    paragrafo.Add(sezione);
                //}



                else
                    //Adriano 20171115 Gestione prodotti protetti, per inserire la sezione S172 in base al tipo di prodotto (1: Italfund, 2: Fonditalia)

                    if (paragrafo.QuerySql.ToLower().Equals("prodottiprotetti"))
                {

                    switch (paragrafo.AreaProgettoCodice)
                    {

                        case "TipoProdotto1":
                            {
                                sezione.QuerySql = "1";
                                break;
                            }

                        case "TipoProdotto2":
                            {
                                sezione.QuerySql = "2";
                                sezione.FiltroSezione = paragrafo.AreaProgettoDescrizione;
                                break;
                            }

                        case "TipoProdotto3":
                            {
                                sezione.QuerySql = "3";
                                sezione.FiltroSezione = paragrafo.AreaProgettoDescrizione;
                                break;
                            }
                    }

                    paragrafo.Add(sezione);

                }

                else
                {
                    paragrafo.Add(sezione);
                }
                //--Adriano
            }
        }


        //Adriano 20171113: inserite per gestire l'inclusione dei capitoli sul Capitale Protetto e sul Bonus in base alla presenza di prodotti a capitale protetto e bonus

        /// <summary>
        /// Recupera eventuali prodotti protetti.
        /// </summary>
        /// <returns></returns>
        private DataTable GetProdottiProtetti()
        {

            return SectionManager.GetDataSection(_tabelleSessione, "[C6MartPeriodico].[Gestione_ProdottiProtetti]", _dataThread);

        }

        /// <summary>
        /// Recupera eventuali bonus.
        /// </summary>
        /// <returns></returns>
        private DataTable GetBonus()
        {

            return SectionManager.GetDataSection(_tabelleSessione, "[C6MartPeriodico].[Gestione_Bonus]", _dataThread);

        }
        //--Adriano

        /// <summary>
        /// Recupera gli intermediari.
        /// </summary>
        /// <returns></returns>
        private DataTable GetIntermediari()
        {
            if (UtilityManager.getAppSetting("Periodico") == "0") // utilizzo come giornaliero            
                return SectionManager.GetDataSection(_tabelleSessione, "[C6Mart].[GESTIONE_S_Intermediari]", _dataThread);
            else
                return SectionManager.GetDataSection(_tabelleSessione, "[C6MartPeriodico].[GESTIONE_S_Intermediari]", _dataThread);

        }

        /// <summary>
        /// Recupera le aree/progetti da stampare nel dettaglio del monitoraggio.
        /// Originariamente non tutte le aree/progetti venivano stampati e il filtro veniva fatto direttamente sulla [C6MartPeriodico].[PL_AreeMonitorate].
        /// Attualmente la richiesta � che devono essere stampate nel dettaglio anche le aree non oggetto di monitoraggio.
        /// </summary>
        /// <returns></returns>
        private DataTable GetAreeMonitorate()
        {
            return SectionManager.GetDataSection(_tabelleSessione, "[C6MartPeriodico].[PL_AreeMonitorate]", _dataThread);
        }

        /// <summary> 
        /// Lancia la R6_S_Generator e recupera i dati di tutto il report.
        /// </summary> 
        /// <param name="IdReport"></param> 
        /// <param name="IdModello"></param> 
        /// <returns></returns> 
        private DataTable getData(int IdReport, int IdModello)
        {
            /*/
                        List<Parametro> parametri = new List<Parametro>();
                        return DataAccess.ExecuteDataTableStoredProcedure(DBProvider.SqlServerStampeC6, "[C6Mart].[SELECT_STRUTTURA_REPORT]", parametri);
                       */

            // D_IMPPROF 20180705 Va differenziata la chiamata alla stored procedure tra Giornaliero e Trimestrale, imposto come default quella per il Giornaliero
            string nomeStoredProcedure = "C6Mart.GESTIONE_C6_S_Generator";
            //-- D_IMPPROF

            List<Parametro> parametri = new List<Parametro>();
            Parametro parametro = new Parametro();
            parametro.ParameterName = "idReport";
            parametro.DbType = DbType.Int32;
            parametro.Value = IdReport;
            parametri.Add(parametro);
            parametro = new Parametro();
            parametro.ParameterName = "idModello";
            parametro.DbType = DbType.Int32;
            parametro.Value = IdModello;
            parametri.Add(parametro);

            //Usato come periodico
            if (UtilityManager.getAppSetting("Periodico") == "1")
            {
                parametro = new Parametro();
                parametro.ParameterName = "periodicita";
                parametro.DbType = DbType.String;
                parametro.Value = 'T';
                parametri.Add(parametro);
                // D_IMPPROF
                nomeStoredProcedure = "C6MartPeriodico.GESTIONE_C6_S_Generator";
                //-- D_IMPPROF

            }
            return _dataThread.DataAccess.ExecuteDataTableStoredProcedure(DBProvider.SqlServerStampeC6, nomeStoredProcedure, parametri);

        }

        /// <summary> 
        /// Lancia la R6_S_Vincoli e recupera i vincoli di tutte le sezioni 
        /// </summary> 
        /// <param name="IdModello"></param> 
        /// <returns></returns> 
        private DataTable getDataVincoli(int IdModello)
        {
            List<Parametro> parametri = new List<Parametro>();
            Parametro parametro = new Parametro();
            parametro.ParameterName = "idModello";
            parametro.DbType = DbType.Int32;
            parametro.Value = IdModello;
            parametri.Add(parametro);
            return _dataThread.DataAccess.ExecuteDataTableStoredProcedure(DBProvider.SqlServerStampeC6, "[C6Mart].[GESTIONE_C6_S_Vincoli]", parametri);
        }

        private int getIntFromBitArray(BitArray bitArray)
        {
            if (bitArray.Length > 32)
                throw new ArgumentException("Argument length shall be at most 32 bits.");
            int[] array = new int[1];
            bitArray.CopyTo(array, 0);
            return array[0];
        }
    }

    public class Worker : Task
    {

        string query;
        DataThread dataThread;
        List<SessionStruct> tabelleSessione;

        public Worker(string query, DataThread dt, List<SessionStruct> tabSess)
        {
            this.query = query;
            this.dataThread = dt;
            this.tabelleSessione = tabSess;
            this.taskData = new PipelineContext(dt.CodiceFiscale + "_" + query, this);
        }

        public override object Elaborate(Dictionary<String, Object> input)
        {

            SectionManager.GetDataSection(tabelleSessione, query, dataThread);
            return null;
        }
    }
}