import {Graph} from "./graph";

declare var require: any

/**
 * Graph with multiple sensors. (Only linechart)
 */
export class MultiGraph implements Graph{


  isAnalytics: boolean;
  data: any [];
  interval: number;
  legend: {};

  /**
   * Instantiates new multigraph
   * @param isAnalytics true/false analytics/observations
   * @param data source of values for vega graph
   * @param legend source of legend for graph (e.g. sensors phenomenon)
   * @param interval default graph interval used for different purposes (in milliseconds) (see timeWindow and maxTimeDifference in vega specification)
   */
  constructor(isAnalytics: boolean, data: any [], legend: {}, interval: number) {
    this.isAnalytics = isAnalytics;
    this.data = data;
    this.interval = interval;
    this.legend = this.getLegend(legend);

  }

  /**
   * Returns vega configuration (see readme.txt in vega folder)
   */
  getConfig(): {} {
    //from folder vega/config merge corresponding files

    const lodash = require('lodash/object');
    const rvalue: any = {};
    let config1 = require('/src/vega/config/config.json');
    lodash.merge(rvalue, config1);

    let config2;
    if (this.isAnalytics) {
      config2 = require('/src/vega/config/config-multiline-analytics.json');
    } else {
      config2 = require('/src/vega/config/config-multiline-observations.json');
    }

    let config3 = require('/src/vega/config/config-barline.json');


    for(let key in config2.signals) {
      let obj = config2.signals[key];
      rvalue.signals.push(obj);
    }

    for(let key in config3.signals) {
      let obj = config3.signals[key];
      rvalue.signals.push(obj);
    }

    return rvalue;
  }


  /**
   * returns vega specification (see readme.txt in vega folder)
   */
  getSpec(): {} {
    const lodash = require('lodash/object');
    const rvalue: any = {};
    const base = require('/src/vega/base/default.json');
    const body = require('/src/vega/body/multilinechart.json');
    const legend = require('/src/vega/miscs/legend.json');
    const tooltip = require('/src/vega/miscs/multiline-tooltip.json');

    lodash.merge(rvalue, base, body, legend, tooltip);

    //setting legend to result
    rvalue.data[0].values = this.legend;

    //setting data to result
    rvalue.data[1].values = this.data;

    //setting interval to json
    //interval used for
    // 1) appending graph domain
    // 2) 5 * interval is max difference for connecting the dots
    // 3) setting zoom in windcharts
    rvalue.signals[0].value = this.interval;

    //setting tooltip message
    rvalue.marks[0].marks[0].marks[0].marks[2].encode.enter.tooltip.signal = this.getTooltipMessage();

    return rvalue;
  }

  /**
   * Generates the tooltip message
   */
  private getTooltipMessage() {
    let message = "{title: timeFormat(datum.dateTime, '%A, %B %e, %Y %X')";
    this.data.forEach(function (e) {
      message += (", '" + e.sensor.sensorName + "': datum['" + e.sensor.sensorName + "'] + ' " + e.sensor.phenomenon.unit +"' ");
    })

    message += "}";
    return message;
  }

  /**
   * If legend is array of phenomenons, it selects the first element
   * @param legend info for displaying legend
   */
  private getLegend(legend: any) {
    if(Array.isArray(legend)) {
      return legend[0];
    } else {
      return legend;
    }
  }


}
