<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-confirm/3.3.2/jquery-confirm.min.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-confirm/3.3.2/jquery-confirm.min.js"></script>
    <script src="{{url_for('static', filename='board.js')}}"></script>
    <script>
        let names = ["{{names[0]}}", "{{names[1]}}"];
        let moves = [{% for move in moves %}{number:{{move['number']}},kif_move:"{{move['kif_move']}}",time:{{move['time']}},move:{{move['move']}},eval:{{move['eval']}},pv:"{{move['pv']}}"},{% endfor %}];
        let isMatch = {{is_match}};
        let autoupdate = {{autoupdate}};
        let human = "{{human}}";
        let board = new Board();

        let current = 0;
        function selectMoveNumber(number) {
            rows = $("#table-moves tr");
            if (rows.length > 0) {
                if (number < 0 || number > rows.length) return;
                if (current > 0)
                    rows.eq(current - 1).removeClass("table-active");
                if (number > 0)
                    rows.eq(number - 1).addClass("table-active");

                let currentTop = $("#moves").scrollTop() / rows.eq(0).height();
                if (number - 1 < currentTop || number - 1 > currentTop + 8)
                    $("#moves").scrollTop(rows.eq(0).height() * (number - 1));

                current = number;
                $("#move-number").val(current);
                updateBoard(current);
            }
        }

        function updateBoard(number) {
            board.reset();
            let len = number;
            if (moves.length > 0 && len == moves.length && moves[len - 1]['move'] == 0)
                len--;
            for (let i = 0; i < len; i++)
                board.move(moves[i]['move']);
            $("#board").html(board.to_svg(1.5, names[1] == 'Human'));
            comments = len % 2 == 0 ? [$("#white-comment"), $("#black-comment")] : [$("#black-comment"), $("#white-comment")];

            let eval = '';
            let pv = '';
            if (len > 0) {
                eval = moves[len - 1]['eval'];
                if (eval == null || eval == 'null') eval = '';
                pv = moves[len - 1]['pv'];
            }
            comments[0].removeClass('text-black-50')
            comments[0].addClass('text-body')
            comments[0].html("<td>" + eval + "</td><td>" + pv + "</td>");

            eval = '';
            pv = '';
            if (len - 1 > 0) {
                eval = moves[len - 2]['eval'];
                if (eval == null || eval == 'null') eval = '';
                pv = moves[len - 2]['pv'];
            }
            comments[1].removeClass('text-body')
            comments[1].addClass('text-black-50')
            comments[1].html("<td>" + eval + "</td><td>" + pv + "</td>");
        }

        function drawEvalGraph() {
            let canvas = $("#eval-graph");
            let width = 25 + 256 * 2;
            if (moves.length > 256) {
                width = 25 + moves.length * 2;
                canvas.attr("width", width);
            }
            let ctx = canvas[0].getContext("2d");

            ctx.fillStyle = "#D0D0FF";
            ctx.fillRect(0, 0, width, 160);
            ctx.lineWidth = 1;

            ctx.beginPath();
            ctx.strokeStyle = "#080808";
            ctx.moveTo(0, 80);
            ctx.lineTo(600, 80);
            ctx.moveTo(25, 0);
            ctx.lineTo(25, 160);
            ctx.stroke();

            ctx.fillStyle = "#080808";
            for (let i = 2000; i >= -2000; i -= 1000) {
                if (i == 0) continue;
                const y = 80 - i * 3 / 100;

                ctx.beginPath();
                ctx.strokeStyle = "gray";
                ctx.setLineDash([1, 4]);
                ctx.moveTo(28, y);
                ctx.lineTo(width, y);
                ctx.stroke();

                ctx.beginPath();
                ctx.strokeStyle = "#080808";
                ctx.setLineDash([]);
                ctx.moveTo(22, y);
                ctx.lineTo(27, y);
                ctx.stroke();

                ctx.font = "8px serif";
                ctx.fillText(i, 0, y + 3);
            }

            for (let i = 50; i < Math.max(256, moves.length); i += 50) {
                ctx.beginPath();
                ctx.strokeStyle = "gray";
                ctx.setLineDash([1, 6]);
                ctx.moveTo(25 + i * 2, 0);
                ctx.lineTo(25 + i * 2, 160);
                ctx.stroke();

                ctx.beginPath();
                ctx.strokeStyle = "#080808";
                ctx.setLineDash([]);
                ctx.moveTo(25 + i * 2, 78);
                ctx.lineTo(25 + i * 2, 82);
                ctx.stroke();

                ctx.fillText(i, 20 + i * 2, 89);
            }

            ctx.lineWidth = 2.5;
            for (let c = 1; c <= 2; c++) {
                ctx.strokeStyle = c == 1 ? "black" : "white";
                ctx.beginPath();
                let needMove = true;
                for (let i = c; i < moves.length; i += 2) {
                    let eval = moves[i - 1]['eval'];
                    if (eval != null && eval != 'null') {
                        const y = Math.min(160, Math.max(0, 80 - eval * 80 / 3000));
                        if (needMove) {
                            ctx.moveTo(25 + i * 2, y);
                            needMove = false;
                        } else
                            ctx.lineTo(25 + i * 2, y);
                    } else {
                        needMove = true;
                    }
                }
                ctx.stroke();
            }
        }

        function updateNames() {
            if (names[0] != null && names[0] != "None")
                $("#names").html("▲" + names[0] + " △" + names[1]);
        }

        function updateTableMoves() {
            let html = "";
            for (let i = 0; i < moves.length; i++) {
                html += '<tr><td style="width:3em; text-align: right;">' + moves[i]["number"] + '</td><td nowrap>' + moves[i]["kif_move"] + '</td><td nowrap style="text-align: right;">' + moves[i]["time"] + '秒</td></tr>';
            }
            $("#table-moves").html(html);
            $("#table-moves tr").click(function() {
                selectMoveNumber($(this).index() + 1);
            });
        }

        function update() {
            if (human == '') {
                $.ajax({
                    url: "/update",
                    type: "GET",
                    dataType: "json",
                }).done(function(data) {
                    names = data["names"];
                    updateNames();
                    moves = data["moves"];
                    human = data["human"];
                    updateBoard(moves.length);
                    updateTableMoves();
                    selectMoveNumber(moves.length);
                    drawEvalGraph();
                });
            }
            if (moves.length > 0 && moves[moves.length - 1]["move"] == 0) {
                $("#autoupdate").prop('checked', false).change();
            }
        }

        let selected = null;
        function onMouseDown1(event) {
            if (event.button == 0) {
                if (Number($("#move-number").val()) != moves.length)
                    return;
                selected = document.elementFromPoint(event.clientX, event.clientY);
                if ((selected.tagName == "use" && selected.getAttribute("xlink:href").substring(1, 6) == human) ||
                    (selected.tagName == "text" && selected.getAttribute("id") != null && selected.getAttribute("id").substring(0, 5) == human)) {
                    selected.style.fillOpacity = "0.5";
                    $("#board")[0].removeEventListener('mousedown', onMouseDown1);
                    $("#board")[0].addEventListener("mousedown", onMouseDown2);
                }
            }
        }

        function human_move(from_sq, to_sq) {
            $.ajax({
                url: "/move",
                type: "GET",
                data: { "number": moves.length + 1, "move": from_sq + to_sq },
                dataType: "json",
            }).done(function(data) {
                names = data["names"];
                updateNames();
                moves = data["moves"];
                human = data["human"];
                updateBoard(moves.length);
                updateTableMoves();
                selectMoveNumber(moves.length);
                drawEvalGraph();
                if (moves.length > 0 && moves[moves.length - 1]["move"] == 0) {
                    $("#autoupdate").prop('checked', false).change();
                }
                if (human == '')
                    $("#autoupdate").change();
            });
        }

        function onMouseDown2(event) {
            let to = document.elementFromPoint(event.clientX, event.clientY);
            if (to.getAttribute("id") != null && (to.tagName == "use" || to.tagName == "rect")) {
                let from_sq = selected.getAttribute("id");
                if (selected.tagName == "text") {
                    from_sq = from_sq.slice(-1) + "*";
                }

                let to_sq = to.getAttribute("id");

                let confirm = false;
                if (event.shiftKey) {
                    to_sq += "+";
                } else if (selected.tagName == "use") {
                    let piece = selected.getAttribute("xlink:href").substring(7);
                    let promote = false;
                    if (["pawn", "lance", "knight", "silver", "bishop", "rook"].includes(piece)) {
                        let promotion_zone = human == "black" ? ["a", "b", "c"] : ["i", "h", "g"];
                        if (promotion_zone.includes(to_sq[1])) {
                            if (to_sq[1] == promotion_zone[0] && ["pawn", "lance", "knight"].includes(piece))
                                promote = true;
                            else if (to_sq[1] == promotion_zone[1] && piece == "knight")
                                promote = true;
                            else
                                confirm = true;
                        }
                        else if (promotion_zone.includes(from_sq[1])) {
                            confirm = true;
                        }
                    }
                    if (confirm) {
                        $.confirm({
                            title: '',
                            content: "成りますか？",
                            buttons: {
                                confirm: {
	                            text:'はい',
	                            btnClass: 'btn-blue',
	                            action: function () {
	                                to_sq += "+";
                                    human_move(from_sq, to_sq);
                                    },
	                            },
                                cancel: {
	                            text:'いいえ',
	                            action:function () {
	                                human_move(from_sq, to_sq);
	                                },
	                            },
                            }
                        });
                    } else if (promote)
                        to_sq += "+";
                }
                if (!confirm)
                    human_move(from_sq, to_sq);
            }

            selected.style.fillOpacity = "";
            selected = null;
            $("#board")[0].removeEventListener('mousedown', onMouseDown2);
            $("#board")[0].addEventListener("mousedown", onMouseDown1);
        }

        $(function() {
            let number = 0;
            updateNames();
            updateBoard(number);
            updateTableMoves();
            drawEvalGraph();

            $("#btn-first").click(function() {
                selectMoveNumber(0);
            });
            $("#btn-back").click(function() {
                selectMoveNumber(current - 1);
            });
            $("#btn-next").click(function() {
                selectMoveNumber(current + 1);
            });
            $("#btn-last").click(function() {
                selectMoveNumber($("#moves tr").length);
            });
            $("#move-number").change(function() {
                selectMoveNumber(Number($(this).val()));
            });
            $("#btn-update").click(function() {
                update();
            });
            let timer = null;
            $("#autoupdate").change(function() {
                autoupdate = $(this).prop('checked');
                if (autoupdate && timer == null) {
                    timer = setInterval(function() {
                        update();
                    }, 1000);
                } else if (!autoupdate && timer != null) {
                    clearInterval(timer);
                    timer = null;
                }
            });

            if (isMatch) {
                $("#update").removeClass("d-none");
                number = moves.length;
                selectMoveNumber(number);
                if (autoupdate) {
                    $("#autoupdate").prop('checked', true);
                    if (human == '')
                        $("#autoupdate").change();
                }
            }

            $("#board")[0].addEventListener("mousedown", onMouseDown1);
        });
    </script>
    <style type="text/css">
        svg {
            -ms-user-select: none;
            -webkit-user-select: none;
            user-select: none;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="row m-1">
            <div id="names" class="col">
                &nbsp;
            </div>
        </div>
        <div class="row">
            <div class="col-auto">
                <div id="board"></div>
            </div>
            <div class="col">
                <div id="moves" style="height: 300px; width: 14.5em; overflow-y: scroll;">
                    <table class="table table-borderless table-sm table-hover" style="width: 13em;">
                        <tbody id="table-moves"></tbody>
                    </table>
                </div>
            </div>
        </div>
        <div class="row">
            <div class="col">
                <button type="button" id="btn-first" class="btn btn-light">最初へ</button>
                <button type="button" id="btn-back" class="btn btn-light">&lt;</button>
                <input type="text" id="move-number" style="width: 3em;" value="0">手目
                <button type="button" id="btn-next" class="btn btn-light">&gt;</button>
                <button type="button" id="btn-last" class="btn btn-light">最後へ</button>
            </div>
            <div id="update" class="col d-none">
                <button type="button" id="btn-update" class="btn btn-light">更新</button>
                <input type="checkbox" id="autoupdate" name="autoupdate"><label for="autoupdate">自動更新</label>
            </div>
        </div>
        <div class="row mt-1">
            <div class="col border" style="height: 60px; overflow-y: scroll;">
                <table class="table table-sm small table-borderless" style="height: 40px;">
                    <thead>
                        <tr>
                            <td style="width: 6em;">評価値</td>
                            <td>読み筋</td>
                        </tr>
                    </thead>
                    <tbody><tr id="black-comment"></tr></tbody>
                </table>
            </div>
        </div>
        <div class="row">
            <div class="col border" style="height: 60px; overflow-y:scroll;">
                <table class="table table-sm small table-borderless" style="height: 40px;">
                    <thead>
                        <tr>
                            <td style="width: 6em;">評価値</td>
                            <td>読み筋</td>
                        </tr>
                    </thead>
                    <tbody><tr id="white-comment"></tr></tbody>
                </table>
            </div>
        </div>
        <div class="row mt-1">
            <div class="col">
                <canvas id="eval-graph" width="537" height="160"></canvas>
            </div>
        </div>
    </div>
</body>
</html>
