<!doctype html>
<html lang="en">

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Coordinates Doctest</title>
    <link rel="stylesheet" href="./3rdparty/highlight/styles/default.css">
    <link rel="stylesheet" href="../css/doctest.css">
    <script src="./3rdparty/highlight/highlight.pack.js"></script>
    <script src="../dist/iwmlib.3rdparty.js"></script>
    <script src="../dist/iwmlib.js"></script>
    <script>
        function drawPolygons() {
            canvas.width = main.getBoundingClientRect().width
            let context = canvas.getContext('2d')
            context.clearRect(0, 0, canvas.width, canvas.height)

            let stage = scatterContainer.polygon
            stage.draw(context, { stroke: '#FF0000' })
            for (let scatter of scatterContainer.scatter.values()) {
                let polygon = scatter.polygon
                polygon.draw(context, { stroke: '#FF0000' })
            }
        }

        function animate(callback) {
            requestAnimationFrame((dt) => {
                drawPolygons()
                callback()
                animate(callback)
            })
        }
    </script>
</head>

<body onload="Doctest.run()">
    <h1>
        Coordinates
    </h1>
    <p>
        To position objects in defined spatial relationships presupposes a clear understanding of the involved coordinate systems.
        Unfortunately, several systems with several conventions are involved:
        <a href="https://javascript.info/coordinates">DOM &amp; CSS</a>,
        <a href="https://www.sarasoueidan.com/blog/svg-coordinate-systems/SVG">SVG</a>,
        <a href="https://www.w3schools.com/graphics/canvas_coordinates.asp">Canvas</a>
    </p>
    <p>
        We need a common reference system to switch between these coordinate systems. As the uttermost context, the browser page
        coordinate system is the most natural one. A simple API was long missing but has now been established in most modern
        browsers with
        <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/convertPointFromNoteToPage">window.convertPointFromNoteToPage</a> and the inverse
        <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/convertPointFromPageToNode">window.convertPointFromPageToNode</a>. 
        Although MDN Web Docs warns about their Non-standard nature the methods work in browsers targeted
        by the IWM Browser project. This doctest assures that this assumption can be tested.
    </p>
    <p>Let's look at a scatter object with a rotatable local coordinate system. We try to follow a point in this local coordinate
        system by showing a marker outside the scatter that follows the point.
    </p>
    <div id="main" class="grayBorder interactive" style="position: relative; width: 100%; height: 280px;">
        <!-- Note that we need to set draggable to false to avoid conflicts. The DOM elements
    must also be positioned absolutely. -->
        <img id="women" draggable="false" style="position: absolute;" src="examples/women.jpeg" />

        <canvas id="canvas" height="280" style="z-index: 100000; pointer-events: none; position: absolute; border: 1px solid red;">
            Canvas not supported.
        </canvas>
    </div>

    <script class="doctest">
        let dx = 44

        let app = new App()
        let scatterContainer = new DOMScatterContainer(main)
        let angle = 15
        let image = document.getElementById('women')
        // The DOMScatter needs initial width and height. Therefore we
        // define the scatter when the image size is known, i.e. after loading...
        image.onload = (e) => {
            let scatter = new DOMScatter(image, scatterContainer, {
                x: dx,
                y: 44,
                width: e.target.naturalWidth,
                height: e.target.naturalHeight,
                rotationDegrees: angle,
                throwVisibility: 88,
                minScale: 0.5,
                maxScale: 1.5
            })
            dx += 300
            angle = -angle
        }

        app.run()

        function followPoint() {
            let context = canvas.getContext('2d')
            let localPoint = { x: 100, y: 100 }
            let globalPoint = convertPointFromNodeToPage(image, localPoint.x, localPoint.y)
            let canvasPoint = convertPointFromPageToNode(canvas, globalPoint.x, globalPoint.y)

            context.strokeStyle = 'red'
            context.beginPath()
            context.arc(canvasPoint.x, canvasPoint.y, 12, 0, Math.PI * 2)
            context.stroke()

        }
        animate(followPoint)
    </script>

</body>