/* Minification failed. Returning unminified contents.
(2,1): run-time error CSS1019: Unexpected token, found '('
(2,11): run-time error CSS1031: Expected selector, found '('
(2,11): run-time error CSS1025: Expected comma or open brace, found '('
(1788,2): run-time error CSS1019: Unexpected token, found '('
(1788,9): run-time error CSS1031: Expected selector, found ')'
(1788,9): run-time error CSS1025: Expected comma or open brace, found ')'
 */

(function ($, undefined) {

    moment.locale('it');
    numeral.locale('it');

    var underConstructionTypes = [TYPE_CONTAINERIZED_GOODS, TYPE_CARBON_FOOTPRINT];

    var timeWords = {
        days: ['giorni', 'giorno'],
        hours: ['ore', 'ora'],
        minutes: ['minuti', 'minuto']
    };

    _.templateSettings.imports = {
        moment: moment,
        numeral: numeral,
        duration: function (min) {
            var res = [];
            
            var time = {
                days: Math.floor(min / 1440),
                hours: Math.floor(min % 1440 / 60),
                minutes: Math.floor(min % 60)
            };
            
            _.each(time, function (tm, k) {
                var i;
                if (tm > 1) {
                    i = 0;
                } else if (tm === 1) {
                    i = 1;
                } else {
                    return;
                }
                res.push(tm.toString() + ' ' + timeWords[k][i]);
            });

            return res.join(' ');
        }
    };

    //Funzioni utili
    function makeColorsArray(length) {
        var colors = [];
        var offset = 6 * Math.random();


        for (var i = 0; i < length; i++) {
            var r, g, b;
            var col = (i / length * 6 + offset) % 6;
            var d = col % 1;

            switch (Math.floor(col)) {
                case 0:
                    r = 1;
                    g = d;
                    b = 0;
                    break;
                case 1:
                    r = 1 - d;
                    g = 1;
                    b = 0;
                    break;
                case 2:
                    r = 0;
                    g = 1;
                    b = d;
                    break;
                case 3:
                    r = 0;
                    g = 1 - d;
                    b = 1;
                    break;
                case 4:
                    r = d;
                    g = 0;
                    b = 1;
                    break;
                case 5:
                    r = 1;
                    g = 0;
                    b = 1 - d;
                    break;
            }
            colors.push([Math.round(255 * r), Math.round(255 * g), Math.round(255 * b)]);
        }

        return _.shuffle(colors);
    }

    function rgbList(colors, alpha) {
        if (alpha !== undefined) {
            return _.map(colors, function (c) {
                return 'rgba(' + c[0] + ',' + c[1] + ',' + c[2] + ',' + alpha + ')';
            });
        } else {
            return _.map(colors, function (c) {
                return 'rgb(' + c[0] + ',' + c[1] + ',' + c[2] + ')';
            });
        }
    }

    function makeApiDeferred(urlOrData) {
        var dfd;

        return function () {
            var self = this;

            if (dfd === undefined) {
                dfd = $.Deferred();

                if (_.isString(urlOrData)) {
                    $.getJSON(urlOrData, function (data) {
                        dfd.resolveWith(self, [data]);
                    });
                } else {
                    dfd.resolveWith(self, [urlOrData]);
                }
            }

            return dfd.promise();
        };
    }

    //TEMPLATES
    var statisticsTmpl = _.template($('#statisticsTmpl').html());
    var statisticsTypesTmpl = _.template($('#statisticsTypesTmpl').html());
    var statisticsParamsTmpl = _.template($('#statisticsParamsTmpl').html());
    var statisticsFiltersTmpl = _.template($('#statisticsFiltersTmpl').html());
    var statisticsDGFiltersTmpl = _.template($('#statisticsDGFiltersTmpl').html());
    var statisticsFiltersTmpl2 = _.template($('#statisticsFiltersTmpl2').html());
    var statisticsResultsTmpl = _.template($('#statisticsResultsTmpl').html());

    //####### STATISTICHE #######
    var statistics = window.statistics = {

        type: START_TYPE,

        data: null,
        total: 0,

        filteredData: null,
        filteredTotal: 0,

        params: {},
        filters: {},
        counters: {},

        //piers: piers,
        //shipTypes: shipTypes,

        getPiers: makeApiDeferred(API_PIERS_URL),
        getShipTypes: makeApiDeferred(API_SHIP_TYPES_URL),
        getHarbors: makeApiDeferred(API_HARBORS_URL),
        getCountries: makeApiDeferred(API_COUNTRIES_URL),
        getContinents: makeApiDeferred(API_CONTINENTS_URL),
        getHandlingTypes: makeApiDeferred([
            { Flag: HANDLING_TYPE_TRANSITO, Name: 'Transito' },
            { Flag: HANDLING_TYPE_IMBARCO, Name: 'Imbarco' },
            { Flag: HANDLING_TYPE_SBARCO, Name: 'Sbarco' },
            { Flag: HANDLING_TYPE_IMBARCO_TRANSHIPMENT, Name: 'Imbarco Transhipment' },
            { Flag: HANDLING_TYPE_SBARCO_TRANSHIPMENT, Name: 'Sbarco Transhipment' }
        ]),

        getAdrClasses: makeApiDeferred([
            { Code: '1', Description: 'Materiali e sostanze esplosive' },
            { Code: '2', Description: 'Gas' },
            { Code: '3', Description: 'Liquidi infiammabili' },
            { Code: '4.1', Description: 'Materie solide infiammabili' },
            { Code: '4.2', Description: 'Materiali e sostanze esplosive' },
            { Code: '4.3', Description: 'Sostanze che, a contatto con l\'acqua, sprigionano gas infiammabili' },
            { Code: '5.1', Description: 'Materie comburenti' },
            { Code: '5.2', Description: 'Perossidi organici' },
            { Code: '6.1', Description: 'Sostanze tossiche' },
            { Code: '6.2', Description: 'Prodotti infettivi' },
            { Code: '7', Description: 'Materiali radioattivi' },
            { Code: '8', Description: 'Materiali corrosivi' },
            { Code: '9', Description: 'Materiali con pericolosita` varia e pericolosi per l\'ambiente' }
        ]),



        init: function (el) {
            var self = this;
            var now = moment();

            self.el = el;
            var $el = self.$el = $(el);

            $el.html(statisticsTmpl());

            self.$statisticsTypes = $el.find('.statistics-types');
            self.$statisticsView = $el.find('.statistics-view');
            self.$statisticsParams = $el.find('.statistics-params');
            self.$statisticsDownload = $el.find('.statistics-download');
            self.$statisticsFilters = $el.find('.statistics-filters');
            self.$statisticsResults = $el.find('.statistics-results');

            //tipi
            self.$statisticsTypes.on('change', 'select', _.bind(self.updateTypes, self));

            self.renderTypes();

            //parametri
            self.params.interval = INTERVAL_MONTH;
            self.params.month = now.month() + 1;
            self.params.semester = self.params.month <= 6 ? 1 : 2;
            self.params.year = now.year();

            self.$statisticsParams.data('activeParams', $.extend({}, self.params));


            self.$statisticsDownload.on('click', '.download-button', _.bind(self.downloadData, self));

            self.$statisticsParams.on('change', 'select', _.bind(self.updateParams, self))
            /*.on('click', 'button', function (ev) {
                switch (ev.target.name) {
                    case 'reset':
                        self.params = $.extend({}, self.$statisticsParams.data('activeParams'));
                        self.renderParams();
                        break;
                }
            })*/;

            self.renderParams();


            //filtri
            $.when(self.getShipTypes(), self.getPiers(), self.getHandlingTypes(), self.getAdrClasses()).done(function (shipTypes, piers, handlingTypes, adrClasses) {
                var mapFn = function () { return arguments[1]; };
                self.filters.piers = _.map(piers, mapFn);
                self.filters.shipTypes = _.map(shipTypes, mapFn);
                self.filters.handlingTypes = _.map(handlingTypes, mapFn);
                self.filters.adrClasses = _.map(adrClasses, mapFn);
                
                self.$statisticsFilters.data('activeFilters', $.extend({}, self.params));

                self.$statisticsFilters.on('change', 'select', _.bind(self.updateFilters, self));

                if (_.indexOf(underConstructionTypes, self.type) < 0) {
                    self.renderFilters().then(self.loadData).then(function () {
                        self.filterData().then(self.renderResults());
                        self.init = $.noop;
                    });
                } else {
                    self.$statisticsView.addClass('under-construction');
                }
            });
        },

        renderTypes: function () {
            this.$statisticsTypes.html(statisticsTypesTmpl({ type: this.type }));
        },

        updateTypes: function (ev) {
            var self = this;

            self.$statisticsView.removeClass('under-construction');

            self.type = Number($(ev.target).val());
            self.renderTypes();

            if (_.indexOf(underConstructionTypes, self.type) < 0) {

                self.$statisticsView.addClass('loading');

                self.loadData().then(function () {
                    self.filterData().then(self.renderResults());
                });
            } else {
                self.$statisticsView.addClass('under-construction');
            }
        },

        renderParams: function () {
            this.$statisticsParams.html(statisticsParamsTmpl({ params: this.params }));
        },

        updateParams: function () {
            var self = this;

            if (_.indexOf(underConstructionTypes, self.type) < 0) {
                self.$statisticsParams.find('select').each(function (i, select) {
                    var $select = $(select);
                    var name = $select.attr('name');
                    var value = Number($select.val());

                    self.params[name] = value;
                });

                self.renderParams();

                self.loadData().then(function () {
                    self.filterData().then(self.renderResults());
                });
            }
        },

        renderFilters: function () {
            var self = this;
            var dfd = $.Deferred();
            var defds;

            if (self.type === TYPE_DANGEROUS_GOODS) {
                defds = [self.getHandlingTypes(), self.getAdrClasses()];
            } else {
                defds = [self.getShipTypes(), self.getPiers()];
            }

            $.when.apply(self, defds).done(function (d1, d2) {

                var tmpl;
                var data;
                var filterStatus;

                if (self.type === TYPE_DANGEROUS_GOODS) {
                    tmpl = statisticsDGFiltersTmpl;

                    data = {
                        handlingTypes: d1,
                        adrClasses: d2
                    };

                    filterStatus = self.filterStatus({
                        handlingTypes: d1.length,
                        adrClasses: d2.length
                    });
                } else {
                    tmpl = statisticsFiltersTmpl;

                    data = {
                        shipTypes: d1,
                        piers: d2
                    };

                    filterStatus = self.filterStatus({
                        shipTypes: d1.length,
                        piers: d2.length
                    });
                }


                self.$statisticsFilters
                    .html(tmpl(_.extend({
                        type: self.type,
                        filters: self.filters,
                        count: function (name, id) {
                            var count = 0;
                            var txt;

                            if (self.counters[name] === undefined || self.counters[name][id] === undefined) {
                                txt = ' data-count="0"';
                            } else {
                                cnt = self.counters[name][id];
                                txt = ' data-count="' + cnt + '" data-subtext="' + templates.berthCount({ count: cnt }) + '"';
                            }
                            return txt;
                        },
                        filterStatus: filterStatus
                    }, data)))

                    .find('select').each(function (i, select) {
                        $(select).selectpicker({
                            actionsBox: true,
                            deselectAllText: 'Deseleziona tutti',
                            noneSelectedText: 'Nessuno selezionato',
                            selectAllText: 'Seleziona tutti',
                            style: 'btn-' + filterStatus(select.name)
                        });
                    })

                    .on('shown.bs.select', function (ev) {
                        $(ev.target).parent().find('.dropdown-header span').each(function (i, header) {
                            var $header = $(header);
                            $header.html($header.text());
                        });
                    });

                dfd.resolveWith(self);
            });

            return dfd;
        },

        renderResults: function () {
            var self = this;
            var dfd = $.Deferred();
            var deferreds;


            if (self.type === TYPE_DANGEROUS_GOODS) {
                deferreds = [self.getHandlingTypes(), self.getAdrClasses()];
            } else {
                deferreds = [self.getShipTypes(), self.getPiers()];
                if (_.indexOf([TYPE_PROVENANCE_PORT, TYPE_DESTINATION_PORT], self.type) >= 0) {
                    deferreds.push(self.getHarbors(), self.getCountries(), self.getContinents());
                }
            }


            $.when.apply($, deferreds).then(function () {

                self.$statisticsView.removeClass('loading');

                var startKey, prevKey, prop;
                var charts = {};

                var minShowPercentage = Math.max(self.filteredTotal * 0.01, 1);
                var maxOthersShown = 20;

                var data = _.cloneDeep(self.filteredData);
                var p = _.cloneDeep(self.params);

                var shipTypes, piers, harbors, countries, continents, handlingTypes, adrClasses;

                if (self.type === TYPE_DANGEROUS_GOODS) {
                    handlingTypes = _.keyBy(arguments[0], 'Flag');
                    adrClasses = _.keyBy(arguments[1], 'Code');
                } else {
                    shipTypes = _.keyBy(arguments[0], 'ID');

                    if (self.type !== TYPE_PERMANENCE_AT_ANCHOR) {
                        piers = _.keyBy(arguments[1], 'ID');
                    }

                    if (_.indexOf([TYPE_PROVENANCE_PORT, TYPE_DESTINATION_PORT], self.type) >= 0) {
                        harbors = _.keyBy(arguments[2], 'ID');
                        countries = _.keyBy(arguments[3], 'Code');
                        continents = _.keyBy(arguments[4], 'ID');
                    }
                }

                switch (self.type) {
                    case TYPE_BERTHS:
                    case TYPE_PROVENANCE_PORT:
                    case TYPE_DESTINATION_PORT:
                        prop = 'Count';
                        break;
                    case TYPE_SHIPS_AGE:
                        prop = 'Age';
                        break;
                    case TYPE_GROSS_TONNAGE:
                        prop = 'GrossTonnage';
                        break;
                    case TYPE_NET_TONNAGE:
                        prop = 'NetTonnage';
                        break;
                    case TYPE_PIER_PERMANENCE:
                    case TYPE_PERMANENCE_AT_ANCHOR:
                        prop = 'Permanence';
                        break;
                    case TYPE_DANGEROUS_GOODS:
                        prop = 'Weight';
                }

                if (TYPE_BERTHS === self.type) {

                    //timeline
                    charts.timeline = {
                        data: [],
                        labels: [],
                        colors: []
                    };

                    startKey = p.interval === INTERVAL_SEMESTER && p.semester === 2 ? moment(p.year).month(6).date(1).week() : 1;
                    prevKey = startKey;

                    _.each(_.groupBy(data, 'DateFragment'), function (f, k) {
                        var key = Number(k);

                        for (prevKey; prevKey <= key; prevKey++) {
                            if (p.interval === 2) {
                                charts.timeline.labels.push(moment().month(prevKey - 1).format('MMMM'));
                            } else {
                                charts.timeline.labels.push(prevKey);
                            }
                        }

                        charts.timeline.data[k - startKey] = _.sumBy(f, prop);
                    });

                    _.each(charts.timeline.labels, function (f, k) {
                        charts.timeline.data[k] = charts.timeline.data[k] || 0;
                    });

                    charts.timeline.colors = makeColorsArray(1);

                    //var prepareData = function (field) {
                    //    //piers
                    //    var dfd = $.Deferred();

                    //    var self = this;

                    //    var result = {
                    //        data: [],
                    //        colors: [],
                    //        others: [],
                    //        othersSum: 0
                    //    };

                    //    _.each(_.groupBy(data, field, function (p, id) {
                    //        var sum = _.sumBy(p, prop);
                    //        var coll = result.data;

                    //        if (sum <= minShowPercentage) {
                    //            result.othersSum += sum;
                    //            coll = result.others;
                    //        }
                    //        coll.push({
                    //            label: piers[id].Name,
                    //            sum: sum
                    //        });
                    //    }));

                    //    result.data = _.orderBy(result.data, 'sum', 'desc');

                    //    if (result.othersSum > 0) {
                    //        result.data.push({
                    //            label: '',
                    //            sum: result.othersSum
                    //        });

                    //        var more = result.others.length > maxOthersShown;

                    //        result.others = _.map(_.slice(_.orderBy(result.others, 'sum', 'desc'), 0, maxOthersShown), function (p) {
                    //            return 'Ormeggio ' + p.label + ': ' + p.sum + ' ' + (p.sum === 1 ? 'accosto' : 'accosti');
                    //        });

                    //        if (more) {
                    //            result.others.push('(...)');
                    //        }
                    //    }

                    //    result.colors = makeColorsArray(result.data.length);

                    //    dfd.resolveWith(result);

                    //    return dfd;
                    //};

                    //piers
                    charts.piers = {
                        data: [],
                        colors: [],
                        others: [],
                        othersSum: 0
                    };

                    _.each(_.groupBy(data, 'PierID'), function (p, id) {
                        var sum = _.sumBy(p, prop);
                        var coll = charts.piers.data;

                        if (sum <= minShowPercentage) {
                            charts.piers.othersSum += sum;
                            coll = charts.piers.others;
                        }
                        coll.push({
                            label: piers[id].Name,
                            sum: sum
                        });
                    });

                    charts.piers.data = _.orderBy(charts.piers.data, 'sum', 'desc');

                    if (charts.piers.othersSum > 0) {
                        charts.piers.data.push({
                            label: '',
                            sum: charts.piers.othersSum
                        });

                        var more = charts.piers.others.length > maxOthersShown;

                        charts.piers.others = _.map(_.slice(_.orderBy(charts.piers.others, 'sum', 'desc'), 0, maxOthersShown), function (p) {
                            return 'Ormeggio ' + p.label + ': ' + p.sum + ' ' + (p.sum === 1 ? 'accosto' : 'accosti');
                        });

                        if (more) {
                            charts.piers.others.push('(...)');
                        }
                    }

                    charts.piers.colors = makeColorsArray(charts.piers.data.length);

                    //ship types
                    charts.shipTypes = {
                        data: [],
                        colors: [],
                        others: [],
                        othersSum: 0
                    };

                    _.each(_.groupBy(data, 'ShipTypeID'), function (p, id) {
                        var sum = _.sumBy(p, prop);
                        var coll = charts.shipTypes.data;

                        if (sum <= minShowPercentage) {
                            charts.shipTypes.othersSum += sum;
                            coll = charts.shipTypes.others;
                        }

                        coll.push({
                            label: shipTypes[id].Name,
                            sum: sum
                        });
                    });

                    charts.shipTypes.data = _.orderBy(charts.shipTypes.data, 'sum', 'desc');

                    if (charts.shipTypes.othersSum > 0) {
                        charts.shipTypes.data.push({
                            label: '',
                            sum: charts.shipTypes.othersSum
                        });

                        more = charts.shipTypes.others.length > maxOthersShown;

                        charts.shipTypes.others = _.map(_.slice(_.orderBy(charts.shipTypes.others, 'sum', 'desc'), 0, maxOthersShown), function (t) {
                            return t.label + ': ' + t.sum + ' ' + (t.sum === 1 ? 'accosto' : 'accosti');
                        });

                        if (more) {
                            charts.shipTypes.others.push('(...)');
                        }
                    }

                    charts.shipTypes.colors = makeColorsArray(charts.shipTypes.data.length);

                    //RENDER

                    self.$statisticsResults.html(statisticsResultsTmpl({
                        type: self.type,
                        params: self.params,
                        count: self.filteredTotal,
                        filteredResult: self.filteredTotal,
                        globalResult: self.total,
                        periodTmpl: templates.period[self.params.interval]
                    }));

                    if (self.filteredData.length) {

                        new Chart($(document.getElementById('timelineChartCanvas')).get(0).getContext('2d'), {
                            type: 'line',
                            data: {
                                labels: charts.timeline.labels,
                                datasets: [{
                                    label: 'Accosti',
                                    data: charts.timeline.data,
                                    fill: true,
                                    backgroundColor: rgbList(charts.timeline.colors, 0.2)[0],
                                    borderColor: rgbList(charts.timeline.colors, 0.8)[0],
                                    lineTension: 0.01
                                }]
                            },
                            options: {
                                legend: { display: false },
                                scales: { yAxes: [{ ticks: { beginAtZero: true } }] },
                                title: {
                                    display: false,
                                    //text: 'Accosti (' + (self.total !== self.filteredTotal ? self.filteredTotal + '/' : '') + self.total + ')'
                                },
                                tooltips: {
                                    enabled: true,
                                    mode: 'single',
                                    callbacks: {
                                        title: function (tooltipItems, data) {
                                            var title;
                                            switch (p.interval) {
                                                case INTERVAL_MONTH:
                                                    title = moment().year(p.year).month(p.month - 1).date(tooltipItems[0].xLabel).format('LL');
                                                    break;
                                                case INTERVAL_SEMESTER:
                                                    title = p.year + ' settimana ' + tooltipItems[0].xLabel;
                                                    break;
                                                case INTERVAL_YEAR:
                                                    title = moment().year(p.year).month(tooltipItems[0].xLabel).format('MMMM YYYY');
                                                    break;
                                            }
                                            return title;
                                        },
                                        label: function (tooltipItems, data) {
                                            return false;
                                        },
                                        afterBody: function (tooltipItems, data) {
                                            return tooltipItems[0].yLabel + ' accosti';
                                        }
                                    }
                                }
                            }
                        });

                        new Chart($('#piersChartCanvas').get(0).getContext('2d'), {
                            type: 'doughnut',
                            data: {
                                labels: _.map(charts.piers.data, 'label'),
                                datasets: [{
                                    data: _.map(charts.piers.data, 'sum'),
                                    backgroundColor: rgbList(charts.piers.colors, 0.5)
                                }]
                            },
                            options: {
                                legend: { display: false },
                                title: {
                                    display: true,
                                    text: templates.results[self.type].title({ by: 'ormeggio' })
                                },
                                tooltips: {
                                    enabled: true,
                                    mode: 'single',
                                    callbacks: {
                                        label: function (item, data) {
                                            var sum = Number(data.datasets[item.datasetIndex].data[item.index]);
                                            var pier = data.labels[item.index];

                                            if (pier === '') {
                                                return 'Altri (' + sum + ')';
                                            } else {
                                                return 'Ormeggio ' + pier + ': ' + sum + ' ' + (sum === 1 ? 'accosto' : 'accosti');
                                            }
                                        },
                                        afterBody: function (items, data) {
                                            if (data.labels[items[0].index] === '') {
                                                return charts.piers.others;
                                            }
                                        }
                                    }
                                }
                            }
                        });


                        new Chart($('#shipTypesChartCanvas').get(0).getContext('2d'), {
                            type: 'pie',
                            data: {
                                labels: _.map(charts.shipTypes.data, 'label'),
                                datasets: [{
                                    data: _.map(charts.shipTypes.data, 'sum'),
                                    backgroundColor: rgbList(charts.shipTypes.colors, 0.5)
                                }]
                            },
                            options: {
                                legend: { display: false },
                                title: {
                                    display: true,
                                    text: templates.results[self.type].title({ by: 'tipo nave' })
                                },
                                tooltips: {
                                    enabled: true,
                                    mode: 'single',
                                    callbacks: {
                                        label: function (item, data) {
                                            var sum = Number(data.datasets[item.datasetIndex].data[item.index]);
                                            var shipType = data.labels[item.index];

                                            if (shipType === '') {
                                                return 'Altri (' + sum + ')';
                                            } else {
                                                return shipType + ': ' + sum + ' ' + (sum === 1 ? 'accosto' : 'accosti');
                                            }
                                        },
                                        afterBody: function (items, data) {
                                            if (data.labels[items[0].index] === '') {
                                                return charts.shipTypes.others;
                                            }
                                        }
                                    }
                                }
                            }
                        });
                    }

                } else if (_.indexOf([TYPE_SHIPS_AGE, TYPE_GROSS_TONNAGE, TYPE_NET_TONNAGE, TYPE_PERMANENCE_AT_ANCHOR, TYPE_PIER_PERMANENCE], self.type) >= 0) {

                    charts.avg = _.meanBy(self.data, prop);
                    charts.filteredAvg = _.meanBy(self.filteredData, prop);

                    charts.piers = {
                        data: [],
                        colors: []
                    };

                    if (self.type !== TYPE_PERMANENCE_AT_ANCHOR) {

                        _.each(_.groupBy(data, 'PierID'), function (p, id) {
                            charts.piers.data.push({
                                label: 'Ormeggio ' + piers[id].Name,
                                avg: _.meanBy(p, prop)
                            });
                        });

                        charts.piers.data = _.orderBy(charts.piers.data, 'avg', 'desc');

                        charts.piers.colors = makeColorsArray(charts.piers.data.length);
                    }

                    charts.shipTypes = {
                        data: [],
                        colors: []
                    };

                    _.each(_.groupBy(data, 'ShipTypeID'), function (p, id) {
                        charts.shipTypes.data.push({
                            label: shipTypes[id].Name,
                            avg: _.meanBy(p, prop)
                        });
                    });

                    charts.shipTypes.data = _.orderBy(charts.shipTypes.data, 'avg', 'desc');

                    charts.shipTypes.colors = makeColorsArray(charts.shipTypes.data.length);

                    //RENDER

                    self.$statisticsResults.html(statisticsResultsTmpl({
                        type: self.type,
                        params: self.params,
                        count: self.total,
                        filteredCount: self.filteredTotal,
                        globalResult: charts.avg,
                        filteredResult: charts.filteredAvg,
                        piersCount: charts.piers.data.length,
                        shipTypesCount: charts.shipTypes.data.length,
                        periodTmpl: templates.period[self.params.interval]
                    }));

                    //creazione Charts

                    if (self.filteredData.length) {

                        if (self.type !== TYPE_PERMANENCE_AT_ANCHOR) {

                            new Chart($('#piersChartCanvas').get(0).getContext('2d'), {
                                type: 'horizontalBar',
                                data: {
                                    labels: _.map(charts.piers.data, 'label'),
                                    datasets: [{
                                        data: _.map(charts.piers.data, 'avg'),
                                        backgroundColor: rgbList(charts.piers.colors, 0.5)
                                    }]
                                },
                                options: {
                                    legend: { display: false },
                                    scales: { xAxes: [{ ticks: { beginAtZero: true } }] },
                                    title: {
                                        display: true,
                                        text: templates.results[self.type].title({ by: 'ormeggio' })
                                    },
                                    tooltips: {
                                        enabled: true,
                                        mode: 'single',
                                        callbacks: {
                                            label: function (item, data) {
                                                return templates.results[self.type].dataLabel({ count: Number(data.datasets[item.datasetIndex].data[item.index]) });
                                            }
                                        }
                                    }
                                }
                            });
                        }

                        new Chart($('#shipTypesChartCanvas').get(0).getContext('2d'), {
                            type: 'horizontalBar',
                            data: {
                                labels: _.map(charts.shipTypes.data, 'label'),
                                datasets: [{
                                    data: _.map(charts.shipTypes.data, 'avg'),
                                    backgroundColor: rgbList(charts.shipTypes.colors, 0.5)
                                }]
                            },
                            options: {
                                legend: { display: false },
                                scales: { xAxes: [{ ticks: { beginAtZero: true } }] },
                                title: {
                                    display: true,
                                    text: templates.results[self.type].title({ by: 'tipo' })
                                },
                                tooltips: {
                                    enabled: true,
                                    mode: 'single',
                                    callbacks: {
                                        label: function (item, data) {
                                            return templates.results[self.type].dataLabel({ count: data.datasets[item.datasetIndex].data[item.index] });
                                        }
                                    }
                                }
                            }
                        });
                    }
                } else if (_.indexOf([TYPE_PROVENANCE_PORT, TYPE_DESTINATION_PORT], self.type) >= 0) {
                    var provDest;
                    switch (self.type) {
                        case TYPE_PROVENANCE_PORT:
                            provDest = "provenienza";
                            break;
                        case TYPE_DESTINATION_PORT:
                            provDest = "destinazione";
                            break;
                    }

                    var harborsCounter = {};
                    var continentsCounter = {};

                    charts.harbors = (function (d) {
                        var dt = _.orderBy(_.map(d, function (p, id) {
                            var harbor = harbors[id];
                            var cc = harbor.CountryCode;
                            var sum = _.sumBy(p, prop);

                            harborsCounter[cc] = (harborsCounter[cc] || 0) + sum;

                            if (continents[id] !== undefined) {
                                continentsCounter[cid] = (continentsCounter[cid] || 0) + sum;
                            }

                            return {
                                label: harbor.Name + ' (' + countries[cc].Name + ')',
                                sum: sum
                            };
                        }), 'sum', 'desc');

                        return {
                            data: dt,
                            colors: makeColorsArray(dt.length)
                        };
                    })(_.groupBy(data, 'HarborID'));

                    charts.countries = (function (d) {
                        var dt = _.orderBy(_.map(d, function (sum, id) {
                            var country = countries[id];
                            var cid = country.ContinentID;


                            if (continents[cid] !== undefined) {
                                continentsCounter[cid] = (continentsCounter[cid] || 0) + sum;
                            } else {
                                console.warn('La nazione "' + country.Name + '" non ha continente.');// evito errori nel caso in cui la nazione non abbia un continente impostato
                            }

                            return {
                                label: country.Name,
                                sum: sum
                            };
                        }), 'sum', 'desc');

                        return {
                            data: dt,
                            colors: makeColorsArray(dt.length)
                        };
                    })(harborsCounter);


                    charts.continents = (function (d) {
                        var dt = _.orderBy(_.map(d, function (sum, id) {
                            return {
                                label: continents[id].Name,
                                sum: sum
                            };
                        }), 'sum', 'desc');

                        return {
                            data: dt,
                            colors: makeColorsArray(dt.length)
                        };
                    })(continentsCounter);


                    self.$statisticsResults.html(statisticsResultsTmpl({
                        type: self.type,
                        params: self.params,
                        count: self.filteredTotal,
                        harborsCount: _.size(charts.harbors.data),
                        filteredResult: self.filteredTotal,
                        globalResult: self.total,
                        periodTmpl: templates.period[self.params.interval]
                    }));

                    new Chart($('#portsChartCanvas').get(0).getContext('2d'), {
                        type: 'horizontalBar',
                        data: {
                            labels: _.map(charts.harbors.data, 'label'),
                            datasets: [{
                                data: _.map(charts.harbors.data, 'sum'),
                                backgroundColor: rgbList(charts.harbors.colors, 0.5)
                            }]
                        },
                        options: {
                            legend: { display: false },
                            scales: { xAxes: [{ ticks: { beginAtZero: true } }] },
                            title: {
                                display: true,
                                text: templates.results[self.type].title({ by: 'porto di ' + provDest })
                            },
                            tooltips: {
                                enabled: true,
                                mode: 'single',
                                callbacks: {
                                    label: function (item, data) {
                                        return data.datasets[item.datasetIndex].data[item.index];
                                    }
                                }
                            }
                        }
                    });

                    new Chart($('#countriesChartCanvas').get(0).getContext('2d'), {
                        type: 'doughnut',
                        data: {
                            labels: _.map(charts.countries.data, 'label'),
                            datasets: [{
                                data: _.map(charts.countries.data, 'sum'),
                                backgroundColor: rgbList(charts.countries.colors, 0.5)
                            }]
                        },
                        options: {
                            legend: { display: false },
                            title: {
                                display: true,
                                text: templates.results[self.type].title({ by: 'nazione' })
                            },
                            tooltips: {
                                enabled: true,
                                mode: 'single',
                                callbacks: {
                                    /*label: function (item, data) {
                                        var sum = Number(data.datasets[item.datasetIndex].data[item.index]);
                                        var pier = data.labels[item.index];

                                        if (pier === '') {
                                            return 'Altri (' + sum + ')';
                                        } else {
                                            return 'Ormeggio ' + pier + ': ' + sum + ' ' + (sum === 1 ? 'accosto' : 'accosti');
                                        }
                                    },
                                    afterBody: function (items, data) {
                                        if (data.labels[items[0].index] === '') {
                                            return charts.piers.others;
                                        }
                                    }*/
                                }
                            }
                        }
                    });


                    new Chart($('#continentsChartCanvas').get(0).getContext('2d'), {
                        type: 'pie',
                        data: {
                            labels: _.map(charts.continents.data, 'label'),
                            datasets: [{
                                data: _.map(charts.continents.data, 'sum'),
                                backgroundColor: rgbList(charts.continents.colors, 0.5)
                            }]
                        },
                        options: {
                            legend: { display: false },
                            title: {
                                display: true,
                                text: templates.results[self.type].title({ by: 'continente' })
                            },
                            tooltips: {
                                enabled: true,
                                mode: 'single',
                                callbacks: {
                                    /*label: function (item, data) {
                                        var sum = Number(data.datasets[item.datasetIndex].data[item.index]);
                                        var shipType = data.labels[item.index];

                                        if (shipType === '') {
                                            return 'Altri (' + sum + ')';
                                        } else {
                                            return shipType + ': ' + sum + ' ' + (sum === 1 ? 'accosto' : 'accosti');
                                        }
                                    },
                                    afterBody: function (items, data) {
                                        if (data.labels[items[0].index] === '') {
                                            return charts.shipTypes.others;
                                        }
                                    }*/
                                }
                            }
                        }
                    });
                } else if (self.type === TYPE_DANGEROUS_GOODS) {


                    charts.adrClasses = (function (d) {
                        var dt = _.orderBy(_.map(d, function (p, id) {
                            var adrClass = adrClasses[id];

                            return {
                                label: 'Classe ' + adrClass.Code,
                                sum: _.sumBy(p, prop) * 0.001
                            };
                        }), 'sum', 'desc');

                        return {
                            data: dt,
                            colors: makeColorsArray(dt.length)
                        };
                    })(_.groupBy(data, 'AdrClass'));

                    charts.handlingTypes = (function (d) {
                        var dt = _.orderBy(_.map(d, function (p, id) {
                            return {
                                label: handlingTypes[id].Name,
                                sum: _.sumBy(p, prop) * 0.001
                            };
                        }), 'sum', 'desc');

                        return {
                            data: dt,
                            colors: makeColorsArray(dt.length)
                        };
                    })(_.groupBy(data, 'Flag'));

                    self.$statisticsResults.html(statisticsResultsTmpl({
                        type: self.type,
                        params: self.params,
                        count: self.filteredTotal,
                        filteredResult: _.sumBy(data, prop) * 0.001,
                        globalResult: _.sumBy(self.data, prop)*0.001,
                        periodTmpl: templates.period[self.params.interval]
                    }));

                    if (self.filteredTotal) {

                        new Chart($('#handlingTypesChartCanvas').get(0).getContext('2d'), {
                            type: 'horizontalBar',
                            data: {
                                labels: _.map(charts.handlingTypes.data, 'label'),
                                datasets: [{
                                    data: _.map(charts.handlingTypes.data, 'sum'),
                                    backgroundColor: rgbList(charts.handlingTypes.colors, 0.5)
                                }]
                            },
                            options: {
                                legend: { display: false },
                                scales: { xAxes: [{ ticks: { beginAtZero: true } }] },
                                title: {
                                    display: true,
                                    text: templates.results[self.type].title({ by: 'tipo movimentazione' })
                                },
                                tooltips: {
                                    enabled: true,
                                    mode: 'single',
                                    callbacks: {
                                        label: function (item, data) {
                                            return templates.results[self.type].dataLabel({ count: data.datasets[item.datasetIndex].data[item.index] });
                                        }
                                    }
                                }
                            }
                        });

                        new Chart($('#adrClassesChartCanvas').get(0).getContext('2d'), {
                            type: 'horizontalBar',
                            data: {
                                labels: _.map(charts.adrClasses.data, 'label'),
                                datasets: [{
                                    data: _.map(charts.adrClasses.data, 'sum'),
                                    backgroundColor: rgbList(charts.adrClasses.colors, 0.5)
                                }]
                            },
                            options: {
                                legend: { display: false },
                                scales: { xAxes: [{ ticks: { beginAtZero: true } }] },
                                title: {
                                    display: true,
                                    text: templates.results[self.type].title({ by: 'classe di rischio' })
                                },
                                tooltips: {
                                    enabled: true,
                                    mode: 'single',
                                    callbacks: {
                                        label: function (item, data) {
                                            return templates.results[self.type].dataLabel({ count: data.datasets[item.datasetIndex].data[item.index] });
                                        }
                                    }
                                }
                            }
                        });
                    }
                }



                dfd.resolveWith(self);
            });
            return dfd;
        },

        updateFilters: function (ev) {
            var self = this;
            var selected = [];
            var name = ev.target.name;
            var $select = $(ev.target);
            var prop = $select.data('prop');
            //var relevantChange = false;


            _.each(_.xorWith($select.val(), self.filters[name], function (a, b) { return Number(a) === Number(b); }), function (_id) {
                var id = Number(_id);

                //if (self.counters[prop][id] > 0) {
                //    relevantChange = true;
                //}
                if (_.indexOf(self.filters[name], id) < 0) {
                    self.filters[name].push(id);
                } else {
                    _.pull(self.filters[name], id);
                }
            });

            $select.selectpicker('setStyle', 'btn-info', 'remove');
            $select.selectpicker('setStyle', 'btn-light', 'remove');
            $select.selectpicker('setStyle', 'btn-warning', 'remove');

            ({
                shipTypes: self.getShipTypes,
                piers: self.getPiers,
                adrClasses: self.getAdrClasses,
                handlingTypes: self.getHandlingTypes
            })[name]().then(function () {
                var lengths = {};

                lengths[name] = _.size(arguments);

                $select.selectpicker('setStyle', 'btn-' + self.filterStatus(lengths)(name));
            });

            //if (relevantChange) {
                self.filterData().then(self.renderResults());
            //}
        },

        loadData: function () {
            var dfd = $.Deferred();
            var self = this;
            var tf;

            switch (self.params.interval) {
                case INTERVAL_MONTH:
                    tf = self.params.year + '-' + self.params.month;
                    break;
                case INTERVAL_SEMESTER:
                    tf = self.params.year + 's' + self.params.semester;
                    break;
                case INTERVAL_YEAR:
                    tf = self.params.year;
                    break;
            }

            $.getJSON(API_URL + '?type=' + self.type + '&period=' + tf, function (data) {
                var filters;

                self.data = data;
                self.counters = {};

                if (self.type === TYPE_DANGEROUS_GOODS) {
                    filters = {
                        adrClass: 'AdrClass',
                        handlingType: 'Flag'
                    }
                } else {
                    filters = { shipType: 'ShipTypeID' };
                    if (self.type !== TYPE_PERMANENCE_AT_ANCHOR) {
                        filters.pier = 'PierID';
                    }
                }

                _.each(filters, function (idf, cn) {
                    var counter = self.counters[cn] = {};

                    _.each(_.groupBy(data, idf), function (dt, id) {
                        counter[id] = _.reduce(dt, function (sum, d) {
                            return sum + (d['Count'] || 1);
                        }, 0);
                    });
                });

                self.renderFilters();

                dfd.resolve();
            });

            return dfd.promise();
        },

        filterData: function () {
            var self = this;
            var filters;
            var dfd = $.Deferred();
            var defds = [];
            
            self.total = 0;
            self.filteredTotal = 0;

            if (self.type === TYPE_DANGEROUS_GOODS) {
                filters = {
                    handlingTypes: ['Flag', 'Flag'],
                    adrClasses: ['AdrClass', 'Code']
                };
                defds.push(self.getHandlingTypes(), self.getAdrClasses());
            } else {
                filters = {
                    shipTypes: ['ShipTypeID', 'ID']
                };
                defds.push(self.getShipTypes());
                defds.push(self.getPiers());

                if (self.type !== TYPE_PERMANENCE_AT_ANCHOR) {
                    filters.piers = ['PierID', 'ID'];
                }
            }

            $.when.apply(self, defds).done(function () {
                var data = {};

                if (self.type === TYPE_DANGEROUS_GOODS) {
                    data.handlingTypes = arguments[0];
                    data.adrClasses = arguments[1];
                } else {
                    data.shipTypes = arguments[0];
                    data.piers = arguments[1];
                }

                self.filteredData = _.filter(self.data, function (dt) {
                    var res = false;
                    var cnt = Number(dt['Count']) || 1;

                    if (_.every(filters, function (k, nm) {
                        var search = {};
                        search[k[1]] = dt[k[0]];

                        var i = _.findIndex(data[nm], search);

                        return _.indexOf(self.filters[nm], _.findIndex(data[nm], search)) >= 0;
                    })) {
                        res = true;
                        self.filteredTotal += cnt;
                    }

                    self.total += cnt;

                    return res;
                });

                dfd.resolveWith(self, self.filteredData);
            });

            return dfd.promise();

        },

        filterStatus: function (lengths) {
            var filters = this.filters;

            return function (name) {
                var l = filters[name].length;

                if (l === 0) {
                    return 'warning';
                } else if (l === lengths[name]) {
                    return 'light';
                } else {
                    return 'info';
                }
            };
        },

        filterCounter: function (prop, id) {
            if (this.counters[prop] === undefined || this.counters[prop][id] === undefined) {
                return '';
            }
            return ' " data-subtext="' + templates.berthCount({ count: this.counters[prop][id] }) + '"';
        },

        downloadData: function (ev) {
            ev.preventDefault();
            var format = ev.target.name;
            var self = this;
            var getSheetData;

            var ws_name;
            var ws_cols;

            var filenameParts = ['statistiche', HARBOR.toLowerCase()];

            switch (self.type) {
                case TYPE_BERTHS:
                    /* make worksheet */
                    filenameParts.push('accosti');
                    ws_name = 'Accosti';

                    getSheetData = Promise.all([_.orderBy(self.data, 'DateFragment'), self.getPiers(), self.getShipTypes()]).then(function (d) {

                        var data = d[0];

                        var head = [];
                        var piers = _.keyBy(d[1], 'ID');
                        var shipTypes = _.keyBy(d[2], 'ID');

                        var sheet = [];
                        
                        switch (self.params.interval) {
                            case INTERVAL_MONTH:
                                head.push('Giorno');
                                break;
                            case INTERVAL_SEMESTER:
                                head.push('Settimana');
                                break;
                            case INTERVAL_YEAR:
                                head.push('Mese');
                                break;
                        }

                        head.push('Terminal', 'Ormeggio', 'Tipo Nave', 'Accosti');

                        wscols = [
                            { wch: 10 },
                            { wch: 30 },
                            { wch: 30 },
                            { wch: 30 },
                            { wch: 10 }
                        ];

                        sheet.push(head);

                        _.forEach(data, function (d) {
                            var s = [];

                            if (self.params.interval === INTERVAL_YEAR) {
                                s.push(moment().month(d.DateFragment - 1).format('MMMM'));
                            } else {
                                s.push(d.DateFragment);
                            }

                            s.push(piers[d.PierID].Terminal || '', piers[d.PierID].Name, shipTypes[d.ShipTypeID].Name, d.Count);

                            sheet.push(s);
                        });

                        return sheet;
                    });

                    break;
                case TYPE_SHIPS_AGE:
                    filenameParts.push('eta-navi');
                    ws_name = 'Eta` navi';

                    getSheetData = Promise.all([self.data, self.getPiers(), self.getShipTypes()]).then(function (d) {
                        var data = d[0];

                        var piers = _.keyBy(d[1], 'ID');
                        var shipTypes = _.keyBy(d[2], 'ID');

                        var sheet = [['Terminal', 'Ormeggio', 'Tipo Nave', 'Eta` (anni)']];

                        wscols = [
                            { wch: 30 },
                            { wch: 30 },
                            { wch: 30 },
                            { wch: 15 }
                        ];

                        _.forEach(data, function (d) {
                            sheet.push([piers[d.PierID].Terminal || '', piers[d.PierID].Name, shipTypes[d.ShipTypeID].Name, d.Age]);
                        });

                        return sheet;
                    });

                    break;
                case TYPE_GROSS_TONNAGE:
                    filenameParts.push('tonnellaggio-lordo');
                    ws_name = 'Tonn. lordo';

                    getSheetData = Promise.all([self.data, self.getPiers(), self.getShipTypes()]).then(function (d) {

                        var data = d[0];

                        var piers = _.keyBy(d[1], 'ID');
                        var shipTypes = _.keyBy(d[2], 'ID');

                        var sheet = [['Terminal', 'Ormeggio', 'Tipo Nave', 'Tonnellaggio lordo']];

                        wscols = [
                            { wch: 30 },
                            { wch: 30 },
                            { wch: 30 },
                            { wch: 25 }
                        ];

                        _.forEach(data, function (d) {
                            sheet.push([piers[d.PierID].Terminal || '', piers[d.PierID].Name, shipTypes[d.ShipTypeID].Name, d.GrossTonnage]);
                        });

                        return sheet;
                    });
                    break;
                case TYPE_NET_TONNAGE:
                    filenameParts.push('tonnellaggio-netto');
                    ws_name = 'Tonn. netto';

                    getSheetData = Promise.all([self.data, self.getPiers(), self.getShipTypes()]).then(function (d) {

                        var data = d[0];

                        var piers = _.keyBy(d[1], 'ID');
                        var shipTypes = _.keyBy(d[2], 'ID');

                        var sheet = [['Terminal', 'Ormeggio', 'Tipo Nave', 'Tonnellaggio netto']];

                        wscols = [
                            { wch: 30 },
                            { wch: 30 },
                            { wch: 30 },
                            { wch: 25 }
                        ];

                        _.forEach(data, function (d) {
                            sheet.push([piers[d.PierID].Terminal || '', piers[d.PierID].Name, shipTypes[d.ShipTypeID].Name, d.NetTonnage]);
                        });

                        return sheet;
                    });
                    break;
                case TYPE_PIER_PERMANENCE:
                    filenameParts.push('permanenza-a-banchina');
                    ws_name = 'Perm. a Banchina';

                    getSheetData = Promise.all([self.data, self.getPiers(), self.getShipTypes()]).then(function (d) {
                        
                        var data = d[0];

                        var piers = _.keyBy(d[1], 'ID');
                        var shipTypes = _.keyBy(d[2], 'ID');

                        var sheet = [['Terminal', 'Ormeggio', 'Tipo Nave', 'Permanenza (minuti)']];

                        wscols = [
                            { wch: 30 },
                            { wch: 30 },
                            { wch: 30 },
                            { wch: 25 }
                        ];

                        _.forEach(data, function (d) {
                            sheet.push([piers[d.PierID].Terminal || '', piers[d.PierID].Name, shipTypes[d.ShipTypeID].Name, d.Permanence]);
                        });

                        return sheet;
                    });
                    break;
                case TYPE_PERMANENCE_AT_ANCHOR:
                    filenameParts.push('permanenza-in-rada');
                    ws_name = 'Perm. in Rada';

                    getSheetData = Promise.all([self.data, self.getShipTypes()]).then(function (d) {

                        var data = d[0];

                        var shipTypes = _.keyBy(d[1], 'ID');

                        var sheet = [['Tipo Nave', 'Permanenza (minuti)']];

                        wscols = [
                            { wch: 30 },
                            { wch: 25 }
                        ];

                        _.forEach(data, function (d) {
                            sheet.push([shipTypes[d.ShipTypeID].Name, d.Permanence]);
                        });

                        return sheet;
                    });
                    break;
                case TYPE_DANGEROUS_GOODS:
                    filenameParts.push('merci-pericolose');
                    ws_name = 'Merci peric.';

                    getSheetData = Promise.all([self.data, self.getAdrClasses(), self.getHandlingTypes()]).then(function (d) {

                        var data = d[0];

                        var adrClasses = _.keyBy(d[1], 'Code');
                        var handlingTypes = _.keyBy(d[2], 'Flag');

                        var sheet = [['Tipo movimentazione', 'Classe di rischio', 'Descrizione', 'Peso (kg)']];

                        wscols = [
                            { wch: 30 },
                            { wch: 25 },
                            { wch: 50 },
                            { wch: 20 }
                        ];

                        _.forEach(data, function (d) {
                            sheet.push([handlingTypes[d.Flag].Name, d.AdrClass, adrClasses[d.AdrClass].Description, d.Weight]);
                        });

                        return sheet;
                    });
                    break;
                case TYPE_PROVENANCE_PORT:
                case TYPE_DESTINATION_PORT:
                    var harborFieldName;
                    if (self.type === TYPE_PROVENANCE_PORT) {
                        filenameParts.push('porto-provenienza');
                        ws_name = 'Porto di prov.';
                        harborFieldName = 'Porto di provenienza';
                    } else {
                        filenameParts.push('porto-destinazione');
                        ws_name = 'Porto di dest.';
                        harborFieldName = 'Porto di destinazione';
                    }

                    getSheetData = Promise.all([self.data, self.getPiers(), self.getShipTypes(), self.getHarbors(), self.getCountries(), self.getContinents()]).then(function (d) {

                        var data = d[0];

                        var piers = _.keyBy(d[1], 'ID');
                        var shipTypes = _.keyBy(d[2], 'ID');
                        var harbors = _.keyBy(d[3], 'ID');
                        var countries = _.keyBy(d[4], 'Code');
                        var continents = _.keyBy(d[5], 'ID');

                        var sheet = [['Terminal', 'Ormeggio', 'Tipo Nave', harborFieldName, 'Nazione', 'Continente', 'Accosti']];

                        wscols = [
                            { wch: 30 },
                            { wch: 30 },
                            { wch: 30 },
                            { wch: 30 },
                            { wch: 15 },
                            { wch: 15 },
                            { wch: 10 }
                        ];

                        _.forEach(data, function (d) {
                            var s = [piers[d.PierID].Terminal || '', piers[d.PierID].Name, shipTypes[d.ShipTypeID].Name];

                            var harbor = harbors[d.HarborID] || {};

                            var country = countries[harbor.CountryCode] || {};

                            var continent = continents[country.ContinentID] || {};


                            s.push(harbor.Name, country.Name, continent.Name, d.Count);

                            sheet.push(s);
                        });

                        return sheet;
                    });
                    break;
            }

            filenameParts.push(self.params.year);

            switch (self.params.interval) {
                case INTERVAL_MONTH:
                    filenameParts.push(self.params.month);
                    ws_name += ' ' + moment().month(self.params.month - 1).format('MMMM') + ' ' + self.params.year;
                    break;
                case INTERVAL_SEMESTER:
                    switch (self.params.semester) {
                        case 1:
                            ' 1� semestre ' + self.params.year;
                            break;
                        case 2:
                            ' 2� semestre ' + self.params.year;
                            break;
                    }
                    filenameParts.push('s' + self.params.semester);
                    break;
                case INTERVAL_YEAR:
                    ws_name += ' anno ' + self.params.year;
                    break;
            }

            getSheetData.then(function (data) {
                var ws = XLSX.utils.aoa_to_sheet(data);

                ws['!cols'] = wscols;

                var wb = XLSX.utils.book_new();

                /* Add the worksheet to the workbook */
                XLSX.utils.book_append_sheet(wb, ws, ws_name);

                switch (format) {
                    case 'xlsx':
                        XLSX.writeFile(wb, filenameParts.join('-') + '.xlsx', { type: 'xlsx' });
                        break;
                    //case 'xls':
                    //    XLSX.writeFile(wb, filenameParts.join('-') + '.xls', { type: 'xls' });
                    //    break;
                    case 'csv':
                        XLSX.writeFile(wb, filenameParts.join('-') + '.csv', { type: 'csv' });
                        break;
                    case 'ods':
                        XLSX.writeFile(wb, filenameParts.join('-') + '.ods', { type: 'ods' });
                        break;
                    case 'txt':
                        XLSX.writeFile(wb, filenameParts.join('-') + '.txt', { type: 'txt' });
                        break;
                }
            });
        }
    };

    //var Statistics = function (opt) {

    //};

    ///*
    // * Filter
    // */
    //var Filter = function (opt) {
    //    var self = this;
    //    self.name = opt.name || console.error("Nome filtro mancante", { filter: self, options: opt });
    //    self.el = opt.el || console.error("Elemento filtro mancante", { filter: self, options: opt });
    //    self.$el = $(self.el);
    //    self.template = opt.template || console.error("Template mancante per filtro", { filter: self, options: opt });
    //    self.data = opt.data || [];

    //    self.selection = opt.selection || cache.selection[self.name] || [];
    //    cache.selection[self.name] = self.selection;
    //};

    ///*
    // * FiltersCollection
    // */
    //var FiltersCollection = function (opt) {
    //    var self = this;

    //    self.el = opt.el || console.error("Elemento collezione di filtri mancante", { filtersCollection: self, options: opt });
    //    self.template = opt.template;
    //    self.$el = $(self.el);
    //    self.data = opt.data || [];
    //    self.filters = opt.filters || [];

    //    //render
    //    self.$el.html = self.template(self);

    //    //render filters
    //    _.forEach(filtersOpts, function (fopts) {

    //    });
    //};

    //FiltersCollection.prototype.filterData = function (data) {
    //    var dfd = $.Deferred();
    //    var self = this;

    //    var total = 0;
    //    var count = 0;

    //    var filtered = _.filter(data, function (dt) {
    //        var res = false;
    //        var cnt = Number(dt['Count']) || 1;

    //        if (self.filters.length === 0 || _.every(self.filters, function (f) {
    //            return f.filter(dt);
    //        })) {
    //            res = true;
    //            count += cnt;
    //        }

    //        total += cnt;

    //        return res;
    //    });

    //    dfd.resolve(filtered, count, data, total);
            
    //    return dfd;
    //};


    //Statistics.Filter = Filter;
    //Statistics.FiltersCollection = FiltersCollection;
    

}(jQuery));
