"use strict";
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 });
exports.CanvasView = void 0;
var next_1 = require("@hackforplay/next");
var csstips = require("csstips/lib");
var React = require("react");
var recoil_1 = require("recoil");
var lib_1 = require("typestyle/lib");
var recoils_1 = require("../recoils");
var cursor_1 = require("../utils/cursor");
var updateScene_1 = require("../utils/updateScene");
var Paper_1 = require("./Paper");
var cn = {
    root: lib_1.style(csstips.flex1, {
        padding: 16,
        paddingLeft: 0,
        paddingTop: 8,
        overflow: 'hidden'
    }),
    renderRoot: lib_1.style({
        width: '100%',
        height: '100%',
        padding: 16,
        boxSizing: 'border-box',
        overflow: 'scroll'
    }),
    disableTouchAction: lib_1.style({
        /**
         * https://developer.mozilla.org/en-US/docs/Web/CSS/touch-action
         * iOS 11 Safari では 'manipulation' だと Double Tap Zoom を防げなかった
         */
        touchAction: 'none'
    })
};
function CanvasView() {
    var cursorMode = recoil_1.useRecoilValue(recoils_1.cursorModeState);
    var nibLoadable = recoil_1.useRecoilValueLoadable(recoils_1.paletteNibState);
    var cursor = cursor_1.cursorClasses[cursorMode];
    var _a = recoil_1.useRecoilValue(recoils_1.sceneScreenState), width = _a.width, height = _a.height;
    var canvasRendererRef = React.useRef();
    var containerRef = React.useRef(null);
    React.useEffect(function () {
        var container = containerRef.current;
        if (!container || canvasRendererRef.current)
            return;
        canvasRendererRef.current = new next_1.CanvasRenderer(container, {
            width: width,
            height: height
        });
    }, [containerRef.current]);
    var scene = recoil_1.useRecoilValue(recoils_1.sceneState);
    React.useEffect(function () {
        var canvasRenderer = canvasRendererRef.current;
        if (!canvasRenderer)
            return;
        canvasRenderer.update(scene);
    }, [scene]);
    var _b = __read(React.useState({
        px: -1,
        py: -1,
        pressed: false,
        id: 0
    }), 1), mutate = _b[0];
    var start = React.useCallback(function () {
        mutate.px = -1;
        mutate.py = -1;
        mutate.pressed = true;
        mutate.id++;
    }, []);
    var update = React.useCallback(function (x, y) {
        mutate.px = x;
        mutate.py = y;
    }, []);
    var stop = React.useCallback(function () {
        mutate.pressed = false;
    }, []);
    var setEditing = recoil_1.useSetRecoilState(recoils_1.editingState);
    var handleMove = React.useCallback(function (e) {
        if (!mutate.pressed)
            return;
        if (nibLoadable.state !== 'hasValue')
            return;
        var _a = e.currentTarget, offsetLeft = _a.offsetLeft, offsetTop = _a.offsetTop, parentElement = _a.parentElement;
        var x = ((e.pageX -
            offsetLeft +
            (parentElement ? parentElement.scrollLeft : 0)) /
            32) >>
            0;
        var y = ((e.pageY - offsetTop + (parentElement ? parentElement.scrollTop : 0)) /
            32) >>
            0;
        if (x !== mutate.px || y !== mutate.py) {
            update(x, y);
            var cursor_2 = new cursor_1.default(x, y, cursorMode, nibLoadable.contents, mutate.id);
            setEditing(function (current) { return updateScene_1.editWithCursor(current, cursor_2); });
        }
    }, [cursorMode, nibLoadable]);
    var handleMouseDown = React.useCallback(function (e) {
        start();
        handleMove(e);
    }, [handleMove]);
    React.useEffect(function () {
        window.addEventListener('mouseup', stop, { passive: true });
        return function () {
            window.removeEventListener('mouseup', stop);
        };
    }, []);
    var handleTouchMove = React.useCallback(function (e) {
        if (!mutate.pressed)
            return;
        if (nibLoadable.state !== 'hasValue')
            return;
        e.nativeEvent.preventDefault(); // 指でスクロールするのを防ぐ
        var _a = e.currentTarget, offsetLeft = _a.offsetLeft, offsetTop = _a.offsetTop, parentElement = _a.parentElement;
        var primary = e.touches.item(0);
        var x = ((primary.pageX -
            offsetLeft +
            (parentElement ? parentElement.scrollLeft : 0)) /
            32) >>
            0;
        var y = ((primary.pageY -
            offsetTop +
            (parentElement ? parentElement.scrollTop : 0)) /
            32) >>
            0;
        if (x !== mutate.px || y !== mutate.py) {
            update(x, y);
            var cursor_3 = new cursor_1.default(x, y, cursorMode, nibLoadable.contents, mutate.id);
            setEditing(function (current) { return updateScene_1.editWithCursor(current, cursor_3); });
        }
    }, [cursorMode, nibLoadable]);
    var handleTouchStart = React.useCallback(function (e) {
        start();
        handleTouchMove(e);
    }, [handleTouchMove]);
    // Disable scroll on mobile browser
    var canvasRef = React.useRef(null);
    React.useEffect(function () {
        var canvas = canvasRef.current;
        if (!canvas)
            return;
        canvas.ontouchmove = function (e) { return e.preventDefault(); };
    }, [canvasRef.current]);
    return (React.createElement("div", { className: cn.root },
        React.createElement(Paper_1.Paper, { id: "rme-canvas-view", className: cn.renderRoot, ref: containerRef },
            React.createElement("canvas", { className: lib_1.classes(cursor, cn.disableTouchAction), width: width, height: height, onTouchStart: handleTouchStart, onTouchCancel: stop, onTouchEnd: stop, onTouchMove: handleTouchMove, onMouseDown: handleMouseDown, onMouseUp: stop, onMouseMove: handleMove }))));
}
exports.CanvasView = CanvasView;
//# sourceMappingURL=CanvasView.js.map