using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using ceTe.DynamicPDF;
using Consulenza.ReportWriter.Business.Entity;

namespace Consulenza.ReportWriter.Business.OBJ_PDF
{
    /// <summary>
    /// Rappresenta una tabella.
    /// 
    /// </summary>
    public class TablePDF : ObjectPDF
    {
        #region Fields
        private bool _whitespaceTableCell = false;
        private float _widthseparationlines = 1;
        private bool _hidelastseparationline = true;
        private bool _hidefirstseparationline = false;
        private bool _showseparationlines = false;
        private bool _showfooterseparationlines = false;
        private bool _alternaterow = true;
        private float _margin = 5;
        private bool _pagebreak = true;
        private Style _style = Style.ConsulenzaBase;
        private bool _whiteSpacesHorizontalSeparator = false;
        private List<ColumnPDF> _columns = new List<ColumnPDF>();
        private DataTable _datasource;
        public List<int> RowsIndexesThatCantEndPage = new List<int>();
        public int RowsIndexesThatCantEndPageYLimit = 0;
        // TABLE TITLE
        private string _tableTitle = "";
        private bool _tableTitleFontBold = false;
        private ColorPDF _tableTitleFontColor = null;
        private float _tableTitleFontSize = 10;
        private float _tableTitleDeltaX = 0;


        // ROW TITLE
        private string _titlerowtext = string.Empty;
        private float _titlerowheight = 20;
        private BorderTitleRowType _titlerowborder = BorderTitleRowType.Pieno;
        private float _titlerowspace = 10;

        // SUBTITLE

        //CELL
        private Cell[,] _cells;


        //ROWS
        private RowPDF[] _row;
        private readonly int _rowscount;
        private float _rowspadding = 5;
        private float _rowheight = 18;
        private float _minimumrowheight;
        private List<float> specifiedRowHeights = new List<float>();


        // HEADER
        private bool _header = true;
        private bool _showborderheader = true;
        private string _headertext = string.Empty;
        private float _headerheight = 20;
        private float _headerfontsize = 9;
        private float _headermargin = 1;
        private float _yoffset = 0;
        private HorizontalAlignmentType _headertexthorizontalalign = HorizontalAlignmentType.Nonimpostato;
        private VerticalAlignmentType _headertextverticalalign = VerticalAlignmentType.Centrato;
        private float _additionalSpaceBetweenHeadersAndTable = 0;

        //FOOTER
        private bool _footer = true;
        private bool _showborderfooter = true;
        private List<ColumnPDF> _footercolumns = new List<ColumnPDF>();
        private Cell[,] _footercells;
        private float _footerheight = 20;
        private VerticalAlignmentType _footertextverticalalign = VerticalAlignmentType.Centrato;
        private float _footerYOffset = 0;
        //CONTENT
        private bool _showborderlastlineinpagebreak;

        // NOTE
        private List<TableNotePDF> _notes = new List<TableNotePDF>();

        // HEADER NOTES
        public List<ObjectPDF> HeaderNoteObjects = new List<ObjectPDF>();




        /// <summary>
        /// Imposta o ottiene la coordianata X su cui disegnare la TablePDF.
        /// </summary>
        public float X { get; set; }

        public bool DrawLineHeaderUP
        {
            get { return drawLineHeaderUP; }
            set { drawLineHeaderUP = value; }
        }

        private bool drawLineHeaderUP = true;

        public bool AddSpaceBeforeTableAfterEntireTableIsMovedToNextPage = false;
        public bool HeaderTextDrawJustOnce
        {
            get { return headerTextDrawJustOnce; }
            set { headerTextDrawJustOnce = value; }
        }

        public int HeaderTextCounter = 0;
        public int HeaderNoteObjectsCounter = 0;

        private bool headerTextDrawJustOnce = false;

        public int TableCantReachThisYPosition = 0;
        /// <summary>
        /// Imposta o ottiene la coordinaat Y su cui disegnare la TablePDF.
        /// </summary>
        public float Y { get; set; }

        public bool WhiteSpacesHorizontalSeparator
        {
            get
            {
                return _whiteSpacesHorizontalSeparator;
            }
            set
            {
                _whiteSpacesHorizontalSeparator = value;
            }
        }

        public float AdditionalSpaceBetweenHeadersAndTable
        {
            get
            {
                return _additionalSpaceBetweenHeadersAndTable;
            }
            set
            {
                _additionalSpaceBetweenHeadersAndTable = value;
            }
        }

        /// <summary>
        /// Imposta o recupera lo stile di visualizzazione di una tabella di Default (senza ulteriori personalizzazioni).
        /// Di default = Style.ConsulenzaBase (Report di proposta per ConsulenzaBase.)
        /// </summary>
        /// <remarks>NOTA DI SVILUPPO:
        /// Essendo di default impostata = Style.ConsulenzaBase, ogni proprietà impostata per ConsulenzaBase 
        /// deve necessariamente essere riportata in tutti gli altri "case"</remarks>
        public Style Style
        {
            get { return _style; }
            set
            {
                switch (value)
                {
                    case Style.ConsulenzaBase:
                        _minimumrowheight = 14;
                        _rowheight = 18;
                        _rowspadding = 5;

                        _headerfontsize = 8;
                        break;
                    case Style.Immobiliare:
                        _minimumrowheight = 0;
                        _rowheight = 0;
                        _rowspadding = 7;

                        _alternaterow = false;
                        _showborderfooter = false;
                        _showborderheader = false;

                        _headerfontsize = 8;
                        _headerheight = 25;
                        break;
                    case Style.ConsulenzaUnica:
                        _minimumrowheight = 18;
                        _rowheight = 0;
                        _rowspadding = 0;

                        _showseparationlines = true;
                        _showborderfooter = false;
                        _showborderheader = false;

                        _headerfontsize = 7;
                        break;
                    default:
                        break;
                }
                _style = value;
            }
        }

        /// <summary>
        /// Recupera l'altezza della tabella. 
        /// LIMITAZIONE: Utilizzabile solo se impostato MinimumRowHeight > 0.
        /// In caso contrario ritorna 0.
        /// </summary>
        public float Height
        {
            get
            {
                var rowheight = _minimumrowheight > 0 ? _minimumrowheight : 0;

                if (_rowheight > rowheight)
                    rowheight = _rowheight;

                return rowheight == 0 ? 0 : _headerheight + (rowheight * _rowscount) + (_rowspadding * (_rowscount + 1)) + _footerheight;
            }
        }

        /// <summary>
        /// Imposta o ottiene l'altezza dell'header della tabella
        /// Di default = 20.
        /// </summary>
        public float HeaderHeight
        {
            get { return _headerheight; }
            set { _headerheight = value; }
        }

        /// <summary>
        /// Imposta o ottiene il testo da stampare nell'header della tabella.
        /// Di default il testo non viene stampato e vengono stampate nell'header le caption delle singole colonne
        /// della tabella.
        /// Se HeaderText è valorizzata, non verranno stampate le caption delle colonne ma il testo contenuto in HeaderText.
        /// </summary>
        public string HeaderText
        {
            get { return _headertext; }
            set { _headertext = value; }
        }

        /// <summary>
        /// Imposta o ottiene il titolo della tabella.
        /// Di default il testo non viene stampato.
        /// </summary>
        public string TableTitle
        {
            get { return _tableTitle; }
            set { _tableTitle = value; }
        }

        private float tableTitleHeight;

        public float TableTitleHeight
        {
            get { return tableTitleHeight; }
            set { tableTitleHeight = value; }
        }

        public float HeadersObjectsHeight { get; set; }
        /// <summary>
        /// Imposta o ottiene il colore del titolo della tabella.
        /// Di default il testo è 'ColorPDF.Immobiliare_Grigio_TitoloPiccolo'.
        /// </summary>
        public ColorPDF TableTitleFontColor
        {
            get { return _tableTitleFontColor; }
            set { _tableTitleFontColor = value; }
        }

        /// <summary>
        /// Imposta o ottiene il titolo della tabella è in grassetto.
        /// Di default il testo non è in grassetto.
        /// </summary>
        public bool TableTitleFontBold
        {
            get { return _tableTitleFontBold; }
            set { _tableTitleFontBold = value; }
        }

        /// <summary>
        /// Imposta o ottiene la dimensione del titolo della tabella.
        /// Di default il testo non è 10.
        /// </summary>
        public float TableTitleFontSize
        {
            get { return _tableTitleFontSize; }
            set { _tableTitleFontSize = value; }
        }

        /// <summary>
        /// Imposta o ottiene il DeltaX del titolo della tabella.
        /// Di default il deltaX del testo è 0.
        /// </summary>
        public float TableTitleDeltaX
        {
            get { return _tableTitleDeltaX; }
            set { _tableTitleDeltaX = value; }
        }

        /// <summary>
        /// Allineamento Orizzontale del testo dell'header della tabella.
        /// Di default allineamento = NONIMPOSTATO.
        /// Se il valore è su NONIMPOSTATO l'allineamento usato sarà quello definito a livello di ciascuna colonna.
        /// Se il valore viene cambiato tutte le colonne dell'header verranno allineate secondo l'allineamento scelto indipendentemente da quello di ciascuna colonna.
        /// </summary>
        public HorizontalAlignmentType HeaderTextHorizontalAlign
        {
            get { return _headertexthorizontalalign; }
            set { _headertexthorizontalalign = value; }
        }

        /// <summary>
        /// Allineamento Verticale del testo dell'header della tabella
        /// Di default è allineato CENTRATO.
        /// </summary>
        public VerticalAlignmentType HeaderTextVerticalAlign
        {
            get { return _headertextverticalalign; }
            set { _headertextverticalalign = value; }
        }

        /// <summary>
        /// Imposta o recupera il margine tra l'header e il corpo della tabella.
        /// Di default = 1.
        /// </summary>
        public float HeaderMargin
        {
            get { return _headermargin; }
            set { _headermargin = value; }
        }

        /// <summary>
        /// Allineamento Verticale del testo del footer della tabella.
        /// Di default è allineato CENTRATO.
        /// </summary>
        public VerticalAlignmentType FooterTextVerticalAlign
        {
            get { return _footertextverticalalign; }
            set { _footertextverticalalign = value; }
        }

        /// <summary>
        /// Booleano che indica se mostrare il bordo di chiusura sull'ultima riga.
        /// Viene renderizzato solo se la tabella non ha footer.
        /// Di default = false;
        /// </summary>
        public bool ShowBorderLastLine { get; set; }

        /// <summary>
        /// Ottiene o imposta l'insieme di celle che costruiscono ogni singola riga della tabella. 
        /// TO DO
        /// </summary>
        public RowPDF[] Row
        {
            get { return _row; }
            set { _row = value; }
        }

        /// <summary>
        /// Recupera il numero totale di righe della tabella.
        /// </summary>
        public int RowsCount
        {
            get { return _rowscount; }
        }

        /// <summary>
        /// Imposta o recupera lo spazio tra le righe.
        /// Di default = 5.
        /// </summary>
        public float RowsPadding
        {
            get { return _rowspadding; }
            set { _rowspadding = value; }
        }
        public float RowsHeightOffset { get; set; }
        /// <summary>
        /// Ottiene o imposta le celle della tabella.
        /// L'ordine dell'array è colonna,riga.
        /// </summary>
        public Cell[,] Cells
        {
            get { return _cells; }
            set { _cells = value; }
        }

        /// <summary>
        /// Restituisce la larghezza tabella. Data dalla somma della largheza di ciascuna colonna.
        /// </summary>
        public float Width
        {
            get { return GetWidth(); }
        }

        /// <summary>
        /// Lista di colonne.
        /// </summary>
        public List<ColumnPDF> Columns
        {
            get { return _columns; }
            set { _columns = value; }
        }

        /// <summary>
        /// Lista delle colonne del Footer
        /// </summary>
        public List<ColumnPDF> FooterColumns
        {
            get { return _footercolumns; }
            set { _footercolumns = value; }
        }
        public float FooterYOffset
        {
            get { return _footerYOffset; }
            set { _footerYOffset = value; }
        }

        /// <summary>
        /// Imposta o ottiene la cella del footer.
        /// </summary>
        public Cell[,] FooterCells
        {
            get { return _footercells; }
            set { _footercells = value; }
        }

        /// <summary>
        /// Recupera o imposta l'altezza del footer della tabella
        /// Di default = 20.
        /// </summary>
        public float FooterHeight
        {
            get { return _footerheight; }
            set { _footerheight = value; }
        }

        /// <summary>
        /// DataSource. Contiene i dati che andranno stampati nella tabella
        /// </summary>
        public DataTable DataSource
        {
            get { return _datasource; }
            set { _datasource = value; }
        }

        /// <summary>
        /// DataSource del Footer. Contiene i dati che andranno stampati nel footer della tabella
        /// </summary>
        public DataTable FooterDatasource { get; set; }

        /// <summary>
        /// Mostra le linee di separazione tra una riga e l'altra.
        /// Di default false.
        /// </summary>
        public bool ShowSeparationLines
        {
            get { return _showseparationlines; }
            set { _showseparationlines = value; }
        }

        public bool ShowFooterSeparationLines
        {
            get { return _showfooterseparationlines; }
            set { _showfooterseparationlines = value; }
        }


        /// <summary>
        /// Di default true.
        /// Nasconde l'ultima riga di separazione.
        /// </summary>
        public bool HideLastSeparationLine
        {
            get { return _hidelastseparationline; }
            set { _hidelastseparationline = value; }
        }

        public bool HideFirstSeparationLine
        {
            get { return _hidefirstseparationline; }
            set { _hidefirstseparationline = value; }
        }


        ///// <summary>
        ///// Ottiene o imposta lo spessore delle linee di separazione.
        ///// Di default = 1
        ///// </summary>
        //public bool WhiteSpaceCells
        //{
        //    get { return _whitespaceTableCell; }
        //    set { _whitespaceTableCell = value; }
        //}
        /// <summary>
        /// Ottiene o imposta lo spessore delle linee di separazione.
        /// Di default = 1
        /// </summary>
        public float WidthSeparationLines
        {
            get { return _widthseparationlines; }
            set { _widthseparationlines = value; }
        }

        /// <summary>
        /// Indica se la tabella è provvista di header.
        /// Di default true.
        /// </summary>
        public bool Header
        {
            get { return _header; }
            set
            {
                _header = value;
                if (_header == false)
                    _headerheight = 0;
            }
        }

        /// <summary>
        /// Indica se l' header della tabella ha un border oppure no.
        /// Di default = true.
        /// </summary>
        public bool ShowBorderHeader
        {
            get { return _showborderheader; }
            set { _showborderheader = value; }
        }

        /// <summary>
        /// Indica se la tabella è provvista di Footer.
        /// Di default = True.
        /// </summary>
        public bool Footer
        {
            get { return _footer; }
            set
            {
                _footer = value;
                if (_footer == false)
                    _footerheight = 0;
            }
        }

        /// <summary>
        ///  Indica se il footer della tabella ha un border oppure no.
        ///  Di default = true.
        /// </summary>
        public bool ShowBorderFooter
        {
            get { return _showborderfooter; }
            set { _showborderfooter = value; }
        }

        /// <summary>
        /// Dimensione del carattere dell'header. E' il fontsize di base definito a seconda dello Style attributo alla tabella.
        /// </summary>
        public float HeaderFontSize
        {
            get { return _headerfontsize; }
            set { _headerfontsize = value; }
        }

        ///// <summary>
        ///// Colore del carattere dell'intestazione della tabella
        ///// </summary>
        //public ceTe.DynamicPDF.CmykColor HeaderFontColor
        //{
        //    get { return _headerfontcolor; }
        //    set { _headerfontcolor = value; }
        //}

        /// <summary>
        /// Ottiene o imposta un booleano che indica se alternare le righe della tabella con uno sfondo bianco e uno grigio.
        /// Di default = true.
        /// </summary>
        public bool AlternateRow
        {
            get { return _alternaterow; }
            set { _alternaterow = value; }
        }

        /// <summary>
        /// Ottiene o imposta un booleano che indica se la tabella conterrà una riga aggiuntiva 
        /// all'inizio della stessa in cui andrà scritta il titolo (TitleRowText).
        /// La riga ha sfondo grigio ed è bordata, è posta sopra l'header della tabella.
        /// Se impostata a true, la proprietà ShowBorderHeader viene automaticamente settata a false.
        /// Di default = false.
        /// </summary>
        public bool TitleRow { get; set; }

        /// <summary>
        /// Ottiene o imposta il testo della riga del titolo della tabella.
        /// </summary>
        public string TitleRowText
        {
            get { return _titlerowtext; }
            set { _titlerowtext = value; }
        }

        /// <summary>
        /// Ottiene o imposta l'altezza del titolo della tabella.
        /// Di default = 20.
        /// </summary>
        public float TitleRowHeight
        {
            get { return _titlerowheight; }
            set { _titlerowheight = value; }
        }

        /// <summary>
        /// Ottiene o imposta il tipo di bordo per il TitleRow della tabella.
        /// Di default = BorderTypeTitleRow.PIENO
        /// </summary>
        public BorderTitleRowType TitleRowBorder
        {
            get { return _titlerowborder; }
            set { _titlerowborder = value; }
        }

        /// <summary>
        /// Ottiene o imposta il valore dello spazio che intercorre tra la fine del TitleRow e l'inizio dell' Header della tabella sottostante.
        /// Se è impostato la SubTitleTable è il valore che intercorre tra la fine della SubTitleTable e l' Header della tabella sottostante.
        /// Di default=10.
        /// </summary>
        public float TitleRowSpace
        {
            get { return _titlerowspace; }
            set { _titlerowspace = value; }
        }

        /// <summary>
        /// Imposta o recupera la TablePDF da disegnare sotto al TitleRow.
        /// </summary>
        public TablePDF SubTitleTable { get; set; }

        /// <summary>
        /// Imposta o recupera la lista di oggetti (ObjectPDF) da disegnare sotto al TitleRow. 
        /// </summary>
        public List<ObjectPDF> SubTitleElements { get; set; }

        /// <summary>
        /// Imposta o recupera il valore del margine sinistro e destro, la distanza tra
        /// il bordo sinistro e destro dal testo della prima e ultima colonna.
        /// Di default = 5.
        /// </summary>
        public float Margin
        {
            get { return _margin; }
            set { _margin = value; }
        }

        /// <summary>
        /// Indica se il contenuto della tabella ha un border oppure no.
        /// Di default = false.
        /// </summary>
        public bool ShowBorderContent { get; set; }

        /// <summary>
        /// Imposta o recupera un booleano che indica se la tabella può effettuare il salto pagina.
        /// Se impostato a false la tabella sarà stampata in un'unica pagina.
        /// Di default = true.
        /// </summary>
        public bool PageBreak
        {
            get { return _pagebreak; }
            set { _pagebreak = value; }
        }

        /// <summary>
        /// Imposta o recupera la lista di note da associare alla tabella.
        /// </summary>
        public List<TableNotePDF> Notes
        {
            get { return _notes; }
            set { _notes = value; }
        }

        /// <summary>
        /// Imposta o recupera lo spazio aggiuntivo sotto la tabella.
        /// Di default = 0.
        /// </summary>
        public float AdditionalSpaceBelow { get; set; }

        /// <summary>
        /// Imposta o ottiene un booleano che indica se mostrare le note aggiunte alla tabella in fondo alla pagina per ogni pagina quando questa effettua dei salti pagina.
        /// Di default=false.
        /// </summary>
        public bool ShowNotesFooterPageForAllPages { get; set; }

        /// <summary>
        /// Imposta o recupera l'altezza della riga.
        /// </summary>
        public float RowHeight
        {
            get { return _rowheight; }
            set { _rowheight = value; }
        }

        public List<float> SpecifiedRowHeights
        {
            get { return specifiedRowHeights; }
            set { specifiedRowHeights = value; }
        }

        ///// <summary>
        ///// Recupera un bool che indica se l'altezza di ogni riga della tabella è fissa a RowHeight.
        ///// Di default: Style.ConsulenzaBase = TRUE, Style.Immobiliare e Style.ConsulenzaUnica = FALSE.
        ///// </summary>
        //public bool FixedRowHeight
        //{
        //    get { return _style == Style.ConsulenzaBase; }
        //}

        /// <summary>
        /// Imposta o recupera l'altezza minima delle righe della tabella.
        /// Se 0 non viene considerata.
        /// Di default 0.
        /// </summary>
        public float MinimumRowHeight
        {
            get { return _minimumrowheight; }
            set { _minimumrowheight = value; }
        }

        /// <summary>
        /// Bool che indica se mostrare una linea orizzontale all'ultima riga della tabella prima del salto pagina.
        /// Di default = false.
        /// </summary>
        public bool ShowBorderLastLineInPageBreak
        {
            get { return _style == Style.Immobiliare || _showborderlastlineinpagebreak; }
            set { _showborderlastlineinpagebreak = value; }
        }

        public float YOffset
        {
            get
            {
                return _yoffset;
            }
            set
            {
                _yoffset = value;
            }
        }
        public List<int> RowsIndexesThatIgnoreColumnBackgroundColor { get; set; }
        public List<int> IndexesOfSeparatorsToIgnore { get; set; }
        public List<int> IndexesOfRowLinesToIgnoreSeparators { get; set; }
        #endregion

        #region Costruttori

        /// <summary>
        /// Costruttore
        /// </summary>
        public TablePDF()
        {
            Style = OBJ_PDF.Style.ConsulenzaBase; // Di Default Style.ConsulenzaBase
            ObjectType = ObjectTypePdf.TABLE;
            TableTitle = null;
            ShowNotesFooterPageForAllPages = false;
            AdditionalSpaceBelow = 0;
            ShowBorderContent = false;
            SubTitleElements = null;
            SubTitleTable = null;
            TitleRow = false;
            ShowSeparationLines = false;
            ShowBorderLastLine = false;
            IndexesOfSeparatorsToIgnore = new List<int>();
            RowsIndexesThatIgnoreColumnBackgroundColor = new List<int>();
            IndexesOfRowLinesToIgnoreSeparators = new List<int>();
        }

        /// <summary>
        /// Costruttore
        /// </summary>
        public TablePDF(float x)
            : this()
        {
            X = x;
        }

        ///// <summary>
        ///// Costruttore.
        ///// Verrà disegnata una tabella a partire dal "datasource" passato in input.
        ///// La proprietà "cells" della tabella non deve essere impostata in quanto verranno stampate le colonne del "datasource" che coincidono con le colonne (proprietà "columns").
        ///// Devono essere definite le colonne tramite la proprietà "columns".
        ///// </summary>        
        ///// <param name="x">x a partire dalla quale verrà disegnata la tabella.</param>
        ///// <param name="datasource">Fonte dati</param>
        //public TablePDF(float x, DataTable datasource)
        //    : this(x)
        //{
        //    _datasource = datasource;            
        //    _rowscount = datasource.Rows.Count;
        //    X = x;

        //    _row = new RowPDF[datasource.Rows.Count];
        //    _cells = new Cell[datasource.Columns.Count, datasource.Rows.Count];
        //    _footercell = new Cell[datasource.Columns.Count];

        //    for (int col = 0; col < datasource.Columns.Count; col++)
        //    {
        //        for (int row = 0; row < datasource.Rows.Count; row++)
        //        {
        //            _cells[col, row] = new Cell(string.Empty);
        //            _row[row] = new RowPDF();
        //        }
        //        _footercell[col] = new Cell(string.Empty);
        //    }
        //}

        /// <summary>
        /// Costruttore.
        /// Viene impostato sull'intera riga il FontBold in funzione del booleano impostato nella colonna "FontBold" del datasource.
        /// Viene rimpiazzato sull'intera riga i valori a 0 con il carattere impostato nella colonna "ReplaceIfZero" del datasource.
        /// </summary>
        /// <param name="x">x a partire dalla quale verrà disegnata la tabella.</param>
        /// <param name="datasource">Fonte dati</param>        
        public TablePDF(float x, DataTable datasource)
            : this(x)
        {
            _datasource = datasource;
            _rowscount = datasource.Rows.Count;
            X = x;

            _row = new RowPDF[datasource.Rows.Count];
            _cells = new Cell[datasource.Columns.Count, datasource.Rows.Count];

            _footercells = new Cell[datasource.Columns.Count, 1];

            for (int col = 0; col < datasource.Columns.Count; col++)
            {
                for (int row = 0; row < datasource.Rows.Count; row++)
                {
                    var cell = new Cell(string.Empty);

                    if (_datasource.Columns.Contains("FontBold"))
                        cell.FontBold = Convert.ToBoolean(_datasource.Rows[row]["FontBold"]);

                    if (_datasource.Columns.Contains("ReplaceIfZero"))
                        cell.ReplaceIfZero = _datasource.Rows[row]["ReplaceIfZero"].ToString();

                    _cells[col, row] = cell;
                    _row[row] = new RowPDF();
                }

                _footercells[col, 0] = new Cell(string.Empty) { BackgroundColor = ColorPDF.ConsulenzaUnica_Grigio_SfondoColonnaHeaderFooterTabella };
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="x"></param>
        /// <param name="datasource"></param>
        /// <param name="footerdatasource"></param>
        public TablePDF(float x, DataTable datasource, DataTable footerdatasource)
            : this(x, datasource)
        {
            FooterDatasource = footerdatasource;
            _footercells = new Cell[footerdatasource.Columns.Count, footerdatasource.Rows.Count];

            for (int col = 0; col < footerdatasource.Columns.Count; col++)
            {
                for (int row = 0; row < footerdatasource.Rows.Count; row++)
                {
                    var cell = new Cell(string.Empty);

                    if (footerdatasource.Columns.Contains("FontBold"))
                        cell.FontBold = Convert.ToBoolean(footerdatasource.Rows[row]["FontBold"]);

                    if (footerdatasource.Columns.Contains("ReplaceIfZero"))
                        cell.ReplaceIfZero = footerdatasource.Rows[row]["ReplaceIfZero"].ToString();

                    if (footerdatasource.Columns.Contains("BackgroundGray"))
                    {
                        var boolBackgroundGray = Convert.ToBoolean(footerdatasource.Rows[row]["BackgroundGray"]);
                        cell.BackgroundColor = boolBackgroundGray ? ColorPDF.Standard_Grigio_SfondoColonnaTabella : ColorPDF.Bianco;
                    }

                    _footercells[col, row] = cell;
                }
            }
        }


        /// <summary>
        /// Costruttore.
        /// La tabella sarà composta dal numero di colonne e di righe passate in input.
        /// E' necessario valorizzare la proprietà "cells" della tabella per l'assegnazione dei valori
        /// alle singole celle.
        /// Devono essere definite le colonne tramite la proprietà "columns".
        /// </summary>
        /// <param name="x">x a partire dalla quale verrà disegnata la tabella.</param>
        /// <param name="columns">Numero di colonne.</param>
        /// <param name="rows">Numero di righe.</param>       
        public TablePDF(float x, int columns, int rows)
            : this()
        {
            _cells = new Cell[columns, rows];
            //_footercell = new Cell[columns];
            _row = new RowPDF[rows];
            X = x;
            _rowscount = rows;

            for (int col = 0; col < columns; col++)
            {
                for (int row = 0; row < rows; row++)
                {
                    _cells[col, row] = new Cell(string.Empty);
                    _row[row] = new RowPDF();
                }
                //_footercell[col] = new Cell(string.Empty);
            }
        }

        #endregion

        #region Metodi

        /// <summary>
        /// Recupera la larghezza totale della tabella, data dalla somma delle colonne aggiunte ad essa.
        /// </summary>
        /// <returns></returns>
        private float GetWidth()
        {
            return _columns.Aggregate<ColumnPDF, float>(0, (current, col) => current + col.Width);
        }


        /// <summary>
        /// Ritorna l'oggetto che sarà stampato sulla pagina.
        /// </summary>
        /// <returns></returns>
        public override PageElement ToElement()
        {
            return null;
        }

        ///// <summary>
        ///// Converte in DataTable le righe e le colonne aggiunte alla tabella.
        ///// Ritorna un DataTable denominato "ToDataTable".
        ///// </summary>
        ///// <returns></returns>
        //public DataTable ToDataTable()
        //{
        //    DataTable dtReturn = new DataTable("ToDataTable");

        //    foreach (ColumnPDF colonna in _columns)
        //        dtReturn.Columns.Add(colonna.Id, typeof(string));

        //    DataRow drToAdd;

        //    for (int iRiga = 0; iRiga < _rowscount; iRiga++)
        //    {
        //        drToAdd = dtReturn.NewRow();

        //        for (int iColonna = 0; iColonna < _columns.Count; iColonna++)
        //            drToAdd[iColonna] = _cells[iColonna, iRiga].Value;

        //        dtReturn.Rows.Add(drToAdd);
        //    }

        //    return dtReturn;
        //}

        #endregion
    }

    /// <summary>
    /// Rappresenta il tipo della colonna della tabella.
    /// </summary>
    public enum ColumnType
    {
        Testo,
        Immagine,
        Objectpdf,
        Decimale,
        Intero,
        Percentuale
    }

    /// <summary>
    /// Tipo di allineamento orizzontale della colonna.
    /// </summary>
    public enum HorizontalAlignmentType
    {
        Nonimpostato,
        Centrato,
        Destra,
        Sinistra
    }

    /// <summary>
    /// Tipo di allineamento verticale della colonna.
    /// </summary>
    public enum VerticalAlignmentType
    {
        Nonimpostato,
        Alto,
        Centrato,
        Basso
    }

    /// <summary>
    /// Tipo di bordo per il TitleRow dell'oggetto TablePDF
    /// </summary>
    public enum BorderTitleRowType
    {
        Nessuno,
        Pieno
    }

    /// <summary>
    /// Tipo di bordo per la Row dell'oggetto TablePDF
    /// </summary>
    public enum BorderRowType
    {
        Alto,
        Basso,
        Entrambi
    }

    /// <summary>
    /// Rappresenta la singola colonna di una tabella
    /// </summary>
    public class ColumnPDF
    {
        private int _width;

        private bool? _fontbold;
        private float _fontsize = 7;

        private HorizontalAlignmentType _horizontalalignment = HorizontalAlignmentType.Nonimpostato;
        private VerticalAlignmentType _verticalalignment = VerticalAlignmentType.Centrato;

        private string _headertext = string.Empty;
        private VerticalAlignmentType _headerverticalalignment = VerticalAlignmentType.Centrato;
        private bool _headerfontbold = true;
        private List<string> _headergrouptext = new List<string>();
        private bool _headergroupborderline = true;

        private float _scalecolumntypeimage = 1;
        private float _paddingtopimage = 0;
        private bool _visibile = true;
        private float _paddingleft;


        /// <summary>
        /// Costruttore
        /// </summary>
        /// <param name="id">Identificativo della colonna</param>
        /// <param name="width">Larghezza della colonna</param>
        public ColumnPDF(string id, int width)
        {
            ForceStyleFontColor = false;
            ForceStyleFontBold = false;
            HeaderFontColor = null;
            HeaderBackgroundColor = null;
            HeaderTextVerticalDirection = false;
            HeaderFontSize = 0; // Viene impostata di default in base alla HeaderFontSize della relativa TablePDF. 
            FontColor = null;
            BackgroundColor = null;
            BackgroundGray = false;
            DeltaYContent = 0;
            HeaderGroupTextDeltaX = 0;
            HeaderPaddingLeft = 0;
            PaddingRight = 0;
            HeaderGroupWidth = 0;
            HeaderGroupTextDeltaY = 0;
            HeaderGroupScaleImage = 1;
            Id = id;
            _width = width;
        }

        /// <summary>
        /// Costruttore
        /// </summary>
        /// <param name="id">Identificativo della colonna</param>
        /// <param name="width">Larghezza della colonna</param>
        /// <param name="horizontalalignment">Allineamento Orizzontale della colonna</param>
        public ColumnPDF(string id, int width, HorizontalAlignmentType horizontalalignment)
            : this(id, width)
        {
            _horizontalalignment = horizontalalignment;
        }

        /// <summary>
        /// Costruttore
        /// </summary>
        /// <param name="id">Identificativo della colonna</param>
        /// <param name="width">Larghezza della colonna</param>
        /// <param name="horizontalalignment">Allineamento orizzontale della colonna</param>
        /// <param name="backgroundgray">Se true disegna uno sfondo grigio sull'intera colonna</param>
        public ColumnPDF(string id, int width, HorizontalAlignmentType horizontalalignment, bool backgroundgray)
            : this(id, width, horizontalalignment)
        {
            BackgroundGray = backgroundgray;
        }

        /// <summary>
        /// Costruttore
        /// </summary>
        /// <param name="id">Identificativo della colonna</param>
        /// <param name="width">Larghezza della colonna</param>
        /// <param name="horizontalalignment">Allineamento orizzontale della colonna</param>
        /// <param name="backgroundgray">Se true disegna uno sfondo grigio sull'intera colonna</param>
        /// <param name="fontbold">Se true il testo dell'intera colonna viene scritto in grassetto</param>
        public ColumnPDF(string id, int width, HorizontalAlignmentType horizontalalignment, bool backgroundgray, bool fontbold)
            : this(id, width, horizontalalignment, backgroundgray)
        {
            _fontbold = fontbold;
        }

        /// <summary>
        /// Costruttore
        /// </summary>
        /// <param name="id">Identificativo della colonna</param>
        /// <param name="width">Larghezza della colonna</param>
        /// <param name="horizontalalignment">Allineamento orizzontale della colonna</param>
        /// <param name="backgroundgray">Se true disegna uno sfondo grigio sull'intera colonna</param>
        /// <param name="fontbold">Se true il testo dell'intera colonna viene scritto in grassetto</param>
        /// <param name="fontsize">Dimensione del carattere con cui viene scritto il testo sull'intera colonna</param>
        public ColumnPDF(string id, int width, HorizontalAlignmentType horizontalalignment, bool backgroundgray, bool fontbold, int fontsize)
            : this(id, width, horizontalalignment, backgroundgray, fontbold)
        {
            _fontsize = fontsize;
        }

        /// <summary>
        /// Costruttore
        /// </summary>
        /// <param name="id">Identificativo della colonna</param>
        /// <param name="width">Larghezza della colonna</param>
        /// <param name="horizontalalignment">Allineamento orizzontale della colonna</param>
        /// <param name="backgroundgray">Se true disegna uno sfondo grigio sull'intera colonna</param>
        /// <param name="fontbold">Se true il testo dell'intera colonna viene scritto in grassetto</param>
        /// <param name="fontsize">Dimensione del carattere con cui viene scritto il testo sull'intera colonna</param>
        /// <param name="columntype">Tipo di colonna</param>
        public ColumnPDF(string id, int width, HorizontalAlignmentType horizontalalignment, bool backgroundgray, bool fontbold, int fontsize, ColumnType columntype)
            : this(id, width, horizontalalignment, backgroundgray, fontbold, fontsize)
        {
            TipoColonna = columntype;
        }

        /// <summary>
        /// Costruttore
        /// </summary>
        /// <param name="id">Identificativo della colonna</param>
        /// <param name="width">Larghezza della colonna</param>
        /// <param name="horizontalalignment">Allineamento orizzontale della colonna</param>
        /// <param name="backgroundgray">Se true disegna uno sfondo grigio sull'intera colonna</param>
        /// <param name="fontbold">Se true il testo dell'intera colonna viene scritto in grassetto</param>
        /// <param name="fontsize">Dimensione del carattere con cui viene scritto il testo sull'intera colonna</param>
        /// <param name="columntype">Tipo di colonna</param>
        /// <param name="columnnamedatasource">Nome della colonna del datasource a cui associare la colonna</param>
        /// <param name="headertext">Testo dell'header della colonna. Se specificato il valore contenuto in "columnnamedatasource" viene rimpiazzato da questo valore.</param>
        public ColumnPDF(string id, int width, HorizontalAlignmentType horizontalalignment, bool backgroundgray, bool fontbold, int fontsize, ColumnType columntype, string columnnamedatasource, string headertext)
            : this(id, width, horizontalalignment, backgroundgray, fontbold, fontsize, columntype)
        {
            Name = columnnamedatasource;
            _headertext = headertext;
        }

        /// <summary>
        /// Costruttore
        /// </summary>
        /// <param name="id">Identificativo della colonna</param>
        /// <param name="width">Larghezza della colonna</param>
        /// <param name="horizontalalignment">Allineamento orizzontale della colonna</param>
        /// <param name="backgroundgray">Se true disegna uno sfondo grigio sull'intera colonna</param>
        /// <param name="fontbold">Se true il testo dell'intera colonna viene scritto in grassetto</param>
        /// <param name="fontsize">Dimensione del carattere con cui viene scritto il testo sull'intera colonna</param>
        /// <param name="columntype">Tipo di colonna</param>
        /// <param name="columnnamedatasource">Nome della colonna del datasource a cui associare la colonna</param>
        /// <param name="headertext">Testo dell'header della colonna. Se specificato il valore contenuto in "colonnadatasource" viene rimpiazzato da questo valore.</param>
        /// <param name="headertextpaddingleft">Spostamento a destra o a sinistra (a seconda se positivo o negativo) del valore attribuito alla proprietà dell'intestazione.</param>
        public ColumnPDF(string id, int width, HorizontalAlignmentType horizontalalignment, bool backgroundgray, bool fontbold, int fontsize, ColumnType columntype, string columnnamedatasource, string headertext, float headertextpaddingleft)
            : this(id, width, horizontalalignment, backgroundgray, fontbold, fontsize, columntype, columnnamedatasource, headertext)
        {
            HeaderPaddingLeft = headertextpaddingleft;
        }

        /// <summary>
        /// Ottiene o imposta l'identificativo della colonna.
        /// </summary>
        public string Id { get; set; }

        /// <summary>
        /// Ottiene o imposta la larghezza della colonna.
        /// </summary>
        public int Width
        {
            get { return _width; }
            set { _width = value; }
        }

        /// <summary>
        /// Dimensione in scala di ciascuna immagine che verrà stampata nella colonna di tipo immagine.
        /// Di default = 1.
        /// </summary>
        public float ScaleColumnTypeImage
        {
            get { return _scalecolumntypeimage; }
            set { _scalecolumntypeimage = value; }
        }

        public float PaddingTopImage
        {
            get { return _paddingtopimage; }
            set { _paddingtopimage = value; }
        }

        /// <summary>
        /// Indica se il testo contenuto nella colonna sarà in grassetto oppure no.
        /// </summary>
        public bool? FontBold
        {
            get { return _fontbold; }
            set { _fontbold = value; }
        }

        /// <summary>
        /// Ottiene o imposta la dimensione del font della colonna.
        /// Se non impostato = 7.
        /// </summary>
        public float FontSize
        {
            get { return _fontsize; }
            set { _fontsize = value; }
        }

        /// <summary>
        /// Imposta o recupera il colore del carattere della colonna.
        /// </summary>
        public ColorPDF FontColor { get; set; }

        /// <summary>
        /// Indica se lo sfondo della colonna della tabella deve essere grigio.
        /// Lo sfondo verrà applicato all'intera colonna della tabella.
        /// </summary>
        public bool BackgroundGray { get; set; }

        /// <summary>
        /// Recupera o imposta il colore di sfondo della colonna della tabella.
        /// Di default = null (bianco)
        /// </summary>
        public ColorPDF BackgroundColor { get; set; }

        /// <summary>
        /// Ottiene o imposta il nome della colonna.
        /// Corrisponde al campo del DataTable cui la colonna viene associata.
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// Tipo della colonna.
        /// </summary>
        public ColumnType TipoColonna { get; set; }

        /// <summary>
        /// Ottiene e imposta la visibilità della colonna.
        /// </summary>
        public bool Visibile
        {
            get { return _visibile; }
            set { _visibile = value; }
        }

        /// <summary>
        /// Allineamento orizzontale del testo della colonna.
        /// Di default = NONIMPOSTATO
        /// </summary>
        public HorizontalAlignmentType HorizontalAlignment
        {
            get { return _horizontalalignment; }
            set { _horizontalalignment = value; }
        }

        /// <summary>
        /// Allineamento verticale del testo della colonna.
        /// Di default = AllineamentoVerticale.CENTRATO.
        /// </summary>
        public VerticalAlignmentType VerticalAlignment
        {
            get { return _verticalalignment; }
            set { _verticalalignment = value; }
        }

        /// <summary>
        /// Imposta o recupera la distanza tra il bordo e il contenuto in una colonna allineata a sinistra.
        /// Di default = 0.
        /// </summary>
        public float PaddingLeft
        {
            get { return _paddingleft; }
            set
            {
                _paddingleft = value;
                if (_paddingleft > _width)
                    throw new Exception("Il padding sinistro non può essere maggiore della larghezza della colonna");
            }
        }

        /// <summary>
        /// Imposta o recupera la distanza tra il bordo e il contenuto in una colonna allineata a destra.
        /// Di default = 0.
        /// </summary>
        public float PaddingRight { get; set; }

        /// <summary>
        /// Imposta o recupera il Delta (incremento o decremento) sinistro per il titolo della colonna.
        /// Rappresenta lo spostamento a destra o a sinistra (a seconda se positivo o negativo) del valore attribuito alla HeaderText.
        /// Di default = 0.
        /// </summary>
        public float HeaderPaddingLeft { get; set; }

        /// <summary>
        /// Imposta o recupera il Delta (incremento o decremento) destro per il titolo della colonna.
        /// Rappresenta lo spostamento a destra o a sinistra (a seconda se positivo o negativo) del valore attribuito alla HeaderText.
        /// Di default = 0.
        /// </summary>
        public float HeaderPaddingRight { get; set; }

        /// <summary>
        /// Imposta o recupera il Delta (incremento o decremento) per il titolo della colonna.
        /// Rappresenta lo spostamento a destra o a sinistra (a seconda se positivo o negativo) del valore attribuito allla HeaderGroupText.
        /// Di default = 0.
        /// </summary>
        public float HeaderGroupTextDeltaX { get; set; }

        /// <summary>
        /// Imposta o recupera il Delta (incremento o decremento) per il titolo della colonna.
        /// Rappresenta lo spostamento in alto o in basso (a seconda se positivo o negativo) del valore attribuito allla HeaderGroupText.
        /// Di default = 0.
        /// </summary>
        public float HeaderGroupTextDeltaY { get; set; }


        /// <summary>
        /// Imposta o recupera il Delta (incremento o decremento) per il contenuto della colonna.
        /// Rappresenta lo spostamento in alto o in basso (a seconda se negativo o positivo) del valore in cui sarebbe scritto l'elemento.
        /// Di default = 0.
        /// </summary>
        public float DeltaYContent { get; set; }

        /// <summary>
        /// Ottiene o imposta il testo che verrà scritto sul titolo della colonna.
        /// Il campo del DataTable cui la colonna viene associata verrà sovrascritto da questa proprietà.
        /// </summary>
        public string HeaderText
        {
            get { return _headertext; }
            set { _headertext = value; }
        }

        /// <summary>
        /// Allineamento verticale del testo dell'Header della colonna.
        /// Di default = AllineamentoVerticale.CENTRATO.
        /// </summary>
        public VerticalAlignmentType HeaderVerticalAlignment
        {
            get { return _headerverticalalignment; }
            set { _headerverticalalignment = value; }
        }

        /// <summary>
        /// Imposta o recupera un bool che indica se il testo dell'Header della colonna sarà scritto in verticale.
        /// Di default = false.
        /// </summary>
        public bool HeaderTextVerticalDirection { get; set; }

        /// <summary>
        /// Recupera o imposta il colore di sfondo dell'header della colonna della tabella.
        /// Di default = null (bianco)
        /// </summary>
        public ColorPDF HeaderBackgroundColor { get; set; }

        /// <summary>
        /// Imposta o recupera il colore del carattere dell'header della colonna.
        /// Di default = null (bianco).
        /// </summary>
        public ColorPDF HeaderFontColor { get; set; }

        /// <summary>
        /// Imposta o recupera un bool che indica se il testo dell'Header della colonna è bold.
        /// Di default = true.
        /// </summary>
        public bool HeaderFontBold
        {
            get { return _headerfontbold; }
            set { _headerfontbold = value; }
        }

        /// <summary>
        /// Imposta o recupera la grandezza del testo dell'Header della colonna.
        /// Di default = 9.
        /// </summary>
        public float HeaderFontSize { get; set; }

        /// <summary>
        /// Imposta o recupera una lista di stringhe rappresentanti i testi che saranno scritti nell' header della colonna per una larghezza complessiva definita in HeaderGroupWidth. 
        /// </summary>
        public List<string> HeaderGroupText
        {
            get { return _headergrouptext; }
            set { _headergrouptext = value; }
        }

        /// <summary>
        /// Imposta o recupera il percorso dell'immagine da inserire nel HeaderGroup in sostituzione dell'HeaderGroupText.
        /// </summary>
        public string HeaderGroupPathImage { get; set; }

        /// <summary>
        /// Imposta o recupera la scala dell'immagine definita in HeaderGroupPathImage
        /// </summary>
        public float HeaderGroupScaleImage { get; set; }

        /// <summary>
        /// Imposta o recupera la larghezza su cui scrivere HeaderGroupText.       
        /// </summary>
        public int HeaderGroupWidth { get; set; }

        /// <summary>
        /// Imposta o recupera un bool che indica se scrivere in modalità verticale il HeaderGroupText 
        /// </summary>
        public bool HeaderGroupTextVerticalDirection { get; set; }

        /// <summary>
        /// Imposta o recupera un bool che indica se disegnare una linea di bordo basso quando HeaderGroupText è impostato.
        /// Di default = true.
        /// </summary>
        public bool HeaderGroupBorderLine
        {
            get { return _headergroupborderline; }
            set { _headergroupborderline = value; }
        }

        /// <summary>
        /// Imposta o recupera un bool che indica se forzare l'utilizzo dello stile di FontBold definito a livello di Column.
        /// Se False,lo stile definito viene sovrascritto, in ordine, da quello definito a livello di Cell.
        /// Di default = False.
        /// </summary>
        public bool ForceStyleFontBold { get; set; }

        /// <summary>
        /// Imposta o recupera un bool che indica se forzare l'utilizzo dello stile di FontColor definito a livello di Column.
        /// Se False,lo stile definito viene sovrascritto, in ordine, da quello definito a livello di Cell.
        /// Di default = False.
        /// </summary>
        public bool ForceStyleFontColor { get; set; }
    }

    /// <summary>
    /// Rappresenta la singola cella di una tabella.
    /// </summary>
    public class Cell
    {
        private string _value = string.Empty;
        private bool? _fontbold;
        private string _replaceifzero = string.Empty;

        /// <summary>
        /// Costruttore
        /// </summary>
        public Cell()
        {
            FontColor = null;
            BackgroundColor = null;
            ColSpan = 0;
            ValueObject = null;
            ValueObjectList = new List<ObjectPDF>();
            HorizontalAlignment = HorizontalAlignmentType.Nonimpostato;
            YContentOffset = 0;
            XContentOffset = 0;
        }

        /// <summary>
        /// Costruttore
        /// </summary>
        /// <param name="value">Valore da inserire nella cella.</param>
        public Cell(string value)
            : this()
        {
            _value = value;
        }

        /// <summary>
        /// Imposta o recupera il valore della cella.
        /// Se si imposta il tipo di colonna = IMMAGINE e si assegna a questa proprietà il nome dell'immagine
        /// (ad esempio danger.png), sulla tabella verranno riportate le immagini,altimenti verrà stampato il testo impostato.
        /// </summary>
        public string Value
        {
            get { return _value; }
            set { _value = value; }
        }

        /// <summary>
        /// Imposta o recupera l'ObjectPDF da disegnare nella cella.
        /// Attualmente è possibile renderizzare solamente FormattedTextAreaPDF, RectanglePDF e CirclePDF (altri oggetti non verranno renderizzati).
        /// </summary>
        public ObjectPDF ValueObject { get; set; }

        /// <summary>
        /// Imposta o recupera la lista di ObjectPDF da disegnare nella cella.
        /// Attualmente è possibile renderizzare solamente FormattedTextAreaPDF, RectanglePDF e CirclePDF (altri oggetti non verranno renderizzati).
        /// </summary>
        public List<ObjectPDF> ValueObjectList { get; set; }

        /// <summary>
        /// Imposta o recupera un bool che indica se il testo della cella è bold. 
        /// </summary>
        public bool? FontBold
        {
            get { return _fontbold; }
            set { _fontbold = value; }
        }

        /// <summary>
        /// Imposta o recupera il carattere di sostituzione nel caso il valore di una colonna INTERO o DECIMALE sia uguale a 0.
        /// Valido solo per le colonne di tipo INTERO o DECIMALE.
        /// Di default = string.empty (nessuna sostituzione).
        /// </summary>
        public string ReplaceIfZero
        {
            get { return _replaceifzero; }
            set { _replaceifzero = value; }
        }

        /// <summary>
        /// Imposta o recupera il numero di celle che saranno raggruppate all'interno delle colonne definite per l'oggetto TablePDF.
        /// ColSpan = 2 raggruppa la cella corrente e la successiva.
        /// Di default = 0 (nessun colspan);
        /// </summary>
        public int ColSpan { get; set; }

        /// <summary>
        /// Recupera o imposta il colore di sfondo della cella della tabella.
        /// Di default = null (bianco)
        /// </summary>
        public ColorPDF BackgroundColor { get; set; }

        public ColorPDF HorizontalSeparatorColor { get; set; }

        /// <summary>
        /// Imposta o recupera il colore del carattere della cella.
        /// </summary>
        public ColorPDF FontColor { get; set; }

        /// <summary>
        /// Allineamento orizzontale del testo della cella.
        /// Di default = NonImpostato (viene condiserato l'allineamento definito a livello di ColumnPDF)
        /// </summary>
        public HorizontalAlignmentType HorizontalAlignment { get; set; }

        public float YContentOffset { get; set; }
        public float XContentOffset { get; set; }
    }

    /// <summary>
    /// Rappresenta la singola riga di una tabella
    /// </summary>
    public class RowPDF
    {
        private bool? _fontbold;
        private bool _visible = true;
        private BorderRowType _bordertype = BorderRowType.Entrambi;
        private bool _showborderincolumnimage = true;

        public RowPDF()
        {
            BackgroundColor = null;
            Border = false;
            ForceStyleFontColor = false;
            ForceStyleFontBold = false;
            BackgroundGray = false;
        }

        /// <summary>
        /// Indica se il testo dell'intera riga della tabella sarà grassetto.
        /// </summary>
        public bool? FontBold
        {
            get { return _fontbold; }
            set { _fontbold = value; }
        }

        /// <summary>
        /// Imposta o recupera un booleano che indica se la riga deve essere visualizzata.
        /// Di default=true.
        /// </summary>
        public bool Visible
        {
            get { return _visible; }
            set { _visible = value; }
        }

        /// <summary>
        /// Indica se lo sfondo della riga della tabella deve essere grigio.
        /// Di default=false.
        /// </summary>
        public bool BackgroundGray { get; set; }

        /// <summary>
        /// Recupera o imposta il colore di sfondo della riga della tabella.
        /// Di default = null (bianco)
        /// </summary>
        public ColorPDF BackgroundColor { get; set; }

        /// <summary>
        /// Imposta o recupera il colore del carattere della riga.
        /// Se non impostato viene definito di base in funzione dello Style della tabella.
        /// </summary>
        public ColorPDF FontColor { get; set; }

        /// <summary>
        /// Imposta o recupera un bool che indica se mostare il bordo (una linea in alto e una in basso alla riga).
        /// </summary>
        public bool Border { get; set; }

        /// <summary>
        /// Imposta o recupera il tipo di bordo della riga.
        /// Di default = ENTRAMBI
        /// </summary>
        public BorderRowType BorderType
        {
            get { return _bordertype; }
            set { _bordertype = value; }
        }

        /// <summary>
        /// Imposta o recupera un bool che indica se mostrare il border della riga anche nelle colonne di tipo Immagine.
        /// Di default= true.
        /// </summary>
        public bool ShowBorderInColumnImage
        {
            get { return _showborderincolumnimage; }
            set { _showborderincolumnimage = value; }
        }

        /// <summary>
        /// Imposta o recupera un bool che indica se forzare l'utilizzo dello stile di FontBold definito a livello di Row.
        /// Se False,lo stile definito viene sovrascritto, in ordine, da quello definito a livello di Column e da quello a livello di Cell.
        /// Di default = False.
        /// </summary>
        public bool ForceStyleFontBold { get; set; }

        /// <summary>
        /// Imposta o recupera un bool che indica se forzare l'utilizzo dello stile di FontColor definito a livello di Row.
        /// Se False,lo stile definito viene sovrascritto, in ordine, da quello definito a livello di Column e da quello a livello di Cell.
        /// Di default = False.
        /// </summary>
        public bool ForceStyleFontColor { get; set; }
    }

    /// <summary>
    /// Tipologia di stile di visulizzazione della tabella.
    /// </summary>
    public enum Style
    {
        ConsulenzaBase,
        Immobiliare,
        ConsulenzaUnica
    }
}
