$(window).on('load', function() {

    /**
     * This piece of code is used to draw the total value of a doughnut
     * in the center of itself. The value is automatically calculated
     * using the data defined in the doughnut.
     *
     *  @param {object} chart - The chartjs object
     *  @param {string} label - The label that is shown below the number.
     *  @param {number} completionRate
     *
     *  @return void
     */
    function drawDoughnutNumber(chart, label, completionRate) {
        if (!completionRate) {
            completionRate = 1;
        }

        var width = chart.chart.width,
            height = chart.chart.height,
            ctx = chart.chart.ctx;

        ctx.restore();
        var fontSize = (height / 100).toFixed(2);

        ctx.fillStyle = '#333';
        ctx.textBaseline = "middle";
        ctx.font = "bold " + fontSize + "em sans-serif";

        // Draw the number
        var value = chart.data.datasets[0].data.reduce(function(x, y) {
            return x + y;
        }, 0);
        var valueX = Math.round((width - ctx.measureText(value).width) / 2);
        var valueY = height / 2 + (fontSize * 2);

        ctx.fillText(Math.round(value * completionRate), valueX, valueY);

        // Draw the label
        ctx.fillStyle = '#666';
        fontSize = (height / 350).toFixed(2);
        ctx.font = fontSize + "em sans-serif";
        var textX = Math.round((width - ctx.measureText(label).width) / 2);
        var textY = height / 2 - (fontSize * 25);
        ctx.fillText(label, textX, textY);

        ctx.save();
    }

    // Don't execute anything on ie8
    if ($('html').hasClass('browser-version-8') && $('html').hasClass("browser-IE")) {
        return false;
    }

    Chart.defaults.global.animationSteps = 60;
    Chart.defaults.global.responsive = true;
    Chart.defaults.global.maintainAspectRatio = false;
    Chart.defaults.global.responsiveAnimationDuration = 1000;

    // Only render the charts if they are inside of the viewport
    // this improves the performance, especially on mobile devices.
    $('.ig-chart').one('inview', function(event, visible) {
        if (visible) {

            var ctx = $(this),
                chartType = $(this).data('charttype'),
                showLegend = $(this).data('showlegend'),
                yScaleSuffix = $(this).data('yscalesuffix'),
                xScaleSuffix = $(this).data('xscalesuffix'),
                data = $(this).data('chart');

            var chartSettings = {
                // Doughnut specific options
                cutoutPercentage : $(this).data('cutoutpercentage'),
                showDoughnutTotal : $(this).data('showdoughnuttotal'),
                doughnutTotalSuffix : $(this).data('doughnuttotalsuffix'),

                // Scale options
                showXScale : $(this).data('showxscale'),
                showYScale : $(this).data('showyscale'),
                yStepSize : $(this).data('ystepsize'),
                yScaleMax : $(this).data('yscalemax'),
                yScaleMin : $(this).data('yscalemin'),
                xStepSize : $(this).data('xstepsize'),
                xScaleMax : $(this).data('xscalemax'),
                xScaleMin : $(this).data('xscalemin'),
                xScalePosition : $(this).data('xscaleposition'),
                yScalePosition : $(this).data('yscaleposition'),
                scaleFontFamily : $(this).data('scalefontfamily'),
                scaleFontColor : $(this).data('scalefontcolor'),
                scaleFontSize : $(this).data('scalefontsize'),
                scaleFontStyle : $(this).data('scalefontstyle'),

                // Global options
                animationDuration : $(this).data('animationduration'),
                animationEasing : $(this).data('animationeasing'),
                animationDelay: $(this).data('animationdelay')
            };

            var additionalOptions = $(this).data('additionalOptions');
            // Setting duration for the chart animations. This setting can
            // only be applied globally for now.
            Chart.defaults.global.animation.duration = chartSettings.animationDuration;
            Chart.defaults.global.animation.easing = chartSettings.animationEasing;

            Chart.defaults.global.animation.onComplete = function(a) {
                delayed = chartSettings.animationDelay > 0;
                chart.initialAnimationIsComplete = true;
            };
            if(chartSettings.animationDelay > 0) {
                Chart.defaults.global.animation.delay = function(context) {
                    return 200;
                };
            }
            Chart.defaults.global.animation.onProgress = function(a) {
                if (!chart.initialAnimationIsComplete) {
                    // Code for counting up the doughnut total
                    if (chart.config.type == 'doughnut' && chartSettings.showDoughnutTotal) {
                        var completionRate = a.animationObject.currentStep / a.animationObject.numSteps;
                        drawDoughnutNumber(chart, chartSettings.doughnutTotalSuffix, completionRate);
                    }
                } else {
                    if (chart.config.type == 'doughnut' && chartSettings.showDoughnutTotal) {
                        drawDoughnutNumber(chart, chartSettings.doughnutTotalSuffix, 1);
                    }
                }
            };

            // Set default values for some of the options
            if (!chartSettings.xStepSize) {
                chartSettings.xScaleMax = undefined
            }

            if (!chartSettings.xScaleMax) {
                chartSettings.xScaleMax = undefined
            }

            if (!chartSettings.xScaleMin) {
                chartSettings.xScaleMin = 0
            }

            if (!chartSettings.yStepSize) {
                chartSettings.yScaleMax = undefined
            }

            if (!chartSettings.yScaleMax) {
                chartSettings.yScaleMax = undefined
            }

            if (!chartSettings.yScaleMin) {
                chartSettings.yScaleMin = 0
            }

            var options = {};

            if (chartType == 'bar' || chartType == 'horizontalBar') {
                options = {
                    hover : {
                        mode : "single"
                    },
                    tooltips : {
                        enabled : true,
                        callbacks : {
                            label : function(items, data) {
                                // Depending on the bar type return the correct label
                                if (chartType == 'bar') {
                                    return data.datasets[items.datasetIndex].label + ': ' + items.yLabel + yScaleSuffix;
                                } else {
                                    return data.datasets[items.datasetIndex].label + ': ' + items.xLabel + xScaleSuffix;
                                }
                            }
                        }
                    },
                    scales : {
                        xAxes : [{
                            display : chartSettings.showXScale,
                            position : chartSettings.xScalePosition,
                            ticks : {
                                fontFamily : chartSettings.scaleFontFamily,
                                fontColor : chartSettings.scaleFontColor,
                                fontSize : chartSettings.scaleFontSize,
                                fontStyle : chartSettings.scaleFontStyle,
                                max : chartSettings.xScaleMax,
                                min : chartSettings.xScaleMin,
                                stepSize : chartSettings.xStepSize,
                                autoSkip: false,
                                // Adding the suffix the scale label.
                                callback : function(value) {
                                    return '' + value + xScaleSuffix;
                                }
                            }
                        }],
                        yAxes : [{
                            display : chartSettings.showYScale,
                            position : chartSettings.yScalePosition,
                            ticks : {
                                fontFamily : chartSettings.scaleFontFamily,
                                fontColor : chartSettings.scaleFontColor,
                                fontSize : chartSettings.scaleFontSize,
                                fontStyle : chartSettings.scaleFontStyle,
                                max : chartSettings.yScaleMax,
                                min : chartSettings.yScaleMin,
                                stepSize : chartSettings.yStepSize,
                                // Adding the suffix the scale label.
                                callback : function(value) {
                                    return '' + value + yScaleSuffix;
                                }
                            }
                        }]
                    }
                }
            }

            if (chartType == 'line') {
                options = {
                    fill : false,
                    hover : {
                        mode : "single"
                    },
                    tooltips : {
                        enabled : true,
                        callbacks : {
                            label : function(items, data) {
                                return data.datasets[items.datasetIndex].label + ': ' + items.yLabel + yScaleSuffix;
                            }
                        }
                    },
                    scales : {
                        xAxes : [{
                            display : chartSettings.showXScale,
                            position : chartSettings.xScalePosition,
                            ticks : {
                                fontFamily : chartSettings.scaleFontFamily,
                                fontColor : chartSettings.scaleFontColor,
                                fontSize : chartSettings.scaleFontSize,
                                fontStyle : chartSettings.scaleFontStyle,
                                max : chartSettings.xScaleMax,
                                min : chartSettings.xScaleMin,
                                stepSize : chartSettings.xStepSize,
                                // Adding the suffix the scale label.
                                callback : function(value) {
                                    return '' + value + xScaleSuffix;
                                }
                            }
                        }],
                        yAxes : [{
                            display : chartSettings.showYScale,
                            position : chartSettings.yScalePosition,
                            ticks : {
                                fontFamily : chartSettings.scaleFontFamily,
                                fontColor : chartSettings.scaleFontColor,
                                fontSize : chartSettings.scaleFontSize,
                                fontStyle : chartSettings.scaleFontStyle,
                                max : chartSettings.yScaleMax,
                                min : chartSettings.yScaleMin,
                                stepSize : chartSettings.yStepSize,
                                // Adding the suffix the scale label.
                                callback : function(value) {
                                    return '' + value + yScaleSuffix;
                                }
                            }
                        }]
                    }
                };
            }

            if (chartType == 'radar') {
                options = {};
            }

            // Legend settings for each chart type.
            options.legend = {
                display : showLegend,
                position : 'bottom'
            };

            // Pie and doughnut charts are essentially the same type of
            // chart. So the same settings should be applied to both of them.
            if (chartType == 'pie' || chartType == 'doughnut') {
                options = {

                    // We use a custom legend for pie charts, so we disable
                    // the default one. Because this way we can have more control
                    // over the legend.
                    legend : {
                        display : false
                    },
                    // Custom function to create the legend.
                    legendCallback : function(chart) {
                        var text = [];
                        text.push('<ul class="chart-legend ' + chart.config.type + '-legend">');
                        for (var i = 0; i < chart.data.labels.length; i++) {
                            text.push('<li><span style="background-color:' + chart.data.datasets[0].backgroundColor[i] + '"></span>');
                            if (chart.data.labels[i]) {
                                text.push(chart.data.labels[i]);
                            }
                            text.push('</li>');
                        }
                        text.push('</ul>');

                        return text.join("");
                    }
                };
            }

            if (chartType == 'doughnut') {
                options.cutoutPercentage = chartSettings.cutoutPercentage;
            }

            options.initialAnimationIsComplete = false;


            if(typeof additionalOptions != 'undefined') {
                $.extend(options, additionalOptions);
            }

            // Creating the actual chart object.
            var chart = new Chart(ctx, {
                type : chartType,
                data : data,
                options : options
            });

            // We generate and show a custom legend for pie and doughnut
            // charts, if needed.
            if (showLegend && (chartType == "pie" || chartType == "doughnut")) {
                $(this).parent().after(chart.generateLegend());
            }

            // We trigger the resize event to prevent issues in browsers that
            // only display the chart after resizing. Firefox on Android is one
            // of those browsers.
            $(window).trigger('resize');

        }
    });

    // We need to check the inview event, in case the element is already
    // visible.
    $(window).trigger('checkInView');
});
