/**
 * Analytics
 */

 var Analytics = {
    GoogleVisualizationCalled: false,
    GoogleVisualizationReady: false,
    charts: {}
};

/**
 * Visualization
 */
Analytics.Visualization = Garnish.Base.extend({

    options: null,
    afterInitStack: [],

    init: function(options)
    {
        this.options = options;

        if(Analytics.GoogleVisualizationCalled == false)
        {
            Analytics.GoogleVisualizationCalled = true;

            if(typeof(AnalyticsChartLanguage) == 'undefined')
            {
                AnalyticsChartLanguage = 'en';
            }

            google.load("visualization", "1", {
                packages:['corechart', 'table'],
                language: AnalyticsChartLanguage,
                callback: $.proxy(function() {
                    Analytics.GoogleVisualizationReady = true;

                    this.onAfterInit();

                    this.onAfterFirstInit();
                }, this)
            });
        }
        else
        {
            this.onAfterInit();
        }
    },

    onAfterFirstInit: function()
    {
        // call inAfterInits that are waiting for initialization completion

        for(i=0; i < this.afterInitStack.length; i++)
        {
            this.afterInitStack[i]();
        }
    },

    onAfterInit: function()
    {
        if(Analytics.GoogleVisualizationReady)
        {
            this.options.onAfterInit();
        }
        else
        {
            // add it to the stack
            this.afterInitStack.push(this.options.onAfterInit);
        }
    }
});

/**
 * BaseChart
 */
Analytics.charts.BaseChart = Garnish.Base.extend({

    type: null,
    chart: null,
    data: null,
    period: null,
    options: null,
    visualization: null,

    init: function($element, data)
    {
        this.visualization = new Analytics.Visualization({
            onAfterInit: $.proxy(function() {

                this.$chart = $element;
                this.$chart.html('');
                this.$graph = $('<div class="graph" />').appendTo(this.$chart);

                this.data = data;

                if(typeof(this.data.chartOptions) != 'undefined')
                {
                    this.chartOptions = this.data.chartOptions;
                }

                if(typeof(this.data.type) != 'undefined')
                {
                    this.type = this.data.type;
                }

                if(typeof(this.data.period) != 'undefined')
                {
                    this.period = this.data.period;
                }

                this.addListener(Garnish.$win, 'resize', 'resize');

                this.initChart();

                if(typeof(this.data.onAfterInit) != 'undefined')
                {
                    this.data.onAfterInit();
                }
            }, this)
        });
    },

    initChart: function()
    {
        this.$graph.addClass(this.type);
        // console.error('Chart type "'+this.type+'" not supported.')
    },

    draw: function()
    {
        if(this.dataTable && this.chartOptions)
        {
            this.chart.draw(this.dataTable, this.chartOptions);
        }
    },

    resize: function()
    {
        if(this.chart && this.dataTable && this.chartOptions)
        {
            this.chart.draw(this.dataTable, this.chartOptions);
        }
    },
});

/**
 * Area
 */
Analytics.charts.Area = Analytics.charts.BaseChart.extend(
{
    initChart: function()
    {
        this.base();

        $period = $('<div class="period" />').prependTo(this.$chart);
        $title = $('<div class="title" />').prependTo(this.$chart);
        $title.html(this.data.metric);
        $period.html(this.data.periodLabel);

        this.dataTable = Analytics.Utils.responseToDataTable(this.data.chart);
        this.chartOptions = Analytics.ChartOptions.area(this.data.period);

        if(typeof(this.data.chartOptions) != 'undefined')
        {
            $.extend(this.chartOptions, this.data.chartOptions);
        }

        if(this.data.period == 'year')
        {
            var dateFormatter = new google.visualization.DateFormat({
                pattern: "MMMM yyyy"
            });

            dateFormatter.format(this.dataTable, 0);
        }

        this.chart = new google.visualization.AreaChart(this.$graph.get(0));

        this.draw();
    }
});

/**
 * Counter
 */
Analytics.charts.Counter = Analytics.charts.BaseChart.extend(
{
    initChart: function()
    {
        this.base();

        $value = $('<div class="value" />').appendTo(this.$graph),
        $label = $('<div class="label" />').appendTo(this.$graph),
        $period = $('<div class="period" />').appendTo(this.$graph);

        $value.html(this.data.counter.count);
        $label.html(this.data.metric);
        $period.html(' '+this.data.periodLabel);
    }
});

/**
 * Pie
 */
Analytics.charts.Pie = Analytics.charts.BaseChart.extend(
{
    initChart: function()
    {
        this.base();

        $period = $('<div class="period" />').prependTo(this.$chart);
        $title = $('<div class="title" />').prependTo(this.$chart);
        $title.html(this.data.dimension);
        $period.html(this.data.metric+" "+this.data.periodLabel);

        this.dataTable = Analytics.Utils.responseToDataTable(this.data.chart);
        this.chartOptions = Analytics.ChartOptions.pie();
        this.chart = new google.visualization.PieChart(this.$graph.get(0));
        this.draw();
    }
});

/**
 * Table
 */
Analytics.charts.Table = Analytics.charts.BaseChart.extend(
{
    initChart: function()
    {
        this.base();

        $period = $('<div class="period" />').prependTo(this.$chart);
        $title = $('<div class="title" />').prependTo(this.$chart);
        $title.html(this.data.metric);
        $period.html(this.data.periodLabel);

        this.dataTable = Analytics.Utils.responseToDataTable(this.data.chart);
        this.chartOptions = Analytics.ChartOptions.table();
        this.chart = new google.visualization.Table(this.$graph.get(0));
        this.draw();
    }
});

/**
 * Geo
 */
Analytics.charts.Geo = Analytics.charts.BaseChart.extend(
{
    initChart: function()
    {
        this.base();

        $period = $('<div class="period" />').prependTo(this.$chart);
        $title = $('<div class="title" />').prependTo(this.$chart);
        $title.html(this.data.metric);
        $period.html(this.data.periodLabel);

        this.dataTable = Analytics.Utils.responseToDataTable(this.data.chart);
        this.chartOptions = Analytics.ChartOptions.geo(this.data.dimensionRaw);
        this.chart = new google.visualization.GeoChart(this.$graph.get(0));
        this.draw();
    }
});

/**
 * Chart Options
 */
Analytics.ChartOptions = Garnish.Base.extend({}, {

    area: function(scale) {

        options = this.defaults.area;

        switch(scale)
        {
            case 'week':
            options.hAxis.format = 'E';
            options.hAxis.showTextEvery = 1;
            break;

            case 'month':
            options.hAxis.format = 'MMM d';
            options.hAxis.showTextEvery = 1;
            break;

            case 'year':
            options.hAxis.showTextEvery = 1;
            options.hAxis.format = 'MMM yy';
            break;
        }

        return options;
    },

    table: function()
    {
        return this.defaults.table;
    },

    geo: function(dimension)
    {
        options = this.defaults.geo;

        switch(dimension)
        {
            case 'ga:city':
            options.displayMode = 'markers';
            break;

            case 'ga:country':
            options.resolution = 'countries';
            options.displayMode = 'regions';
            break;

            case 'ga:continent':
            options.resolution = 'continents';
            options.displayMode = 'regions';
            break;

            case 'ga:subContinent':
            options.resolution = 'subcontinents';
            options.displayMode = 'regions';
            break;
        }

        return options;
    },

    pie: function()
    {
        return this.defaults.pie;
    },

    field: function()
    {
        return {
            theme: 'maximized',
            legend: 'none',
            backgroundColor: '#fdfdfd',
            colors: ['#058DC7'],
            areaOpacity: 0.1,
            pointSize: 0,
            lineWidth: 4,
            height: 120,
            hAxis: {
                //format:'MMM yy',
                format: 'MMM d',
                // format: 'E',
                textPosition: 'in',
                textStyle: {
                    color: '#058DC7'
                },
                showTextEvery: 1,
                baselineColor: '#fff',
                gridlines: {
                    color: 'none'
                }
            },
            vAxis: {
                textPosition: 'in',
                textStyle: {
                    color: '#058DC7'
                },
                baselineColor: '#ccc',
                gridlines: {
                    color: '#f4f4f4'
                },
                // viewWindow: {min:0, max: 10},
                minValue: 0,
                maxValue: 10,
                format: '#'
            }
        };
    },

    defaults: {
        area: {
            theme: 'maximized',
            legend: 'none',
            backgroundColor: '#FFF',
            colors: ['#058DC7'],
            areaOpacity: 0.1,
            pointSize: 7,
            lineWidth: 4,
            chartArea: {
            },
            hAxis: {
                //format:'MMM yy',
                // format: 'MMM d',
                format: 'E',
                textPosition: 'in',
                textStyle: {
                    color: '#058DC7'
                },
                showTextEvery: 1,
                baselineColor: '#fff',
                gridlines: {
                    color: 'none'
                }
            },
            vAxis: {
                textPosition: 'in',
                textStyle: {
                    color: '#058DC7'
                },
                baselineColor: '#ccc',
                gridlines: {
                    color: '#fafafa'
                },
                // viewWindow: {min:0, max: 10},
                minValue: 0,
                maxValue: 10,
                format: '#'
            }
        },

        geo: {
            // height: 282
            displayMode: 'auto'
        },

        pie: {
            theme: 'maximized',
            height: 282,
            pieHole: 0.5,
            legend: {
                alignment: 'center',
                position:'top'
            },
            chartArea:{
                top:40,
                height:'82%'
            },
            sliceVisibilityThreshold: 1/120
        },

        table: {
            // page: 'enable'
        }
    }
});


/**
 * Utils
 */
Analytics.Utils = {

    responseToDataTable: function(response)
    {
        var data = new google.visualization.DataTable();

        $.each(response.cols, function(k, column) {
            data.addColumn(column);
        });

        $.each(response.rows, function(kRow, row) {

            $.each(row, function(kCell, cell) {

                switch(response.cols[kCell]['type'])
                {
                    case 'date':

                        $dateString = cell.v;

                        if($dateString.length == 8)
                        {
                            // 20150101

                            $year = eval($dateString.substr(0, 4));
                            $month = eval($dateString.substr(4, 2)) - 1;
                            $day = eval($dateString.substr(6, 2));

                            $date = new Date($year, $month, $day);

                            row[kCell] = $date;
                        }
                        else if($dateString.length == 6)
                        {
                            // 201501

                            $year = eval($dateString.substr(0, 4));
                            $month = eval($dateString.substr(4, 2)) - 1;

                            $date = new Date($year, $month, '01');

                            row[kCell] = $date;
                        }

                        break;
                }
            });

            data.addRow(row);
        });

        return data;
    }
};