import * as tslib_1 from "tslib";
import { round, similar, dragHandle } from '../../internal';
import ADialog from './ADialog';
import { cssClass } from '../../styles';
function clamp(v) {
    return Math.max(Math.min(v, 100), 0);
}
/** @internal */
var MappingLineDialog = /** @class */ (function (_super) {
    tslib_1.__extends(MappingLineDialog, _super);
    function MappingLineDialog(line, dialog, adapter) {
        var _this = _super.call(this, dialog) || this;
        _this.line = line;
        _this.adapter = adapter;
        return _this;
    }
    MappingLineDialog.prototype.build = function (node) {
        var _this = this;
        var domain = this.adapter.domain();
        node.insertAdjacentHTML('beforeend', "\n        <strong>Input Domain Value (min ... max)</strong>\n        <input type=\"number\" value=\"" + round(this.adapter.unnormalizeRaw(this.line.domain), 3) + "\" " + (this.line.frozen ? 'readonly' : '') + " autofocus required min=\"" + domain[0] + "\" max=\"" + domain[1] + "\" step=\"any\">\n        <strong>Output Normalized Value (0 ... 1)</strong>\n        <input type=\"number\" value=\"" + round(this.line.range / 100, 3) + "\" required min=\"0\" max=\"1\" step=\"any\">\n        <button type=\"button\" " + (this.line.frozen ? 'disabled' : '') + " >Remove Mapping Line</button>\n      ");
        this.forEach('input', function (d) { return d.onchange = function () { return _this.submit(); }; });
        this.find('button').addEventListener('click', function () {
            _this.destroy();
            _this.line.destroy();
        }, {
            passive: true
        });
    };
    MappingLineDialog.prototype.submit = function () {
        if (!this.node.checkValidity()) {
            return false;
        }
        var domain = this.adapter.normalizeRaw(this.findInput('input[type=number]').valueAsNumber);
        var range = this.findInput('input[type=number]:last-of-type').valueAsNumber * 100;
        this.line.update(domain, range);
        return true;
    };
    return MappingLineDialog;
}(ADialog));
export default MappingLineDialog;
/** @internal */
var MappingLine = /** @class */ (function () {
    function MappingLine(g, domain, range, adapter) {
        var _this = this;
        this.domain = domain;
        this.range = range;
        this.adapter = adapter;
        g.insertAdjacentHTML('beforeend', "<g class=\"" + cssClass('dialog-mapper-mapping') + "\" transform=\"translate(" + domain + ",0)\">\n      <line x1=\"0\" x2=\"" + (range - domain) + "\" y2=\"60\"></line>\n      <line x1=\"0\" x2=\"" + (range - domain) + "\" y2=\"60\"></line>\n      <circle r=\"3\"></circle>\n      <circle cx=\"" + (range - domain) + "\" cy=\"60\" r=\"3\"></circle>\n      <title>Drag the anchor circle to change the mapping, shift click to edit</title>\n    </g>");
        this.node = g.lastElementChild;
        // freeze 0 and 100 domain = raw domain ones
        this.node.classList.toggle(cssClass('frozen'), similar(0, domain) || similar(domain, 100));
        {
            var beforeDomain_1;
            var beforeRange_1;
            var shiftDomain_1;
            var shiftRange_1;
            var normalize_1 = function (x) { return x * 100 / g.getBoundingClientRect().width; };
            var common = {
                container: g.parentElement,
                filter: function (evt) { return evt.button === 0 && !evt.shiftKey; },
                onStart: function (_, x) {
                    beforeDomain_1 = _this.domain;
                    beforeRange_1 = _this.range;
                    var normalized = normalize_1(x);
                    shiftDomain_1 = _this.domain - normalized;
                    shiftRange_1 = _this.range - normalized;
                },
                onEnd: function () {
                    if (!similar(beforeDomain_1, _this.domain) || !similar(beforeRange_1, _this.range)) {
                        _this.adapter.updated(_this);
                    }
                }
            };
            var line = this.node.querySelector('line:first-of-type');
            dragHandle(line, tslib_1.__assign({}, common, { onDrag: function (_, x) {
                    var normalized = normalize_1(x);
                    _this.update(clamp(normalized + shiftDomain_1), clamp(normalized + shiftRange_1));
                } }));
            var domainCircle = this.node.querySelector('circle:first-of-type');
            dragHandle(domainCircle, tslib_1.__assign({}, common, { onDrag: function (_, x) {
                    var normalized = normalize_1(x);
                    _this.update(clamp(normalized), _this.range);
                } }));
            var rangeCircle = this.node.querySelector('circle:last-of-type');
            dragHandle(rangeCircle, tslib_1.__assign({}, common, { onDrag: function (_, x) {
                    var normalized = normalize_1(x);
                    _this.update(_this.domain, clamp(normalized));
                } }));
        }
        this.node.onclick = function (evt) {
            if (!evt.shiftKey) {
                return;
            }
            var ctx = {
                manager: _this.adapter.dialog.manager,
                level: _this.adapter.dialog.level + 1,
                attachment: _this.node,
                idPrefix: _this.adapter.dialog.idPrefix
            };
            var dialog = new MappingLineDialog(_this, ctx, _this.adapter);
            dialog.open();
        };
    }
    Object.defineProperty(MappingLine.prototype, "frozen", {
        get: function () {
            return this.node.classList.contains(cssClass('frozen'));
        },
        enumerable: true,
        configurable: true
    });
    MappingLine.prototype.destroy = function () {
        this.node.remove();
        this.adapter.destroyed(this);
    };
    MappingLine.prototype.update = function (domain, range) {
        if (similar(domain, this.domain) && similar(range, this.range)) {
            return;
        }
        if (this.frozen) {
            domain = this.domain;
        }
        this.domain = domain;
        this.range = range;
        this.node.setAttribute('transform', "translate(" + domain + ",0)");
        var shift = range - domain;
        Array.from(this.node.querySelectorAll('line')).forEach(function (d) { return d.setAttribute('x2', String(shift)); });
        this.node.querySelector('circle[cx]').setAttribute('cx', String(shift));
    };
    return MappingLine;
}());
export { MappingLine };
//# sourceMappingURL=MappingLineDialog.js.map