"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var d3 = require("d3");
var d3_1 = require("d3");
var Bar3DOptions_1 = require("./Bar3DOptions");
/**
 * Implementation of the '3d bar' markup element.
 */
var Bar3D = /** @class */ (function () {
    function Bar3D(options) {
        if (options === void 0) { options = new Bar3DOptions_1.default(); }
        this.mx = 0;
        this.my = 0;
        this.mouseX = 0;
        this.mouseY = 0;
        // runtime
        this.beta = 0;
        this.alpha = 0;
        // data
        this.yLine = [];
        this.scatter = [];
        this.xGrid = [];
        this.options = options;
    }
    /**
     * @inheritDoc
     */
    Bar3D.prototype.render = function () {
        var div = document.createElement("div");
        div.classList.add("lto-vis-bar3d");
        div.innerHTML = "<svg width=\"" + this.options.width + "\" height=\"" + this.options.height + "\" />";
        return div;
    };
    Bar3D.prototype.init = function (element) {
        var _this = this;
        this.options.data.then(function (data) {
            var grid3d = _this.init3DElement("GRID", 20);
            var point3d = _this.init3DElement("LINE");
            var yScale3d = _this.init3DElement("LINE_STRIP");
            var svg = d3.select(element.querySelector("svg"));
            svg.call(d3.drag()
                .on('drag', _this.dragged(svg, grid3d, point3d, yScale3d))
                .on('start', _this.dragStart.bind(_this))
                .on('end', _this.dragEnd.bind(_this))).append('g');
            d3_1.range(-10, 10).forEach(function (z) { return d3_1.range(-10, 10).forEach(function (x) { return _this.xGrid.push([x, 0, z]); }); });
            _this.scatter.push.apply(_this.scatter, data.map(function (e) { return [{ x: e.x, y: e.y, z: e.z }, { x: e.x, y: 0, z: e.z }]; }));
            d3_1.range(0, 11, 1).forEach(function (d) { return _this.yLine.push([-11, -d, -11]); });
            var barData = [
                grid3d(_this.xGrid),
                point3d(_this.scatter),
                yScale3d([_this.yLine])
            ];
            _this.processData(barData, _this.options.duration, svg, grid3d, yScale3d);
        });
    };
    Bar3D.prototype.init3DElement = function (shape, coords) {
        var d3_3d = require("d3-3d");
        var element = d3_3d._3d()
            .shape(shape, coords)
            .origin(this.options.origin(this.options.width, this.options.height))
            .rotateY(this.options.startAngle)
            .rotateX(-this.options.startAngle)
            .scale(this.options.scale);
        if (shape === "LINE") {
            element
                .x(function (d) { return d.x; })
                .y(function (d) { return d.y; })
                .z(function (d) { return d.z; });
        }
        return element;
    };
    Bar3D.prototype.processData = function (data, duration, svg, grid3d, yScale3d) {
        var _this = this;
        var xGrid = svg.selectAll('path.grid').data(data[0], function (d) { return d.id; });
        xGrid.enter()
            .append('path')
            .attr('class', function (d) { return '_3d grid ' + (d.ccw ? "ccw" : ""); })
            .merge(xGrid)
            .attr('d', grid3d.draw);
        xGrid.exit().remove();
        var lines = svg.selectAll('line').data(data[1], function (d) { return d.id; });
        lines
            .enter()
            .append('line')
            .attr('class', function (d) { return '_3d lto-vis-' + _this.options.toGroup(Math.abs(d[0].y)); })
            .attr('opacity', 0)
            .attr('x1', function (d) { return d[0].projected.x; })
            .attr('y1', function (d) { return d[0].projected.y; })
            .attr('x2', function (d) { return d[1].projected.x; })
            .attr('y2', function (d) { return d[1].projected.y; })
            .merge(lines)
            .transition().duration(duration)
            .attr('opacity', 1)
            .attr('x1', function (d) { return d[0].projected.x; })
            .attr('y1', function (d) { return d[0].projected.y; })
            .attr('x2', function (d) { return d[1].projected.x; })
            .attr('y2', function (d) { return d[1].projected.y; });
        lines.exit().remove();
        var yScale = svg.selectAll('path.yScale').data(data[2]);
        yScale.enter()
            .append('path')
            .attr('class', '_3d yScale legend')
            .merge(yScale)
            .attr('d', yScale3d.draw);
        yScale.exit().remove();
        this.renderLegendX(svg, data[0]);
        this.renderLegendY(svg, data[2][0]);
        this.renderLegendZ(svg, data[0]);
        var d3_3d = require("d3-3d");
        d3.selectAll('._3d').sort(d3_3d._3d().sort);
    };
    Bar3D.prototype.renderLegendX = function (svg, data) {
        var array = data.filter(function (e) { return e[0]["2"] === 9; }).map(function (e) { return e[0]; });
        var xText = svg.selectAll('text.xText').data(array);
        xText.enter()
            .append('text')
            .attr('class', '_3d xText')
            .attr('dx', '.3em')
            .merge(xText)
            .each(function (d) { return d.centroid = { x: d.rotated.x, y: d.rotated.y, z: d.rotated.z }; })
            .attr('x', function (d) { return d.projected.x; })
            .attr('y', function (d) { return d.projected.y; })
            .text(this.options.textX);
        xText.exit().remove();
    };
    Bar3D.prototype.renderLegendY = function (svg, data) {
        var yText = svg.selectAll('text.yText').data(data);
        yText.enter()
            .append('text')
            .attr('class', '_3d yText')
            .attr('dx', '.3em')
            .merge(yText)
            .each(function (d) { return d.centroid = { x: d.rotated.x, y: d.rotated.y, z: d.rotated.z }; })
            .attr('x', function (d) { return d.projected.x; })
            .attr('y', function (d) { return d.projected.y; })
            .text(this.options.textY);
        yText.exit().remove();
    };
    Bar3D.prototype.renderLegendZ = function (svg, data) {
        var array = data.filter(function (e) { return e[0]["0"] === 9; }).map(function (e) { return e[0]; });
        var zText = svg.selectAll('text.zText').data(array);
        zText
            .enter()
            .append('text')
            .attr('class', '_3d zText')
            .attr('dx', '.3em')
            .merge(zText)
            .each(function (d) { return d.centroid = { x: d.rotated.x, y: d.rotated.y, z: d.rotated.z }; })
            .attr('x', function (d) { return d.projected.x; })
            .attr('y', function (d) { return d.projected.y; })
            .text(this.options.textZ);
        zText.exit().remove();
    };
    Bar3D.prototype.dragStart = function () {
        this.mx = d3.event.x;
        this.my = d3.event.y;
    };
    Bar3D.prototype.dragged = function (svg, grid3d, point3d, yScale3d) {
        var _this = this;
        return function () {
            _this.mouseX = _this.mouseX || 0;
            _this.mouseY = _this.mouseY || 0;
            _this.beta = (d3.event.x - _this.mx + _this.mouseX) * Math.PI / 230;
            _this.alpha = (d3.event.y - _this.my + _this.mouseY) * Math.PI / 230 * (-1);
            var data = [
                grid3d.rotateY(_this.beta + _this.options.startAngle).rotateX(_this.alpha - _this.options.startAngle)(_this.xGrid),
                point3d.rotateY(_this.beta + _this.options.startAngle).rotateX(_this.alpha - _this.options.startAngle)(_this.scatter),
                yScale3d.rotateY(_this.beta + _this.options.startAngle).rotateX(_this.alpha - _this.options.startAngle)([_this.yLine]),
            ];
            _this.processData(data, 0, svg, grid3d, yScale3d);
        };
    };
    Bar3D.prototype.dragEnd = function () {
        this.mouseX = d3.event.x - this.mx + this.mouseX;
        this.mouseY = d3.event.y - this.my + this.mouseY;
    };
    return Bar3D;
}());
exports.Bar3D = Bar3D;
//# sourceMappingURL=Bar3D.js.map