// Generated by CoffeeScript 1.11.0 var AppRouter, DynamicChartView, DynamicWidget, DynamicWidgetView, LinePresenter, PageInfo, PageInfoList, PageTitleView, PageTitlesView, SensorInfo, SensorInfoList, SensorInfoListView, SeriesPresenter, StackPresenter, TimelinePresenter, Widget, WidgetChartView, WidgetList, WidgetListView, WidgetPresenter, WidgetView,

extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;

String.prototype.capitalize = function() {

return this.charAt(0).toUpperCase() + this.slice(1);

};

String.prototype.strip = function() {

if (String.prototype.trim != null) {
  return this.trim();
} else {
  return this.replace(/^\s+|\s+$/g, "");
}

};

Number.prototype.humanize = function() {

var d, h, interval, m, res, s;
interval = this;
res = "";
s = interval % 60;
if (s > 0) {
  res = s + " s";
}
interval = (interval - s) / 60;
if (!(interval > 0)) {
  return res;
}
m = interval % 60;
if (m > 0) {
  res = (m + " m " + res).strip();
}
interval = (interval - m) / 60;
if (!(interval > 0)) {
  return res;
}
h = interval % 24;
if (h > 0) {
  res = (h + " h " + res).strip();
}
d = (interval - h) / 24;
if (d > 0) {
  return (d + " d " + res).strip();
} else {
  return res;
}

};

PageInfo = Backbone.Model.extend({});

Widget = Backbone.Model.extend({

initialize: function() {
  this.updating = false;
  this.needRefresh = true;
  this.setNextFetch();
  return this.timespanInc = 0;
},
setStartTime: function(startTime) {
  this.startTime = startTime;
},
setEndTime: function(endTime) {
  this.endTime = endTime;
},
increaseTimespan: function(inc) {
  this.timespanInc = this.timespanInc + inc;
  return this.forceUpdate();
},
resetTimespan: function() {
  this.timespanInc = 0;
  this.startTime = null;
  this.endTime = null;
  return this.forceUpdate();
},
timespan: function() {
  return this.get('timespan') + this.timespanInc;
},
url: function() {
  var timespan, url;
  timespan = this.timespan();
  url = (this.collection.url()) + "/" + (this.get('id')) + "?";
  if (!_.isNaN(timespan)) {
    url += "&timespan=" + timespan;
  }
  if (this.startTime) {
    url += "&startTime=" + this.startTime;
  }
  if (this.endTime) {
    url += "&endTime=" + this.endTime;
  }
  return url;
},
time: function() {
  return (new Date()).getTime();
},
setNextFetch: function() {
  return this.nextFetch = this.time() + this.get('redrawInterval') * 1000;
},
setRefresh: function(needRefresh) {
  return this.needRefresh = needRefresh;
},
needFetch: function() {
  var interval;
  interval = this.get('redrawInterval');
  return this.time() > this.nextFetch && this.needRefresh && (interval != null) && interval > 0;
},
refetch: function() {
  if (this.needFetch()) {
    this.forceUpdate();
    return this.setNextFetch();
  }
},
setUpdated: function() {
  return this.updating = false;
},
forceUpdate: function() {
  var xhr;
  if (this.updating) {
    return;
  }
  this.updating = true;
  xhr = this.fetch({
    success: (function(_this) {
      return function(model, response) {
        return _this.trigger('redraw');
      };
    })(this)
  });
  xhr.always((function(_this) {
    return function() {
      return _this.updating = false;
    };
  })(this));
  return xhr.fail((function(_this) {
    return function(xhr, textStatus, errorThrown) {
      return console.log("xhr fail", _this.get('id'), textStatus, errorThrown);
    };
  })(this));
}

});

DynamicWidget = Backbone.Model.extend({

setStartTime: function(startTime) {
  this.startTime = startTime;
},
setEndTime: function(endTime) {
  this.endTime = endTime;
},
increaseTimespan: function(inc) {
  return this.set('timespan', this.timespan() + inc);
},
resetTimespan: function() {
  this.startTime = null;
  this.endTime = null;
  return this.set('timespan', null);
},
timespan: function() {
  return this.get('timespan');
},
sensorArgs: function() {
  return _.map(this.get('sensorIds'), function(name) {
    return "sensor[]=" + name;
  }).join('&');
},
url: function() {
  var timespan, url;
  timespan = this.timespan();
  url = ROOT + "dynamic_widget?" + (this.sensorArgs()) + "&type=" + (this.get('type'));
  if ((timespan != null) && !_.isNaN(timespan)) {
    url += "&timespan=" + timespan;
  }
  if (this.startTime) {
    url += "&startTime=" + this.startTime;
  }
  if (this.endTime) {
    url += "&endTime=" + this.endTime;
  }
  return url;
},
forceUpdate: function() {
  return this.fetch({
    success: function(model, response) {
      return model.trigger('redraw');
    }
  });
}

});

SensorInfo = Backbone.Model.extend({});

PageInfoList = Backbone.Collection.extend({

model: PageInfo,
selected: function() {
  return this.find(function(m) {
    return m.get('selected');
  });
},
selectFirst: function() {
  if (this.length > 0) {
    return this.at(0).set('selected', true);
  }
},
selectNone: function() {
  return this.each(function(m) {
    return m.set('selected', false);
  });
},
selectPage: function(id) {
  return this.each(function(m) {
    return m.set('selected', m.id === id);
  });
}

});

SensorInfoList = Backbone.Collection.extend({

model: SensorInfo,
url: function() {
  return ROOT + 'sensors';
}

});

WidgetList = Backbone.Collection.extend({

model: Widget,
setContext: function(pageInfos1) {
  this.pageInfos = pageInfos1;
},
url: function() {
  return ROOT + 'pages/' + this.pageInfos.selected().id + '/widgets';
},
startPolling: function() {
  return setInterval((function(_this) {
    return function() {
      if (_this.pageInfos.selected()) {
        return _this.each(function(w) {
          return w.refetch();
        });
      }
    };
  })(this), 200);
}

});

WidgetPresenter = (function() {

function WidgetPresenter(pageInfos1, model1, el1) {
  this.pageInfos = pageInfos1;
  this.model = model1;
  this.el = el1;
  this.chartEl = this.el.find('#chart')[0];
  this.legendEl = this.el.find('#legend')[0];
  this.chart = new Dygraph.GVizChart(this.chartEl);
  this.draw();
}

WidgetPresenter.prototype.get = function(arg) {
  return this.model.get(arg);
};

WidgetPresenter.prototype.globalOptions = function() {
  return gon.options;
};

WidgetPresenter.prototype.dateOffset = function() {
  if (this.globalOptions.useUtc) {
    return (new Date).getTimezoneOffset() * 60000;
  } else {
    return 0;
  }
};

WidgetPresenter.prototype.options = function() {
  return {
    labelsDiv: this.legendEl,
    labelsSeparateLines: false,
    rightGap: 30,
    highlightCircleSize: 2,
    highlightSeriesOpts: {
      strokeWidth: 2,
      strokeBorderWidth: 1,
      highlightCircleSize: 5
    },
    axisLabelWidth: 80
  };
};

WidgetPresenter.prototype.mergedOptions = function() {
  var pageOptions;
  pageOptions = this.pageInfos.selected() ? this.pageInfos.selected().get('dygraphsOptions') : {};
  return $.extend(true, this.options(), this.globalOptions().dygraphsOptions, pageOptions, this.get('dygraphsOptions'));
};

WidgetPresenter.prototype.data = function() {
  return new google.visualization.DataTable;
};

WidgetPresenter.prototype.draw = function() {
  return this.chart.draw(this.data(), this.mergedOptions());
};

return WidgetPresenter;

})();

WidgetPresenter.create = function(pageInfos, model, el) {

var presenterClass, type;
type = model.get('type');
if ((type != null) && type.match(/^\w+$/)) {
  presenterClass = eval((type.capitalize()) + "Presenter");
  return new presenterClass(pageInfos, model, el);
} else {
  return null;
}

};

TimelinePresenter = (function(superClass) {

extend(TimelinePresenter, superClass);

function TimelinePresenter() {
  return TimelinePresenter.__super__.constructor.apply(this, arguments);
}

TimelinePresenter.prototype.data = function() {
  var data, dateOffset, series;
  data = TimelinePresenter.__super__.data.call(this);
  data.addColumn('datetime', 'Time');
  dateOffset = this.dateOffset() + this.get('interval') * 1000;
  series = this.get('series');
  _.each(series.titles, function(t) {
    return data.addColumn('number', t);
  });
  _.each(series.rows, function(row) {
    row[0] = new Date(row[0] + dateOffset);
    return data.addRow(row);
  });
  return data;
};

return TimelinePresenter;

})(WidgetPresenter);

SeriesPresenter = (function(superClass) {

extend(SeriesPresenter, superClass);

function SeriesPresenter() {
  return SeriesPresenter.__super__.constructor.apply(this, arguments);
}

SeriesPresenter.prototype.options = function() {
  return $.extend(true, SeriesPresenter.__super__.options.call(this), {
    title: this.get('title'),
    legend: 'always',
    height: 300,
    ylabel: this.valuesTitle(),
    colors: this.colors()
  });
};

SeriesPresenter.prototype.valuesTitle = function() {
  if (this.get('valuesTitle')) {
    return (this.get('valuesTitle')) + " / " + (this.humanizedInterval());
  } else {
    return this.humanizedInterval();
  }
};

SeriesPresenter.prototype.colors = function() {
  return _.map(this.get('series').options, function(o) {
    return o.color;
  });
};

SeriesPresenter.prototype.humanizedInterval = function() {
  return this.get('interval').humanize();
};

return SeriesPresenter;

})(TimelinePresenter);

LinePresenter = (function(superClass) {

extend(LinePresenter, superClass);

function LinePresenter() {
  return LinePresenter.__super__.constructor.apply(this, arguments);
}

return LinePresenter;

})(SeriesPresenter);

StackPresenter = (function(superClass) {

extend(StackPresenter, superClass);

function StackPresenter() {
  return StackPresenter.__super__.constructor.apply(this, arguments);
}

return StackPresenter;

})(SeriesPresenter);

PageTitleView = Backbone.View.extend({

tagName: 'li',
template: _.template('<a href="#/pages/<%= id  %>"><%= title %></a>'),
initialize: function() {
  this.model.bind('change', this.render, this);
  return this.model.bind('destroy', this.remove, this);
},
render: function() {
  this.$el.html(this.template(this.model.toJSON()));
  if (this.model.get('selected')) {
    return this.$el.addClass('active');
  } else {
    return this.$el.removeClass('active');
  }
}

});

PageTitlesView = Backbone.View.extend({

initialize: function(pageInfos1) {
  this.pageInfos = pageInfos1;
  return this.pageInfos.bind('reset', this.render, this);
},
addOne: function(pageInfo) {
  var view;
  view = new PageTitleView({
    model: pageInfo
  });
  view.render();
  return $('#page-titles').append(view.el);
},
render: function() {
  $('#page-titles').empty();
  return this.pageInfos.each(this.addOne);
}

});

SensorInfoListView = Backbone.View.extend({

tagName: 'div',
template: function() {
  return _.template($("#sensor-list").html());
},
initialize: function(sensorInfo) {
  this.sensorInfo = sensorInfo;
  return this.sensorInfo.bind('reset', this.render, this);
},
render: function() {
  return this.$el.html(this.template()({
    sensors: this.sensorInfo.toJSON()
  }));
},
selectedSensors: function() {
  var checked, ids, selected;
  checked = _.filter(this.$el.find('.sensor-box'), function(el) {
    return $(el).is(':checked');
  });
  ids = {};
  _.each(checked, function(box) {
    return ids[box.id] = true;
  });
  return selected = this.sensorInfo.filter(function(sensor) {
    return ids[sensor.id];
  });
}

});

DynamicChartView = Backbone.View.extend({

initialize: function(options) {
  this.pageInfos = options['pageInfos'];
  this.sensors = [];
  this.type = 'Area';
  this.widget = new DynamicWidget;
  this.widget.bind('destroy', this.remove, this);
  return this.widget.bind('redraw', this.redrawChart, this);
},
tagName: 'div',
events: {
  "click #refresh-chart": 'update',
  "click #extend-timespan": 'extendTimespan',
  "click #reset-timespan": 'resetTimespan',
  "change #start-time input": 'maybeEnableStopTime',
  "click #set-interval": 'setTimelineInterval'
},
template: function() {
  return _.template($("#dynamic-widget-plotarea").html());
},
chartContainerTemplate: '<div id="chart"></div><div id="legend"></div>',
render: function() {
  this.$el.html(this.template()());
  return this.initDatePickers();
},
initDatePickers: function() {
  this.$el.find(".datepicker").each(function(i) {
    return $(this).datetimepicker({
      showOtherMonths: true,
      selectOtherMonths: true
    });
  });
  return this.$el.find("#end-time input").prop("disabled", true);
},
setTimelineInterval: function() {
  var end, start;
  start = this.unixtimeFromDatepicker("#start-time input");
  end = this.unixtimeFromDatepicker("#end-time input");
  this.widget.setStartTime(start);
  this.widget.setEndTime(end);
  return this.update();
},
dateFromDatepicker: function(id) {
  return this.$el.find(id).datetimepicker("getDate");
},
unixtimeFromDatepicker: function(id) {
  var date;
  date = this.dateFromDatepicker(id);
  if (date) {
    return date.getTime() / 1000;
  } else {
    return null;
  }
},
maybeEnableStopTime: function() {
  var date, disabled;
  date = this.dateFromDatepicker("#start-time input");
  disabled = date ? false : true;
  return this.$el.find("#end-time input").prop("disabled", disabled);
},
extendTimespan: function() {
  var select, val;
  select = this.$el.find("#extend-timespan-val");
  val = select.first().val();
  this.widget.increaseTimespan(parseInt(val));
  return this.update();
},
resetTimespan: function() {
  this.widget.resetTimespan();
  return this.update();
},
sensorIds: function() {
  return _.map(this.sensors, function(s) {
    return s.id;
  });
},
redrawChart: function() {
  if (this.presenter) {
    return this.presenter.draw();
  } else {
    return this.presenter = WidgetPresenter.create(this.pageInfos, this.widget, this.chartContainer());
  }
},
chartContainer: function() {
  return $(this.$el.find('#chart-widget')[0]);
},
update: function() {
  if (this.sensors.length > 0) {
    return this.widget.forceUpdate();
  }
},
draw: function(sensors, type) {
  this.sensors = sensors;
  this.type = type;
  this.widget.set('sensorIds', this.sensorIds());
  this.widget.set('type', this.type);
  this.presenter = null;
  this.chartContainer().html(this.chartContainerTemplate);
  return this.widget.forceUpdate();
}

});

DynamicWidgetView = Backbone.View.extend({

tagName: 'div',
initialize: function(options) {
  this.pageInfos = options['pageInfos'];
  this.sensorInfo = new SensorInfoList;
  this.sensorListView = new SensorInfoListView(this.sensorInfo);
  this.chartView = new DynamicChartView({
    pageInfos: this.pageInfos
  });
  this.$el.html(this.template()());
  this.$el.find('#sensor-list-area').append(this.sensorListView.el);
  this.chartView.render();
  return this.$el.find('#dynamic-plotarea').append(this.chartView.el);
},
events: {
  "click #sensor-controls #refresh": 'refresh',
  "click #sensor-controls #draw": 'drawChart'
},
template: function() {
  return _.template($("#dynamic-widget").html());
},
errorTemplate: function() {
  return _.template($("#dynamic-widget-error").html());
},
error: function(error) {
  return this.$el.find('#errors').append(this.errorTemplate()({
    error: error
  }));
},
refresh: function() {
  return this.sensorInfo.fetch();
},
intervalsEqual: function(sensors) {
  var badIntervals, interval;
  interval = sensors[0].get('interval');
  badIntervals = _.filter(sensors, function(s) {
    return s.get('interval') !== interval;
  });
  return badIntervals.length === 0;
},
drawChart: function() {
  var selectedSensors, type;
  selectedSensors = this.sensorListView.selectedSensors();
  if (!(selectedSensors.length > 0)) {
    return;
  }
  if (!this.intervalsEqual(selectedSensors)) {
    this.error('Selected sensors have different intervals');
    return;
  }
  type = this.$el.find('#chart-type').val();
  return this.chartView.draw(selectedSensors, type);
},
render: function(container) {
  container.empty();
  container.append(this.$el);
  this.sensorInfo.fetch();
  return this.chartView.update();
}

});

WidgetChartView = Backbone.View.extend({

tagName: 'div',
template: '<div id="chart"></div><div id="legend"></div>',
initialize: function(options) {
  this.$el.html(this.template);
  this.pageInfos = options['pageInfos'];
  return this.model.bind('destroy', this.remove, this);
},
updateData: function() {
  return this.presenter.draw();
},
render: function() {
  return this.presenter = WidgetPresenter.create(this.pageInfos, this.model, this.$el);
}

});

WidgetView = Backbone.View.extend({

tagName: 'div',
template: function(args) {
  return _.template($(".widget-template[data-widget-type=\"" + (this.model.get('type')) + "\"]").html())(args);
},
initialize: function(options) {
  this.pageInfos = options['pageInfos'];
  this.model.bind('destroy', this.remove, this);
  return this.model.bind('redraw', this.updateChart, this);
},
events: {
  "click #refresh": 'refresh',
  "click #need-refresh": 'setRefresh',
  "click #extend-timespan": 'extendTimespan',
  "click #reset-timespan": 'resetTimespan',
  "change #start-time input": 'maybeEnableStopTime',
  "click #set-interval": 'setTimelineInterval'
},
refresh: function() {
  return this.model.forceUpdate();
},
setRefresh: function() {
  var needRefresh;
  needRefresh = this.$el.find('#need-refresh').is(":checked");
  this.model.setRefresh(needRefresh);
  return true;
},
extendTimespan: function() {
  var select, val;
  select = this.$el.find("#extend-timespan-val");
  val = select.first().val();
  return this.model.increaseTimespan(parseInt(val));
},
setTimelineInterval: function() {
  var end, start;
  start = this.unixtimeFromDatepicker("#start-time input");
  end = this.unixtimeFromDatepicker("#end-time input");
  this.model.setStartTime(start);
  return this.model.setEndTime(end);
},
maybeEnableStopTime: function() {
  var date, disabled;
  date = this.dateFromDatepicker("#start-time input");
  disabled = date ? false : true;
  return this.$el.find("#end-time input").prop("disabled", disabled);
},
resetTimespan: function() {
  return this.model.resetTimespan();
},
renderChart: function() {
  return this.chartView.render();
},
updateChart: function() {
  return this.chartView.updateData();
},
setIds: function() {
  this.$el.find('#configure-button').prop('href', "#configure-" + this.model.id);
  this.$el.find('#configure').attr('id', "configure-" + this.model.id);
  this.$el.find('#start-time input').attr('id', "start-time-" + this.model.id);
  return this.$el.find('#end-time input').attr('id', "end-time-" + this.model.id);
},
render: function() {
  this.$el.html(this.template(this.model.toJSON()));
  this.setIds();
  this.chartView = new WidgetChartView({
    pageInfos: this.pageInfos,
    model: this.model
  });
  this.$el.find("#plotarea").append(this.chartView.el);
  this.$el.addClass("span" + (this.model.get('width')));
  return this.initDatePickers();
},
initDatePickers: function() {
  this.$el.find(".datepicker").each(function(i) {
    return $(this).datetimepicker({
      showOtherMonths: true,
      selectOtherMonths: true
    });
  });
  return this.$el.find("#end-time input").prop("disabled", true);
},
controlValue: function(id) {
  var val;
  return val = this.$el.find(id).first().val();
},
dateFromDatepicker: function(id) {
  return this.$el.find(id).datetimepicker("getDate");
},
unixtimeFromDatepicker: function(id) {
  var date;
  date = this.dateFromDatepicker(id);
  if (date) {
    return date.getTime() / 1000;
  } else {
    return null;
  }
}

});

WidgetListView = Backbone.View.extend({

initialize: function(options) {
  this.widgetList = options['widgetList'];
  this.pageInfos = options['pageInfos'];
  return this.widgetList.bind('reset', this.render, this);
},
render: function() {
  var container;
  container = $('#widgets');
  container.empty();
  return this.widgetList.each((function(_this) {
    return function(w) {
      var view;
      view = new WidgetView({
        pageInfos: _this.pageInfos,
        model: w
      });
      view.render();
      container.append(view.el);
      return view.renderChart();
    };
  })(this));
}

});

AppRouter = Backbone.Router.extend({

initialize: function(pageInfos1, widgetList1) {
  this.pageInfos = pageInfos1;
  this.widgetList = widgetList1;
},
routes: {
  'pages/:id': 'getPage',
  'custom': 'custom',
  '*actions': 'defaultRoute'
},
getPage: function(ids) {
  var id;
  id = parseInt(ids);
  this.pageInfos.selectPage(id);
  return this.widgetList.fetch();
},
custom: function() {
  var dynamicWidget;
  this.pageInfos.selectNone();
  dynamicWidget = new DynamicWidgetView({
    pageInfos: this.pageInfos
  });
  return dynamicWidget.render($('#widgets'));
},
defaultRoute: function(actions) {
  if (this.pageInfos.length > 0) {
    return this.navigate('//pages/1');
  } else {
    return this.navigate('//custom');
  }
}

});

document.startApp = function() {

var appRouter, pageInfos, pageTitlesApp, widgetList, widgetListApp;
pageInfos = new PageInfoList;
pageTitlesApp = new PageTitlesView(pageInfos);
pageInfos.reset(gon.pageInfos);
widgetList = new WidgetList;
widgetList.setContext(pageInfos);
widgetList.startPolling();
widgetListApp = new WidgetListView({
  widgetList: widgetList,
  pageInfos: pageInfos
});
appRouter = new AppRouter(pageInfos, widgetList);
return Backbone.history.start();

};