"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Ranges = void 0;
var tslib_1 = require("tslib");
var react_1 = tslib_1.__importStar(require("react"));
var v_eris_1 = require("v-eris");
require("./types.ranges.scss");
var RangesFloatType = function (value, isFloat) {
    return isFloat ? (v_eris_1.Common.float(value)) : v_eris_1.Common.int(value);
};
var RangesToString = function (array, isSingle) {
    var result = "";
    if (isSingle)
        return v_eris_1.Common.string(array[0]);
    for (var _i = 0, array_1 = array; _i < array_1.length; _i++) {
        var item = array_1[_i];
        result += item[0] + "-" + item[1] + ", ";
    }
    ;
    if (result.length > 2)
        result = result.substring(0, result.length - 2);
    return result;
};
var RangesToArray = function (v, isSingle, isMulti, min, max, isFloat) {
    var value = v;
    if (!Array.isArray(value)) {
        if (typeof value == "number") {
            value = [v];
        }
        else if (typeof v == "string") {
            var s_3 = [];
            var pairs = v_eris_1.Common.string(v || "").split(/\,/g);
            for (var key in pairs) {
                pairs[key] = pairs[key].trim();
                if (!pairs[key].length)
                    continue;
                if (!isMulti) {
                    s_3.push(RangesFloatType(pairs[key], isFloat));
                    continue;
                }
                ;
                var subPair = v_eris_1.Common.string(pairs[key]).split(/\-/g);
                var subPairParsed = [
                    RangesFloatType(subPair[0], isFloat),
                    RangesFloatType(subPair[1], isFloat),
                ];
                if (subPairParsed[1] < subPairParsed[0])
                    subPairParsed[1] = subPairParsed[0];
                s_3.push(subPairParsed);
            }
            ;
            value = s_3;
        }
        else {
            value = [];
        }
        ;
    }
    ;
    if (isSingle)
        return [v_eris_1.VMath.clamp(RangesFloatType(Array.isArray(value) ? value[0] : value, isFloat), min, max)];
    var s = [];
    var p = [];
    for (var _i = 0, value_1 = value; _i < value_1.length; _i++) {
        var item = value_1[_i];
        if (Array.isArray(item)) {
            if (p.length) {
                s.push(tslib_1.__spreadArray([], p, true));
                p = [];
            }
            ;
            s.push(tslib_1.__spreadArray([], item, true));
            continue;
        }
        ;
        if (p.length > 1) {
            s.push(tslib_1.__spreadArray([], p, true));
            p = [];
        }
        ;
        p.push(item);
    }
    ;
    if (p.length) {
        s.push(tslib_1.__spreadArray([], p, true));
        p = [];
    }
    ;
    if (!isMulti && s.length > 1) {
        s.length = 1;
    }
    ;
    for (var _a = 0, s_1 = s; _a < s_1.length; _a++) {
        var item = s_1[_a];
        item[0] = v_eris_1.VMath.clamp(item[0], min, max);
        item[1] = v_eris_1.VMath.clamp(item[1], min, max);
        if (item.length > 1 && item[1] < item[0]) {
            var temp = item[0];
            item[0] = item[1];
            item[1] = temp;
        }
        ;
    }
    ;
    s.sort(function (a, b) { return a[0] - b[0]; });
    var prev = null;
    for (var _b = 0, s_2 = s; _b < s_2.length; _b++) {
        var item = s_2[_b];
        if (prev && prev[1] > item[0])
            prev[1] = prev[0];
        prev = item;
    }
    ;
    return s;
};
var Ranges = function (props) {
    var className = props.className, min = props.min, max = props.max, step = props.step, grid = props.grid, input = props.input, separated = props.separated, inactive = props.inactive, onChange = props.onChange, rest = tslib_1.__rest(props, ["className", "min", "max", "step", "grid", "input", "separated", "inactive", "onChange"]);
    if (input !== false)
        input = true;
    if (!onChange)
        onChange = function () { };
    var isSingle = props.single;
    var isMulti = props.multi;
    var isFloat = props.float;
    min = RangesFloatType(min, isFloat);
    max = RangesFloatType(max, isFloat);
    var v = RangesToArray(props.value, isSingle, isMulti, min, max, isFloat);
    var _a = (0, react_1.useState)(v), ranges = _a[0], setRanges = _a[1];
    var _b = (0, react_1.useState)(false), hovered = _b[0], setHovered = _b[1];
    var _c = (0, react_1.useState)(0), rangeValue = _c[0], setRangeValue = _c[1];
    var wrapRef = (0, react_1.useRef)(null);
    var _d = (0, react_1.useState)(false), isFocused = _d[0], setIsFocused = _d[1];
    var _e = (0, react_1.useState)(""), focusedValue = _e[0], setFocusedValue = _e[1];
    var drag = (0, react_1.useRef)({
        dragging: false,
        index: 0,
        subIndex: 0,
        value: 0,
        c: 0, //temp value
        offset: { x: 0, y: 0 }
    });
    step = step === undefined ? 1 : RangesFloatType(step, isFloat);
    var distance = (max - min) * 1.0;
    var percent = ((ranges[0] || 0) - min) / distance * 100.0;
    var parsedText = RangesToString(ranges, isSingle);
    (0, react_1.useEffect)(function () {
        setRanges(v);
    }, [props.value]);
    var stopDragging = function (e) {
        if (!drag.current.dragging)
            return;
        drag.current.dragging = false;
    };
    var computeValue = function (e, offset) {
        var xShift = (offset.width / (distance || 1)) * (isFloat ? 0.0 : 0.5);
        var x = v_eris_1.VMath.clamp(e.clientX + (0 + xShift) - offset.x, 0, offset.width) / (offset.width * 1.0);
        var y = v_eris_1.VMath.clamp(e.clientY - offset.y, 0, offset.height) / (offset.height * 1.0);
        var c = RangesFloatType(x * distance, isFloat);
        if (isFloat) {
            c = v_eris_1.Common.int((c * 100000.0) / (step * 100000.0)) * step;
            c = +c.toFixed(4);
        }
        else {
            c = v_eris_1.Common.int((c / step)) * step;
        }
        ;
        c += min;
        if (!c)
            c = 0;
        return { x: x, y: y, c: c };
    };
    var computeRange = function (c, alter, align) {
        var array = isSingle ? [] : tslib_1.__spreadArray([], ranges, true);
        var index = drag.current.index;
        var subIndex = drag.current.subIndex;
        if (isSingle) {
            if (alter)
                array.splice(index, 1);
            array.push(c);
            drag.current.value = c;
            drag.current.index = array.indexOf(drag.current.value);
            if (drag.current.index < 0)
                drag.current.index = 0;
            setRanges(array);
        }
        else {
            if (isMulti && !alter) {
                var length_1 = array.length;
                var inside = false;
                for (var n = 0; n < length_1; n++) {
                    var item = array[n];
                    if (c > item[0] && c < item[1]) {
                        inside = true;
                        index = n;
                        break;
                    }
                    ;
                    if (c > item[1]) {
                        index = n + 1;
                    }
                    ;
                }
                ;
                if (index >= length_1) {
                    array.push([c, c]);
                }
                else if (!inside) {
                    array.splice(index, 0, [c, c]);
                }
                ;
            }
            ;
            var subArray = tslib_1.__spreadArray([], (isMulti ? (array[index] || array[0]) : array[0]), true);
            var p0 = subArray[0] || min;
            var p1 = subArray[1] || min;
            if (c < p0) {
                subArray = [c, p1];
                drag.current.subIndex = 0;
            }
            else if (c > p1) {
                subArray = [p0, c];
                drag.current.subIndex = 1;
            }
            else {
                subArray = subIndex < 1 ? [c, p1] : [p0, c];
                drag.current.subIndex = subIndex < 1 ? 0 : 1;
            }
            ;
            if (array[index])
                array[index] = tslib_1.__spreadArray([], subArray, true);
            drag.current.index = index;
            drag.current.value = c;
            setRanges(array);
        }
        ;
        onChange({ value: isSingle ? array[0] : (isMulti ? array : array[0]) });
    };
    var moveDragging = function (e) {
        if (!wrapRef.current)
            return;
        if (!hovered && !drag.current.dragging)
            return;
        drag.current.offset = v_eris_1.Common.offset(wrapRef.current);
        var _a = computeValue(e, drag.current.offset), x = _a.x, y = _a.y, c = _a.c;
        drag.current.c = c;
        setRangeValue(c);
        if (!drag.current.dragging)
            return;
        computeRange(c, true, true);
    };
    (0, react_1.useEffect)(function () {
        window.document.addEventListener("mouseup", stopDragging);
        return function () {
            window.document.removeEventListener("mouseup", stopDragging);
        };
    }, []);
    (0, react_1.useEffect)(function () {
        window.document.addEventListener("mousemove", moveDragging);
        return function () {
            window.document.removeEventListener("mousemove", moveDragging);
        };
    }, [ranges, isSingle, hovered]);
    var gridElements = (0, react_1.useMemo)(function () {
        var lines = [];
        if (!grid)
            return lines;
        var s = isFloat ? (v_eris_1.Common.uint(step) || 1) : step;
        for (var n = min, limit = max + 1; n < limit; n += s) {
            lines.push(react_1.default.createElement("div", { key: n, className: "ranges-grid-mark", style: {
                    left: ((n - min) / distance * 100.0) + "%",
                } },
                react_1.default.createElement("span", null, n)));
        }
        ;
        return lines;
    }, [min, max]);
    var createDotElement = function (pair, v, index, subIndex) {
        return (react_1.default.createElement("div", { className: "ranges-item", key: "range:" + v + ":" + index + ":" + subIndex, style: {
                left: ((v - min) / distance * 100.0) + "%",
                width: (((subIndex + 1) < pair.length ? (pair[subIndex + 1] - v) : (0)) / distance * 100.0) + "%",
            } },
            react_1.default.createElement("div", { className: "ranges-item-dot", onMouseDown: function (e) {
                    e.stopPropagation();
                    e.preventDefault();
                    if (inactive)
                        return;
                    drag.current.dragging = true;
                    drag.current.index = index;
                    drag.current.subIndex = subIndex;
                    drag.current.value = v;
                    drag.current.offset = v_eris_1.Common.offset(wrapRef.current);
                }, onContextMenu: function (e) {
                    if (inactive)
                        return;
                    e.stopPropagation();
                    e.preventDefault();
                    if (isSingle)
                        return;
                    var array = tslib_1.__spreadArray([], ranges, true);
                    array.splice(index, 1);
                    setRanges(array);
                    onChange({ value: isSingle ? array[0] : (isMulti ? array : array[0]) });
                } },
                react_1.default.createElement("span", null)),
            react_1.default.createElement("div", { className: "ranges-item-bg" })));
    };
    return (react_1.default.createElement("div", { className: v_eris_1.Props.className("ranges", className, { gridless: !grid, separated: separated, inactive: inactive }) },
        input && !inactive ?
            (react_1.default.createElement(v_eris_1.Row, null,
                react_1.default.createElement(v_eris_1.Input, { className: "ranges-input", onChange: function (e) {
                        setFocusedValue(e.value);
                        var array = RangesToArray(e.value, isSingle, isMulti, min, max, isFloat);
                        setRanges(array);
                        onChange({ value: isSingle ? array[0] : (isMulti ? array : array[0]) });
                    }, onKeyDown: function (e) {
                        if (e.event.which == 13) {
                            var array = RangesToArray(e.value, isSingle, isMulti, min, max, isFloat);
                            setRanges(array);
                            setFocusedValue(RangesToString(array, isSingle));
                            onChange({ value: isSingle ? array[0] : (isMulti ? array : array[0]) });
                        }
                        ;
                    }, onFocus: function (e) {
                        setFocusedValue(parsedText);
                        setIsFocused(true);
                    }, onBlur: function (e) {
                        setIsFocused(false);
                        var array = tslib_1.__spreadArray([], ranges, true);
                        onChange({ value: isSingle ? array[0] : (isMulti ? array : array[0]) });
                    } }, isFocused ? focusedValue : parsedText),
                react_1.default.createElement(v_eris_1.Text, { className: "ranges-input-params" }, "[ " + min + ", " + max + " ]")))
            :
                null,
        react_1.default.createElement(v_eris_1.Tooltip, { content: (react_1.default.createElement("div", null,
                react_1.default.createElement("div", null, rangeValue))), style: {
                opacity: inactive ? "0" : null,
                pointerEvents: inactive ? "none" : null,
            } },
            react_1.default.createElement("div", { className: "ranges-wrap", onMouseEnter: function () { return setHovered(true); }, onMouseLeave: function () { return setHovered(false); } },
                inactive ? (react_1.default.createElement(v_eris_1.Input, { inactive: true }, parsedText)) : null,
                react_1.default.createElement("div", { className: "ranges-list", ref: wrapRef, onMouseDown: function (e) {
                        if (inactive) {
                            e.stopPropagation();
                            e.preventDefault();
                            return;
                        }
                        ;
                        if (e.button != 0)
                            return;
                        e.preventDefault();
                        drag.current.offset = v_eris_1.Common.offset(wrapRef.current);
                        var _a = computeValue(e, drag.current.offset), x = _a.x, y = _a.y, c = _a.c;
                        computeRange(c, false);
                        drag.current.dragging = true;
                    }, onContextMenu: function (e) {
                        if (inactive) {
                            e.stopPropagation();
                            e.preventDefault();
                            return;
                        }
                        ;
                        e.stopPropagation();
                        e.preventDefault();
                    } },
                    react_1.default.createElement("span", { className: v_eris_1.Props.className("ranges-value", { hidden: !isSingle, flip: percent > 80 }), style: { left: (percent) + "%" } }, isSingle ? ranges[0] : null),
                    ranges.map(function (value, index) {
                        if (!isSingle) {
                            var pair = value;
                            if (pair.length > 1) {
                                return [
                                    createDotElement(pair, value[0], index, 0),
                                    createDotElement(pair, value[1], index, 1)
                                ];
                            }
                            ;
                            return createDotElement(pair, value[0], index, 0);
                        }
                        ;
                        return createDotElement(ranges, value, index, 0);
                    })),
                react_1.default.createElement("div", { className: "ranges-line" }),
                react_1.default.createElement("div", { className: "ranges-grid" }, gridElements)))));
};
exports.Ranges = Ranges;
//# sourceMappingURL=types.ranges.js.map