document.addEventListener("DOMContentLoaded", ()=>{
    const G_KETA = 6, LSkey = "markers";
    var gnssWatchID = null, gnssCount = {};
    var mymap, infobox, gnssMarker, btnGet, btnSTOP;
    var yellowIcon;
    var gsiLayer = L.tileLayer(
	'https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png', {
	    attribution:
	    '<a href="http://maps.gsi.go.jp/development/ichiran.html">国土地理院</a>',
	    maxZoom: 20, maxNativeZoom: 18
	});
    var gsiPhoto = L.tileLayer(
	'https://cyberjapandata.gsi.go.jp/xyz/seamlessphoto/{z}/{x}/{y}.jpg',
	{attribution: '&copy; <a href="http://maps.gsi.go.jp/development/ichiran.html">国土地理院</a>',
	 maxZoom: 20, maxNativeZoom: 18});
    var osmLayer = L.tileLayer(
	'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
	    attribution:
	    '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors',
	    maxZoom: 20, maxNativeZoom: 18
	});
    var offlineLayerGsiPhoto = L.imageOverlay(
	"img/koekimap.png",
	[[38.895492, 139.816593], [38.890816, 139.822602]]
    );
    var offlineLayerOSM = L.imageOverlay(
	"img/osm-koekimap.png",
	[[38.895855, 139.816143], [38.891178, 139.82215]]
    );
    var baseLayers = {
	"(オフライン用)大学周辺地理院空中写真": offlineLayerGsiPhoto,
	"(オフライン用)大学周辺OSM": offlineLayerOSM,
	OpenStreetMap: osmLayer,
	地理院地図: gsiLayer,
	地理院空中写真: gsiPhoto,
    };
    function workerInit() {
	if ('serviceWorker' in navigator) {
	    navigator.serviceWorker.register('./serviceworker.js')
		.then(function() {
		    console.log('service worker registered');
		});
	}
    }
    var stoPrefix = "dkm_";
    var LS = {
	"getItem": (i)=>{return localStorage.getItem(stoPrefix+i);},
	"removeItem": (i)=>{return localStorage.removeItem(stoPrefix+i);},
	"setItem": (k,v)=>{return localStorage.setItem(stoPrefix+k, v);},
	"reset": ()=>{
	    for (let p of Object.keys(localStorage)) {
		console.log(`LS=${p}`);
		if (p.startsWith(stoPrefix))
		    localStorage.removeItem(p);
	    }
	}
    }
    function appendLsMarker(latlng) {
	let lat = latlng.lat, lng = latlng.lng,
	    oldval = (LS.getItem(LSkey)||"[]");
	    newval = [lat, lng];
	console.log(`newval = ${newval}`);
	console.log(`lsval = ${oldval.length}`);
	try {
	    let list = JSON.parse(oldval);
	    console.log(`list=${list}`);
	    list.push(newval);
	    LS.setItem(LSkey, JSON.stringify(list));
	    console.log(`cur=${JSON.stringify(list)}`);
	} catch (e) {
	    // Just ignoring
	}
    }
    function restoreLsMarkers() {
	let lslist = LS.getItem(LSkey);
	if (!lslist) return;
	lastMarker.remove();	// Not required when restoring mode
	LS.reset();
	try {lslist = JSON.parse(lslist)} catch(e) {return;}

	for (let ll of lslist) {
	    let latlng = L.latLng(ll);
	    lastMarker = L.marker(latlng);
	    mvMarker(latlng);
	    kokoMemo();
	}
	dispInfo(`${lslist.length}地点のマーカを復元しました。`);
    }
    function removeLsMarkers(marker) {
	let ll = marker.getLatLng(),
	    lat = ll.lat, lng = ll.lng,
	    lsval = LS.getItem(LSkey), found, newval;
	if (!lsval) return;
	try {lsval = JSON.parse(lsval);} catch(e) {return;}
	newval = lsval.filter((e) => {return e[0] != lat||e[1] != lng});
	LS.setItem(LSkey, JSON.stringify(newval));
    }
    var markers = [], lastMarker, popupOpenedMarker;
    function rmMarker(mrk) {
	if (mrk) {
	    removeLsMarkers(mrk);
	    mrk.remove();
	    popupOpenedMarker = null;
	}
    }
    function mvMarker(ll) {
	let s = `東経=${ll.lat.toFixed(G_KETA)}<br>北緯=${ll.lng.toFixed(G_KETA)}`;
	if (lastMarker)
	    lastMarker.setLatLng(ll);
	else {
	    lastMarker = L.marker(ll);
	}
	let div = document.createElement("div"),
	    p   = document.createElement("p"),
	    btn = document.createElement("button");
	p.innerHTML = s;
	btn.textContent = "《このマーカを消す》";
	btn.addEventListener('click', (e)=>{rmMarker(popupOpenedMarker)});
	div.appendChild(p);
	div.appendChild(btn);
	console.log(`s=${s}`);
	lastMarker.bindPopup(div);
	lastMarker.on('popupopen', (e)=>{
	    let p = e.target.getPopup().getContent().querySelector("p");
	    console.log(`marked = ${p.textContent}`);
	    if (p) dispInfo(p.innerHTML.replace("<br>", ", "));
	    popupOpenedMarker = e.target;
	});
	lastMarker.addTo(mymap);
    }
    function mvMarkerByGNSS(latlng) {
	mymap.panTo(latlng);
	mvMarker(latlng);
    }
    function mvMarkerByClick(e) {
	mvMarker(e.latlng);
    }
    function kokoMemo() {
	if (lastMarker) {
	    markers.push(lastMarker);
	    let ll = lastMarker.getLatLng(),
		lat = ll.lat.toFixed(G_KETA), lng = ll.lng.toFixed(G_KETA),
		pop = lastMarker.getPopup();
	    let msg = `直近の地点を記憶したわ: 東経 ${lat}, 北緯 ${lng}`;
	    lastMarker.setIcon(yellowIcon).bindPopup(pop);
	    
	    dispInfo(msg);
	    lastMarker = null;
	    appendLsMarker(ll);
	} else {
	    alert("設定できるマーカーはまだないの.");
	}
    }
    function resetMarkers() {
	let m;
	if (markers.length==0) {
	    dispInfo("まだ何一つ覚えていない...");
	    return;
	}
	if (confirm("ほんとに消していいの?")) {
	    while (m=markers.shift()) {
		rmMarker(m);
	    }
	    LS.reset();
	    dispInfo("さらば思い出の地");
	}
    }
    function mapInit() {
	infobox = document.getElementById("info");
	mymap = L.map("mymap", baseLayers).setView([38.894, 139.81976], 18);
	L.control.scale().addTo(mymap); // 縮尺表示追加
	lastMarker = L.marker(mymap.getCenter());
	lastMarker.setPopupContent("Hi!").addTo(mymap);
	btnGet  = document.getElementById("get");
	btnSTOP = document.getElementById("stop");
	if (btnGet) btnGet.addEventListener("click", getGNSS, false);
	if (btnSTOP)btnSTOP.addEventListener("click", stopGNSS, false);
	// Create yellow Icon
	yellowIcon = L.icon({
	    iconUrl:	"img/Yellow.png",
	    iconSize:	[40, 41],
	    iconAnchor:	[10, 41],
	    popupAnchor: [3, -41]
	});
	L.control.layers(baseLayers).addTo(mymap);
	offlineLayerGsiPhoto.addTo(mymap);
	mymap.on('click', mvMarkerByClick);
	document.getElementById("memo").addEventListener("click", kokoMemo);
	document.getElementById("reset").addEventListener(
	    "click", resetMarkers);
	restoreLsMarkers();
    }
    function dispInfo(msg) {
	info.innerText = msg;
    }
    function clearWatchGNSS() {	// 位置取得ボタンを元に戻す
	navigator.geolocation.clearWatch(gnssWatchID);
	gnssWatchID = null;
	btnGet.classList.remove('running');
	btnGet.disabled = false;
	dispInfo("衛星信号取得停止");
    }
    function getGNSS(ev) {
	if (gnssWatchID) {
	    dispInfo("もう探索中しているの、急かしても無駄よ.");
	    return;
	}
	gnssWatchID = navigator.geolocation.watchPosition(
	    onSuccess, onError, {
		maximumAge: 0, timeout: 8000, enableHighAccuracy: true
	    });
	setTimeout(clearWatchGNSS, 10000);
	btnGet.classList.add('running');
	btnGet.disabled = true;
	dispInfo("取得中...");
    }
    function stopGNSS(ev) {
	clearWatchGNSS();
	dispInfo("衛星信号捕捉を停止しました.");
    }
    /*
    function onSuccessL(latlng) {
	mymap.panTo(latlng);		// 地図の中心を取得した位置に
	let lat = latlng.lat, lng = latlng.lng;
	let str = `ここは北緯${lat.toFixed(5)}, 東経${lng.toFixed(5)}. `;
	lastMarker.openPopup().setLatLng(latlng);// マーカのポイント変更
	dispInfo(str);
	console.log(latlng);
    }
    var lastloc = null;
    function onSuccess2(ev) {
	if (lastloc && ev.latlng.distanceTo(lastloc) < 10) {
	    onSuccessL(ev.latlng);	// 同一箇所を2連続タップしたら
	}
	lastloc = ev.latlng;
	}
    */
    function onSuccess(pos) { // 成功時のコールバック。関数名は何でもよい。
	// pos.coords に位置情報が入る。LeafletのLatLngに変換する。
	//onSuccessL(L.latLng([pos.coords.latitude, pos.coords.longitude]));
	console.log([pos.coords.latitude, pos.coords.longitude]);
	mvMarkerByGNSS(L.latLng([pos.coords.latitude, pos.coords.longitude]));
    }
    function onError(err) {// 失敗時のコールバック
	lastMarker.setPopupContent("取得失敗:"+restN).openPopup();
	dispInfo("空がよく見える位置でないと駄目なのよ");
	dispInfo("衛星信号捕捉は中止するわね.")
	clearWatchGNSS();
    }
    workerInit();
    mapInit();
});
