<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>logbook2map</title>

    <link rel="stylesheet" href="https://unpkg.com/maplibre-gl/dist/maplibre-gl.css">
    <style>
        body, html {
            margin: 0;
            padding: 0;
            width: 100vw;
            height: 100vh;
            overflow: hidden;
        }

        #map {
            width: 100%;
            height: 100%;
        }

        #input_modal {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0, 0, 0, 0.5);
            display: flex;
            justify-content: center;
            align-items: center;
            
            display: none;

            textarea {
                width: 80%;
                height: 80%;
                font-size: 1.5em;
                min-width: 20em;
                min-height: 20em;
                max-width: 40em;
                max-height: 40em;
            }
        }
    </style>
</head>
<body>
    <div id="map"></div>

    <div id="input_modal">
        <textarea placeholder="ICAO_departure;ICAO_destination&#10;&#10;&#10;Validate with Ctrl+Enter&#10;Load new data with Ctrl+O"></textarea>
    </div>

    <script src="https://unpkg.com/maplibre-gl/dist/maplibre-gl.js"></script>
    <script>
        const osmStyle = {
            "version": 8,
                "sources": {
                "osm": {
                        "type": "raster",
                        "tiles": ["https://a.tile.openstreetmap.org/{z}/{x}/{y}.png"],
                        "tileSize": 256,
                "attribution": "&copy; OpenStreetMap Contributors",
                "maxzoom": 19
                }
            },
            "layers": [
                {
                "id": "osm",
                "type": "raster",
                "source": "osm" // This must match the source key above
                }
            ]
        };
        var map = new maplibregl.Map({
            container: 'map', // container id
            style: osmStyle, // style URL
            center: [17.97, 57.91], // starting position [lng, lat]
            zoom: 3.7 // starting zoom
        });

        function _updateMap(csvData, airportsData) {
            const lines = csvData.split('\n');
            const features = lines.map(line => {
                const [from, to] = line.split(',');

                const fromAirport = airportsData[from];
                const toAirport = airportsData[to];

                if(!fromAirport) { alert(`Airport ${from} not found`); return; }
                if(!toAirport) { alert(`Airport ${to} not found`); return; }

                const fromLongitude = parseFloat(fromAirport.longitude);
                const fromLatitude = parseFloat(fromAirport.latitude);
                const toLongitude = parseFloat(toAirport.longitude);
                const toLatitude = parseFloat(toAirport.latitude);

                return {
                    type: 'Feature',
                    properties: {
                        from,
                        to
                    },
                    geometry: {
                        type: 'LineString',
                        coordinates: [
                            [fromLongitude, fromLatitude],
                            [toLongitude, toLatitude]
                        ]
                    }
                };
            });

            map.addSource('routes', {
                type: 'geojson',
                data: {
                    type: 'FeatureCollection',
                    features
                }
            });

            map.addLayer({
                id: 'routes',
                type: 'line',
                source: 'routes',
                layout: {
                    'line-join': 'round',
                    'line-cap': 'round'
                },
                paint: {
                    'line-color': '#bd34eb',
                    'line-width': 4
                }
            });
        }

        function updateMap(csvData) {
            // download https://davidmegginson.github.io/ourairports-data/airports.csv if not locally available
            const request = indexedDB.open('my_database', 1);
            request.onupgradeneeded = function(event) {
                const db = event.target.result;
                const objectStore = db.createObjectStore('airports');
            };
            request.onerror = function(event) { alert('Error while opening database:\n' + event.target.error); };
            request.onsuccess = function(event) {
                const db = event.target.result;
                const transaction = db.transaction(['airports'], 'readwrite');
                const objectStore = transaction.objectStore('airports');

                const getRequest = objectStore.get('airports');
                getRequest.onerror = function(event) { alert("Error getting data:\n" + event.target.error); };
                getRequest.onsuccess = function(event) {
                    if (!event.target.result) {
                        // Data not found, fetch and store it
                        fetch('https://davidmegginson.github.io/ourairports-data/airports.csv')
                            .then(response => response.text())
                            .then(data => {
                                console.info('Downloaded airports.csv, parsing the data...');
                                const airports = {};
                                for(const airport of data.split('\n')) {
                                    const [_id, ident, _type, name, latitude, longitude] = airport.split(',');
                                    if(!ident) continue;
                                    airports[ident.replace(/^"|"$/g, '')] = { name, latitude, longitude };
                                }

                                const transaction = db.transaction(['airports'], 'readwrite');
                                const objectStore = transaction.objectStore('airports');
                                objectStore.put(airports, 'airports');
                                _updateMap(csvData, airports);
                            })
                            .catch(error => { alert('Error while downloading airports.csv: \n' + error); });
                    } else {
                        console.log('Data found in local storage!');
                        _updateMap(csvData, event.target.result);
                    }
                };
            };
        }

        function showInputModal() {
            document.getElementById('input_modal').style.display = 'flex';

            const textarea = document.querySelector('#input_modal textarea');
            textarea.focus();
            textarea.addEventListener('keydown', event => {
                if(event.ctrlKey && event.key === 'Enter') {
                    const csvData = textarea.value;
                    updateMap(csvData);
                    document.getElementById('input_modal').style.display = 'none';
                }
            });
        }

        showInputModal();

        document.addEventListener('keydown', event => {
            if(event.ctrlKey && event.key === 'o') {
                event.preventDefault();
                showInputModal();
            }
        });
    </script>
</body>
</html>