import * as tslib_1 from "tslib";
import ADialog from './ADialog';
import { schemeCategory10, schemeSet1, schemeSet2, schemeSet3, schemeAccent, schemeDark2, schemePastel2, schemePastel1 } from 'd3-scale-chromatic';
import { round } from '../../internal';
import { uniqueId } from '../../renderer/utils';
import { QuantizedColorFunction, CustomColorMappingFunction, SolidColorFunction, SequentialColorFunction, DivergentColorFunction } from '../../model/ColorMappingFunction';
import { DEFAULT_COLOR } from '../../model';
import { cssClass } from '../../styles';
/** @internal */
var ColorMappingDialog = /** @class */ (function (_super) {
    tslib_1.__extends(ColorMappingDialog, _super);
    function ColorMappingDialog(column, dialog) {
        var _this = _super.call(this, dialog) || this;
        _this.column = column;
        return _this;
    }
    ColorMappingDialog.prototype.build = function (node) {
        node.classList.add(cssClass('dialog-color'));
        var id = uniqueId('col');
        var current = this.column.getColorMapping();
        var entries = current instanceof CustomColorMappingFunction ? current.entries : [];
        var h = '';
        h += "<datalist id=\"" + id + "L\">" + schemeCategory10.map(function (d) { return "<option>" + d + "\"</option>"; }).join('') + "</datalist>";
        h += "<datalist id=\"" + id + "LW\"><option>#FFFFFF\"</option>" + schemeCategory10.slice(0, -1).map(function (d) { return "<option>" + d + "</option>"; }).join('') + "</datalist>";
        h += "<strong>Quantization</strong>\n    <label class=\"" + cssClass('checkbox') + "\">\n      <input name=\"kind\" type=\"radio\" id=\"" + id + "KC\" value=\"continuous\" " + (!(current instanceof QuantizedColorFunction) ? 'checked' : '') + ">\n      <span>Continuous</span>\n    </label>\n    <label class=\"" + cssClass('checkbox') + "\">\n      <input name=\"kind\" type=\"radio\" id=\"" + id + "KQ\" value=\"quantized\" " + (current instanceof QuantizedColorFunction ? 'checked' : '') + ">\n      <span><input type=\"number\" id=\"" + id + "KQS\" min=\"2\" step=\"1\" value=\"" + (current instanceof QuantizedColorFunction ? current.steps : 5) + "\">&nbsp; steps</span>\n    </label>";
        h += "<strong data-toggle=\"" + (current instanceof SolidColorFunction ? 'open' : '') + "\">Solid Color</strong>";
        h += "<div>";
        {
            var refColor_1 = current instanceof SolidColorFunction ? current.color : '';
            var has = false;
            var colorsets = [schemeCategory10, schemeAccent, schemeDark2, schemePastel1, schemePastel2, schemeSet1, schemeSet2, schemeSet3];
            for (var _i = 0, colorsets_1 = colorsets; _i < colorsets_1.length; _i++) {
                var colors = colorsets_1[_i];
                has = has || colors.includes(refColor_1);
                h += "<div class=\"" + cssClass('color-line') + "\">\n          " + colors.map(function (d) { return "<label class=\"" + cssClass('checkbox-color') + "\">\n              <input name=\"color\" type=\"radio\" value=\"" + d + "\" " + (d === refColor_1 ? 'checked="checked"' : '') + ">\n              <span style=\"background: " + d + "\"></span>\n            </label>"; }).join('') + "\n        </div>";
            }
            h += "<label class=\"" + cssClass('checkbox') + " " + cssClass('color-gradient') + "\"><input name=\"color\" type=\"radio\" value=\"custom:solid\" " + (refColor_1 && !has ? 'checked="checked"' : '') + ">\n        <span class=\"" + cssClass('color-custom') + "\"><input type=\"color\" name=\"solid\" list=\"" + id + "L\" value=\"" + (current instanceof SolidColorFunction ? current.color : DEFAULT_COLOR) + "\" " + (refColor_1 && !has ? '' : 'disabled') + "></span>\n      </label>";
        }
        h += '</div>';
        h += "<strong data-toggle=\"" + (current instanceof SequentialColorFunction || (current instanceof CustomColorMappingFunction && entries.length === 2) ? 'open' : '') + "\">Sequential Color</strong>";
        h += '<div>';
        {
            var name_1 = current instanceof SequentialColorFunction ? current.name : '';
            for (var _a = 0, _b = Object.keys(SequentialColorFunction.FUNCTIONS); _a < _b.length; _a++) {
                var colors = _b[_a];
                h += "<label class=\"" + cssClass('checkbox') + " " + cssClass('color-gradient') + "\"><input name=\"color\" type=\"radio\" value=\"" + colors + "\" " + (colors === name_1 ? 'checked="checked"' : '') + ">\n        <span data-c=\"" + colors + "\" style=\"background: " + gradient(SequentialColorFunction.FUNCTIONS[colors], 9) + "\"></span>\n      </label>";
            }
            var isCustom = entries.length === 2;
            h += "<label class=\"" + cssClass('checkbox') + " " + cssClass('color-gradient') + "\">\n        <input name=\"color\" type=\"radio\" value=\"custom:sequential\" " + (isCustom ? 'checked' : '') + ">\n        <span class=\"" + cssClass('color-custom') + "\">\n          <input type=\"color\" name=\"interpolate0\" list=\"" + id + "LW\" " + (!isCustom ? 'disabled' : "value=\"" + entries[0].color + "\"") + ">\n          <input type=\"color\" name=\"interpolate1\" list=\"" + id + "LW\" " + (!isCustom ? 'disabled' : "value=\"" + entries[entries.length - 1].color + "\"") + ">\n        </span>\n      </label>";
        }
        h += '</div>';
        h += "<strong data-toggle=\"" + (current instanceof DivergentColorFunction || (current instanceof CustomColorMappingFunction && entries.length === 3) ? 'open' : '') + "\">Diverging Color</strong>";
        h += '<div>';
        {
            var name_2 = current instanceof SequentialColorFunction ? current.name : '';
            for (var _c = 0, _d = Object.keys(DivergentColorFunction.FUNCTIONS); _c < _d.length; _c++) {
                var colors = _d[_c];
                h += "<label class=\"" + cssClass('checkbox') + " " + cssClass('color-gradient') + "\"><input name=\"color\" type=\"radio\" value=\"" + colors + "\" " + (colors === name_2 ? 'checked="checked"' : '') + ">\n        <span data-c=\"" + colors + "\" style=\"background: " + gradient(DivergentColorFunction.FUNCTIONS[colors], 11) + "\"></span>\n      </label>";
            }
            var isCustom = entries.length === 3;
            h += "<label class=\"" + cssClass('checkbox') + " " + cssClass('color-gradient') + "\">\n        <input name=\"color\" type=\"radio\" value=\"custom:divergent\" " + (isCustom ? 'checked' : '') + ">\n        <span class=\"" + cssClass('color-custom') + "\">\n          <input type=\"color\" name=\"divergingm1\" list=\"" + id + "L\" " + (!isCustom ? 'disabled' : "value=\"" + entries[0].color + "\"") + ">\n          <input type=\"color\" name=\"diverging0\" list=\"" + id + "LW\" " + (!isCustom ? 'disabled' : "value=\"" + entries[1].color + "\"") + ">\n          <input type=\"color\" name=\"diverging1\" list=\"" + id + "L\" " + (!isCustom ? 'disabled' : "value=\"" + entries[2].color + "\"") + ">\n        </span>\n      </label>";
        }
        h += '</div>';
        node.insertAdjacentHTML('beforeend', h);
        this.interactive(node, id);
    };
    ColorMappingDialog.prototype.interactive = function (node, id) {
        var _this = this;
        var continuouos = this.findInput("#" + id + "KC");
        var quantized = this.findInput("#" + id + "KQ");
        var steps = this.findInput("#" + id + "KQS");
        var toggles = Array.from(node.querySelectorAll('strong[data-toggle]'));
        var _loop_1 = function (toggle) {
            toggle.onclick = function (evt) {
                evt.preventDefault();
                evt.stopPropagation();
                for (var _i = 0, toggles_2 = toggles; _i < toggles_2.length; _i++) {
                    var t2 = toggles_2[_i];
                    t2.dataset.toggle = t2.dataset.toggle === 'open' || toggle !== t2 ? '' : 'open';
                }
            };
        };
        for (var _i = 0, toggles_1 = toggles; _i < toggles_1.length; _i++) {
            var toggle = toggles_1[_i];
            _loop_1(toggle);
        }
        var customs = [];
        var toColor = function (input) {
            switch (input.value) {
                case 'custom:solid':
                    return new SolidColorFunction(node.querySelector('input[name=solid]').value);
                case 'custom:sequential':
                    var s0 = node.querySelector('input[name=interpolate0]').value;
                    var s1 = node.querySelector('input[name=interpolate1]').value;
                    return new CustomColorMappingFunction([{ color: s0, value: 0 }, { color: s1, value: 1 }]);
                case 'custom:diverging':
                    var dm1 = node.querySelector('input[name=divergentm1]').value;
                    var d0 = node.querySelector('input[name=divergent0]').value;
                    var d1 = node.querySelector('input[name=divergent1]').value;
                    return new CustomColorMappingFunction([{ color: dm1, value: 0 }, { color: d0, value: 0.5 }, { color: d1, value: 1 }]);
            }
            if (input.value in SequentialColorFunction.FUNCTIONS) {
                return new SequentialColorFunction(input.value);
            }
            if (input.value in DivergentColorFunction.FUNCTIONS) {
                return new DivergentColorFunction(input.value);
            }
            return new SolidColorFunction(input.value);
        };
        var updateColor = function (d) {
            if (!d.checked) {
                return;
            }
            var _loop_2 = function (custom) {
                Array.from(custom.nextElementSibling.getElementsByTagName('input')).forEach(function (s) { return s.disabled = custom !== d; });
            };
            // disable customs
            for (var _i = 0, customs_1 = customs; _i < customs_1.length; _i++) {
                var custom = customs_1[_i];
                _loop_2(custom);
            }
            var base = toColor(d);
            if (quantized.checked && !(base instanceof SolidColorFunction)) {
                _this.column.setColorMapping(new QuantizedColorFunction(base, parseInt(steps.value, 10)));
            }
            else {
                _this.column.setColorMapping(base);
            }
        };
        var updateSelectedColor = function () {
            var selected = _this.findInput("input[name=color]:checked");
            if (selected) {
                updateColor(selected);
            }
        };
        this.forEach('input[name=color]', function (d) {
            if (d.value.startsWith('custom:')) {
                customs.push(d);
            }
            d.onchange = function () { return updateColor(d); };
        });
        // upon changing custom parameter trigger an update
        this.forEach("." + cssClass('color-custom') + " input[type=color]", function (d) {
            d.onchange = function () {
                var item = d.parentElement.previousElementSibling;
                updateColor(item);
            };
        });
        continuouos.onchange = function () {
            if (continuouos.checked) {
                _this.updateGradients(-1);
                updateSelectedColor();
            }
        };
        quantized.onchange = steps.onchange = function () {
            if (!quantized.checked) {
                _this.updateGradients(-1);
                updateSelectedColor();
                return;
            }
            if (toggles[0].dataset.toggle === 'open') {
                // auto open sequential
                toggles[0].dataset.toggle = '';
                toggles[1].dataset.toggle = 'open';
            }
            _this.updateGradients(parseInt(steps.value, 10));
            updateSelectedColor();
        };
    };
    ColorMappingDialog.prototype.updateGradients = function (steps) {
        this.forEach("span[data-c]", function (d) {
            var key = d.dataset.c;
            var s = SequentialColorFunction.FUNCTIONS[key];
            if (s) {
                d.style.background = steps < 0 ? gradient(s, 9) : steppedGradient(s, steps);
                return;
            }
            var di = DivergentColorFunction.FUNCTIONS[key];
            if (di) {
                d.style.background = steps < 0 ? gradient(di, 11) : steppedGradient(di, steps);
                return;
            }
        });
    };
    return ColorMappingDialog;
}(ADialog));
export default ColorMappingDialog;
function gradient(interpolate, steps) {
    if (steps === void 0) { steps = 2; }
    if (steps <= 1) {
        return "" + interpolate(0);
    }
    var stepSize = 1 / (steps - 1);
    var r = "linear-gradient(to right";
    for (var i = 0; i < steps; ++i) {
        r += ", " + interpolate(i * stepSize) + " " + round((i * stepSize) * 100, 2) + "%";
    }
    r += ')';
    return r;
}
function steppedGradient(color, count) {
    if (count === void 0) { count = 2; }
    if (count === 1) {
        return "" + color(0);
    }
    var r = "linear-gradient(to right";
    var stepSize = 1 / count;
    var half = stepSize / 2;
    for (var i = 0; i < count; ++i) {
        // stepped
        // first and last at border else center
        var shift = i === 0 ? 0 : (i === (count - 1) ? stepSize : half);
        var c = color(i * stepSize + shift);
        r += ", " + c + " " + round((i * stepSize) * 100, 2) + "%, " + c + " " + round(((i + 1) * stepSize) * 100, 2) + "%";
    }
    r += ')';
    return r;
}
//# sourceMappingURL=ColorMappingDialog.js.map