"use strict";

exports.__esModule = true;
exports["default"] = Deckly;

var _react = _interopRequireDefault(require("react"));

var _reactDom = require("react-dom");

var _react2 = require("@deck.gl/react");

var _layers = require("@deck.gl/layers");

var _reactMapGl = require("react-map-gl");

var _carto = require("@deck.gl/carto");

var _topojsonClient = require("topojson-client");

var _chromaJs = _interopRequireDefault(require("chroma-js"));

var _reactPlotly = _interopRequireDefault(require("react-plotly.js"));

var _AbsoluteLegend = _interopRequireDefault(require("./AbsoluteLegend"));

require("./custom.css");

var _reactReflex = require("react-reflex");

require("react-reflex/styles.css");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }

function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }

function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }

function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } it = o[Symbol.iterator](); return it.next.bind(it); }

function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }

function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }

// Viewport settings
var INITIAL_VIEW_STATE = {
  longitude: 172.5118422,
  latitude: -41.235726,
  zoom: 5,
  pitch: 0,
  bearing: 0
};

function aggregate(items) {
  var result = {};

  for (var _iterator = _createForOfIteratorHelperLoose(items), _step; !(_step = _iterator()).done;) {
    var item = _step.value;

    for (var k in item) {
      var v = item[k];

      if (typeof v == "object") {
        if (!result[k]) result[k] = {};

        for (var sk in v) {
          if (typeof v[sk] == "object") {
            for (var ssk in v[sk]) {
              if (!result[k][sk]) result[k][sk] = {};
              if (!result[k][sk][ssk]) result[k][sk][ssk] = 0;
              result[k][sk][ssk] += v[sk][ssk];
            }
          } else if (typeof v[sk] == "number") {
            if (!result[k][sk]) result[k][sk] = 0;
            result[k][sk] += v[sk];
          }
        }
      } else if (typeof v == "number") {
        if (!result[k]) result[k] = 0;
        result[k] += v;
      }
    }
  }

  result["aggregate"] = true;
  console.log(result);
  return result;
}

var DecklyComponent = /*#__PURE__*/function (_React$Component) {
  _inheritsLoose(DecklyComponent, _React$Component);

  function DecklyComponent(props) {
    var _this;

    _this = _React$Component.call(this, props) || this;
    _this.state = {
      items: [],
      accessor: _this.props.colorBy,
      isLoaded: false,
      per: false,
      hoverInfo: {},
      limits: _this.props.limits,
      selected: null
    };
    _this.handleInputChange = _this.handleInputChange.bind(_assertThisInitialized(_this));
    return _this;
  }

  var _proto = DecklyComponent.prototype;

  _proto.componentDidMount = function componentDidMount() {
    var _this2 = this;

    document.title = this.props.title;
    fetch(this.props.data).then(function (results) {
      return results.json();
    }).then(function (json) {
      if (json.type == "Topology") {
        json = (0, _topojsonClient.feature)(json, Object.keys(json.objects)[0]); // Convert topojson to geojson
      }

      console.log(json);

      _this2.setState({
        isLoaded: true,
        items: json.features,
        aggregate: aggregate(json.features.map(function (f) {
          return f.properties;
        }))
      });
    });
  };

  _proto.handleInputChange = function handleInputChange(event) {
    var _this$setState;

    var target = event.target;
    var value = target.type === 'checkbox' ? target.checked : target.value;
    var name = target.name;
    this.setState((_this$setState = {}, _this$setState[name] = value, _this$setState));
  };

  _proto.render = function render() {
    var _this3 = this;

    if (!this.state.isLoaded) return null;
    var data = this.state.items.map(this.state.accessor);
    console.log(data);

    if (!this.state.limits) {
      if (typeof data[0] == "number") {
        this.state.limits = _chromaJs["default"].limits(data, 'e', 1);
      } else if (typeof data[0] == "object") {
        this.state.limits = [_chromaJs["default"].limits(data.map(function (v) {
          return v[0];
        }), 'e', 1), _chromaJs["default"].limits(data.map(function (v) {
          return v[1];
        }), 'e', 1)];
      }

      console.log(this.state.limits);
    }

    var COLOR_SCALE;

    if (typeof this.props.colorScale == "string") {
      COLOR_SCALE = _chromaJs["default"].scale(this.props.colorScale).domain(this.state.limits);
    } else if (typeof this.props.colorScale == "object") {
      // Bivariate
      COLOR_SCALE = [_chromaJs["default"].scale(this.props.colorScale[0]).domain(this.state.limits[0]), _chromaJs["default"].scale(this.props.colorScale[1]).domain(this.state.limits[1])];
    }

    console.log(COLOR_SCALE);
    var layers = [new _layers.GeoJsonLayer({
      id: 'geojson',
      data: this.state.items,
      opacity: 0.8,
      lineWidthUnits: "pixels",
      lineWidthMinPixels: 1,
      getLineWidth: function getLineWidth(f) {
        return f == _this3.state.selected ? 3 : 1;
      },
      getFillColor: function getFillColor(f) {
        return typeof COLOR_SCALE == "object" ? _chromaJs["default"].blend(COLOR_SCALE[0](_this3.state.accessor(f)[0]), COLOR_SCALE[1](_this3.state.accessor(f)[1]), "multiply").rgb() : COLOR_SCALE(_this3.state.accessor(f)).rgb();
      },
      getLineColor: function getLineColor(f) {
        return f == _this3.state.selected ? [255, 69, 0] : [0, 0, 0];
      },
      pickable: true,
      onHover: function onHover(info) {
        return _this3.state.selected == null ? _this3.setState({
          hoverInfo: info
        }) : null;
      },
      onClick: function onClick(info) {
        return _this3.state.selected == info.object ? _this3.setState({
          selected: null
        }) : _this3.setState({
          selected: info.object,
          hoverInfo: info
        });
      },
      updateTriggers: {
        getLineWidth: this.state.selected,
        getLineColor: this.state.selected
      }
    })];
    return /*#__PURE__*/_react["default"].createElement(_reactReflex.ReflexContainer, {
      orientation: "horizontal"
    }, /*#__PURE__*/_react["default"].createElement(_reactReflex.ReflexElement, {
      className: "title",
      maxSize: 20
    }, this.props.title), /*#__PURE__*/_react["default"].createElement(_reactReflex.ReflexElement, null, /*#__PURE__*/_react["default"].createElement(_reactReflex.ReflexContainer, {
      orientation: "vertical"
    }, /*#__PURE__*/_react["default"].createElement(_reactReflex.ReflexElement, {
      className: "map"
    }, /*#__PURE__*/_react["default"].createElement(_react2.DeckGL, {
      initialViewState: INITIAL_VIEW_STATE,
      controller: true,
      layers: layers
    }, /*#__PURE__*/_react["default"].createElement(_reactMapGl.StaticMap, {
      mapStyle: _carto.BASEMAP.DARK_MATTER
    }), this.state.hoverInfo.object && /*#__PURE__*/_react["default"].createElement("div", {
      className: "tooltip",
      style: {
        position: 'absolute',
        zIndex: 1,
        pointerEvents: 'none',
        left: this.state.hoverInfo.x,
        top: this.state.hoverInfo.y
      }
    }, this.props.hoverMessage(this.state.hoverInfo.object) + ": " + this.props.colorBy(this.state.hoverInfo.object).toLocaleString()), /*#__PURE__*/_react["default"].createElement(_AbsoluteLegend["default"], {
      title: this.props.legendTitle,
      colorScale: COLOR_SCALE,
      limits: this.state.limits,
      labels: this.props.legendLabels,
      steps: 5
    }))), /*#__PURE__*/_react["default"].createElement(_reactReflex.ReflexSplitter, null), /*#__PURE__*/_react["default"].createElement(_reactReflex.ReflexElement, {
      className: "plots"
    }, /*#__PURE__*/_react["default"].createElement("div", {
      id: "controls"
    }, /*#__PURE__*/_react["default"].createElement("input", {
      name: "per",
      type: "checkbox",
      checked: this.state.per,
      onChange: this.handleInputChange
    }), /*#__PURE__*/_react["default"].createElement("label", {
      htmlFor: "per"
    }, this.props.perText)), this.props.plots.map(function (p) {
      var data = _this3.state.hoverInfo.object ? _this3.state.hoverInfo.object.properties : _this3.state.aggregate;

      if (_this3.state.per) {
        data = _this3.props.perFunc(data);
      }

      return /*#__PURE__*/_react["default"].createElement(_reactPlotly["default"], {
        key: p.id,
        data: p.data(data),
        layout: {
          title: p.layout.title(_this3.state.hoverInfo.object),
          barmode: 'stack',
          height: 300
        },
        useResizeHandler: true,
        style: p.style || {
          width: "100%"
        }
      });
    })))));
  };

  return DecklyComponent;
}(_react["default"].Component);

function Deckly(props) {
  (0, _reactDom.render)( /*#__PURE__*/_react["default"].createElement(DecklyComponent, props), props.container || document.querySelector('#demo'));
}

module.exports = exports.default;