"use strict";

(function($){
    if (typeof ThreeScale == 'undefined') {
      window.ThreeScale = {};
    }


    Highcharts.setOptions({
      lang: {
        decimalPoint: '.',
        thousandsSep: ','
      }
    });

    var Graph = ThreeScale.Graph = function Graph(options){
      $.extend(this, Graph.defaults, options);
      var chart = this;
      this.minInterval = 24 * 3600 * 1000;
      this.done = 0;
      this.sources = new Object();
      this.chartOptions = {
        title: {
          text: false
        },
        chart: {
          renderTo: "container",
          // type: 'column',
          type: 'area',
          zoomType: 'x',
          animation: Highcharts.svg, // don't animate in old IE
          marginRight: 10,

          events: {
            selection: function(event) {
              if (event.xAxis) {
                var xAxis = event.xAxis[0];

                var range = (xAxis.max - xAxis.min);
                if(range < chart.minInterval){
                  xAxis.max = xAxis.min + chart.minInterval;
                }
                chart.setSince((strftime("%F %T",new Date(xAxis.min))));
                chart.setUntil((strftime("%F %T",new Date(xAxis.max))));
                chart.suggestGranularityForRange(range);
                chart.getData();
                return false;
              }
            }
          },
        },
        yAxis: {
          title: {
            text: 'Hits'
          }
        },

        xAxis: {
          type: 'datetime',
        },

        plotOptions: {
          column: {
            stacking: "normal",
          },
          area: {
            stacking: 'normal',
              marker: {
                enabled: false,
              },
              states: {
                hover: {
                  enabled: false
                }
              }
            }
          },

          series: []
        };

      this.initHooks();

    };


    Graph.defaults = {
      noData: '#no-data',
      container: "#container",
      sinceField: "#since",
      untilField: "#until",
      tabs: "#date-pickers",
      endingNowSelectors: "#simple a",
      granularitySelect: "#granularity"
    };

    Graph.prototype = {
      initChart: function(){
        this.$noData = $(this.noData);
        this.$granularitySelect = $(this.granularitySelect);
        this.$sinceField = $(this.sinceField);
        this.$untilField = $(this.untilField);
        this.$container = $(this.container);
        this.$endingNowSelectors = $(this.endingNowSelectors);
        this.viewOptions = {
          since: this.$sinceField.val(),
          until: this.$untilField.val(),
          granularity: "day",
        };

        var h = $(window).height() - 100;
        this.$container.css({'height': h});

        this.chart = new Highcharts.Chart(this.chartOptions);
        this.getData();
        return this.chart;
      },

      initHooks: function(){
        var graph = this;
        $(document).ready(function(){
          $(graph.tabs).tabs();
          var $sinceUntilFields = $([graph.sinceField, graph.untilField].join(','));

          $sinceUntilFields.datepicker({
            dateFormat: "yy-mm-dd"
          });

          $("#applyButton").click(function(){
            graph.setDates(graph.$sinceField.val(), graph.$untilField.val(), graph.$granularitySelect.val());
          });

          $sinceUntilFields.change(function(){
            graph.changeGranularitySelect();
          });

          graph.$endingNowSelectors.click(function(){
            graph.$endingNowSelectors.removeClass('selected');
            $(this).addClass('selected');
            graph.setDates($(this).data("since"), graph.now, $(this).data('granularity'));
          });
        });
      },

      suggestGranularityForRange: function(range){
        if (range < (7 * 24 * 3600 * 1000)){
          this.setGranularity("hour");
        } else if (range < 7 * 30 * 24 * 3600 * 1000){
          this.setGranularity("day");
        }
      },

      changeGranularitySelect: function(){
        var min = Date.parse(this.$sinceField.val());
        var max = Date.parse(this.$untilField.val());
        var range = max - min;
        if(range > 32 * 24 * 3600 * 1000) {
          this.$granularitySelect.children('option[value=hour]').attr('disabled', true);
          if (this.$granularitySelect.val() == "hour"){
            this.$granularitySelect.val("day");
          }
        } else {
          this.$granularitySelect.children('option[value=hour]').attr('disabled', false);
        }

     },

      setDates: function(since, until, granularity) {
        this.setGranularity(granularity);
        this.setSince(since);
        this.setUntil(until);
        this.getData();
      },

      setGranularity: function(granularity){
        this.viewOptions.granularity = granularity;
        this.$granularitySelect.val(granularity);
        this.changeGranularitySelect();
      },

      setSince: function(since){
        this.viewOptions.since = since;
        this.$sinceField.val(since);
      },

      setUntil: function(until){
        this.viewOptions.until = until;
        this.$untilField.val(until);
      },

      defaultSince: function(){
        var date = new Date();
        date.setMonth(date.getMonth() - 12);
        return date;
      },

      automaticGranularity: function(){
        var min = Date.parse(this.viewOptions.since);
        var max = Date.parse(this.viewOptions.until);
        var range = max - min;

        if(this.viewOptions.granularity == 'hour'){
          this.viewOptions.pointInterval = 3600 * 1000;
        } else if (this.viewOptions.granularity == 'day'){
          this.viewOptions.pointInterval = 24 * 3600 * 1000;
        } else {
          this.viewOptions.pointInterval = null;
        }
      },
      getData: function(){
        var graph = this;
        this.done = 0;
        this.automaticGranularity();

        var someData = false;
        this.chart.showLoading('Loading data from server...');
        $(this.chart.series).each(function(index,serie){
          var source = graph.sources[serie.name];
          $.getJSON(source.url(), function(data) {
            graph.done +=1;

            var total = 0;
            $(data.values).each(function(index, value){
              total += value;
            });

            if(total > 0){
              someData = true;
            }

            serie.update({
              pointInterval: graph.viewOptions.pointInterval,
              pointIntervalUnit: graph.viewOptions.granularity,
              pointStart: Date.parse(graph.viewOptions.since),
              data: data.values
            });

            if(graph.done==graph.chart.series.length){
              if(someData){
                graph.$container.show();
                graph.$noData.hide();
              } else {
                graph.$container.hide();
                graph.$noData.show();
              }
              graph.chart.hideLoading();
            }
          });

        });
     },
     addSource: function(source){
        this.sources[source.name] = source;
        this.chart.addSeries({
          name: source.name,
          data: []
        });
      },
  };
})(jQuery);


