"use strict";
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __read = (this && this.__read) || function (o, n) {
    var m = typeof Symbol === "function" && o[Symbol.iterator];
    if (!m) return o;
    var i = m.call(o), r, ar = [], e;
    try {
        while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
    }
    catch (error) { e = { error: error }; }
    finally {
        try {
            if (r && !r.done && (m = i["return"])) m.call(i);
        }
        finally { if (e) throw e.error; }
    }
    return ar;
};
Object.defineProperty(exports, "__esModule", { value: true });
var csstips = require("csstips/lib");
var React = require("react");
var react_redux_1 = require("react-redux");
var react_resize_detector_1 = require("react-resize-detector");
var lib_1 = require("typestyle/lib");
var useTypedSelector_1 = require("../hooks/useTypedSelector");
var palette_1 = require("../redux/palette");
var MenuBar_1 = require("./MenuBar");
var padding = 4;
var transparent = 'rgba(255,255,255,0)';
var color = 'rgba(255,255,255,1)';
var tileSize = 32 + 1;
var floatThrethold = 300;
var cn = {
    root: lib_1.style(csstips.vertical, {
        flexBasis: floatThrethold,
        height: '100%',
        position: 'relative',
        $nest: {
            '&>*': {
                height: '100%'
            }
        }
    }),
    floating: lib_1.style({
        position: 'absolute',
        right: 0,
        top: 0,
        display: 'flex'
    }),
    resizeWrapper: lib_1.style({
        transition: 'width 250ms',
        backgroundColor: 'rgb(218,218,218)',
        overflow: 'hidden'
    }),
    collapsed: lib_1.style({
        width: 0
    }),
    vertical: lib_1.style(csstips.vertical),
    table: lib_1.style({
        flex: 1,
        overflowY: 'scroll',
        overflowX: 'hidden',
        width: tileSize * 8,
        boxSizing: 'content-box',
        paddingRight: 10,
        $nest: {
            '&>img': {
                boxSizing: 'border-box',
                cursor: 'copy',
                borderWidth: 0.5,
                borderStyle: 'solid',
                borderColor: 'transparent',
                width: '12.5%',
                height: 'auto',
                marginBottom: -3 // うまく height が計算されない？列方向に謎の空白が生まれる
            },
            '&>img.selected': {
                borderColor: MenuBar_1.selectedColor
            },
            '&::-webkit-scrollbar': {
                width: 10
            },
            '&::-webkit-scrollbar-track': {
                borderRadius: 4,
                backgroundColor: 'rgb(255,255,255)'
            },
            '&::-webkit-scrollbar-thumb': {
                borderRadius: 4,
                backgroundColor: 'rgb(62,62,62)'
            }
        }
    }),
    nibView: lib_1.style(csstips.selfCenter, csstips.vertical, {
        flex: 0,
        flexBasis: tileSize * 5,
        minHeight: tileSize * 5,
        justifyContent: 'center',
        $nest: {
            '&>div': {
                height: tileSize
            }
        }
    })
};
function PaletteView() {
    var _a = __read(React.useState(false), 2), floating = _a[0], setFloating = _a[1];
    var _b = __read(React.useState(false), 2), collapsed = _b[0], setCollapsed = _b[1];
    return (React.createElement("div", { className: cn.root },
        React.createElement(react_resize_detector_1.default, { handleWidth: true, onResize: function (width) { return setFloating(width < floatThrethold); } }, floating ? (React.createElement("div", { className: cn.floating },
            React.createElement("button", { onClick: function () { return setCollapsed(!collapsed); } }, collapsed ? '◀︎' : '▶︎'),
            React.createElement(PaletteContainer, { className: lib_1.classes(cn.resizeWrapper, collapsed && cn.collapsed) }))) : (React.createElement(PaletteContainer, null)))));
}
exports.PaletteView = PaletteView;
function PaletteContainer(props) {
    return (React.createElement("div", { className: lib_1.classes(props.className, cn.vertical) },
        React.createElement(TileSetsView, null),
        React.createElement(NibView, null)));
}
exports.PaletteContainer = PaletteContainer;
function TileSetsView() {
    var pages = useTypedSelector_1.useTypedSelector(function (state) { return state.palette.pages; });
    return (React.createElement("div", { className: cn.table }, pages.map(function (page) { return (React.createElement(PageView, __assign({ key: page.index }, page))); })));
}
function PageView(props) {
    var _a = __read(React.useState(props.row > 1), 2), collapsed = _a[0], setCollapsed = _a[1];
    var selection = useTypedSelector_1.useTypedSelector(function (state) { return state.palette.selection; });
    var touchRef = React.useRef(0); // save last touch indentifier of onTouchStart
    var draggingRef = React.useRef(false); // is dragging or swiping?
    var release = React.useCallback(function () {
        draggingRef.current = false;
    }, []);
    React.useEffect(function () {
        window.addEventListener('mouseup', release, { passive: true });
        window.addEventListener('touchend', release, { passive: true });
        return function () {
            window.removeEventListener('mouseup', release);
            window.removeEventListener('touchend', release);
        };
    }, [release]);
    var canOpen = props.row > 1 && collapsed;
    var open = React.useCallback(function () {
        if (canOpen) {
            setCollapsed(false);
        }
    }, [canOpen]);
    var canClose = props.row > 1 && !collapsed;
    var close = React.useCallback(function () {
        if (canClose) {
            setCollapsed(true);
        }
    }, [canClose]);
    var dispatch = react_redux_1.useDispatch();
    var start = React.useCallback(function (pos) {
        draggingRef.current = true;
        dispatch(palette_1.actions.setSelection({
            page: props.index,
            start: pos,
            end: pos
        }));
    }, []);
    var move = React.useCallback(function (pos) {
        if (!selection || !draggingRef.current)
            return;
        if (react_redux_1.shallowEqual(pos, selection.end))
            return;
        dispatch(palette_1.actions.setSelection({
            page: selection.page,
            start: selection.start,
            end: pos
        }));
    }, [selection]);
    var handleMouseDown = React.useCallback(function (e) {
        if (collapsed)
            return;
        start(getPos(e.clientX, e.clientY, e.currentTarget.getBoundingClientRect()));
    }, [collapsed, start]);
    var handleMouseMove = React.useCallback(function (e) {
        if (collapsed)
            return;
        move(getPos(e.clientX, e.clientY, e.currentTarget.getBoundingClientRect()));
    }, [collapsed, move]);
    var handleTouchStart = React.useCallback(function (e) {
        var p = e.touches.item(0);
        if (collapsed || !p)
            return;
        start(getPos(p.clientX, p.clientY, e.currentTarget.getBoundingClientRect()));
        touchRef.current = p.identifier;
    }, [collapsed, start]);
    var handleTouchMove = React.useCallback(function (e) {
        var p = e.touches.item(0);
        if (collapsed || !p || p.identifier !== touchRef.current)
            return;
        move(getPos(p.clientX, p.clientY, e.currentTarget.getBoundingClientRect()));
    }, [collapsed, move]);
    return (React.createElement("div", { style: { paddingTop: padding } },
        React.createElement("div", { style: {
                padding: padding,
                paddingBottom: collapsed ? 0 : padding,
                width: '100%',
                backgroundColor: color,
                borderRadius: 2,
                overflow: 'hidden',
                cursor: canOpen ? 'pointer' : 'inherit'
            }, onClick: open },
            React.createElement("div", { style: {
                    position: 'relative',
                    height: 0,
                    paddingTop: collapsed ? '12.5%' : 12.5 * props.row + "%",
                    width: '100%',
                    transition: 'padding-top 200ms'
                }, onMouseDown: handleMouseDown, onMouseMove: handleMouseMove, onMouseUp: release, onTouchStart: handleTouchStart, onTouchMove: handleTouchMove, onTouchEnd: release },
                React.createElement("img", { src: props.src, alt: "", style: {
                        position: 'absolute',
                        top: 0,
                        left: 0,
                        width: '100%',
                        transformOrigin: 'top',
                        transform: collapsed ? 'scaleY(0.5)' : 'none'
                    }, draggable: false }),
                selection && selection.page === props.index && !collapsed ? (React.createElement(SelectionView, { selection: selection, row: props.row })) : null,
                collapsed ? (React.createElement("div", { style: {
                        position: 'absolute',
                        background: "linear-gradient(" + transparent + "," + transparent + "," + color + ")",
                        height: '100%',
                        width: '100%',
                        top: 0,
                        zIndex: 1
                    } })) : null),
            canClose ? (React.createElement("div", { style: {
                    height: 32,
                    textAlign: 'center',
                    width: '100%',
                    cursor: 'pointer',
                    fontSize: 28 // TODO: SVG にする
                }, onClick: close }, "\u30FC")) : null)));
}
function SelectionView(_a) {
    var _b = _a.selection, start = _b.start, end = _b.end, row = _a.row;
    var left = Math.min(start.col, end.col);
    var top = Math.min(start.row, end.row);
    var right = Math.max(start.col, end.col) + 1;
    var bottom = Math.max(start.row, end.row) + 1;
    return (React.createElement("div", { style: {
            borderWidth: 1,
            borderStyle: 'solid',
            borderColor: MenuBar_1.selectedColor,
            boxSizing: 'border-box',
            position: 'absolute',
            left: left * 12.5 + "%",
            top: (top / row) * 100 + "%",
            width: (right - left) * 12.5 + "%",
            height: ((bottom - top) / row) * 100 + "%",
            zIndex: 1
        } }));
}
function NibView() {
    var nib = useTypedSelector_1.useTypedSelector(function (state) { return state.palette.nib; });
    var author = nib && nib[0] && nib[0][0] && nib[0][0].author;
    return (React.createElement("div", { className: cn.nibView },
        nib &&
            nib.map(function (row, i) { return (React.createElement("div", { key: i }, row.map(function (tile) {
                return tile.index > 0 ? (React.createElement("img", { key: tile.index, src: tile.src, alt: "NOT FOUND", draggable: false })) : null;
            }))); }),
        author ? (React.createElement("small", { style: { position: 'absolute', right: 0, bottom: 0 } }, "Illustrated by ",
            React.createElement("a", { href: author.url, target: "_blank", referrerPolicy: "no-referrer" }, author.name))) : null));
}
function getPos(x, y, bound) {
    var tileSize = bound.width / 8;
    var col = ((x - bound.left) / tileSize) | 0;
    var row = ((y - bound.top) / tileSize) | 0;
    return {
        row: row,
        col: col,
        num: col + row * 8
    };
}
//# sourceMappingURL=PaletteView.js.map