/*<VersionInfo>*/

var track = new Array();
var route = new Array();
var waypoints = new Array();
var markerIcon = new Array();
var markers = new Array();
var markers = new Array();
var map;
var currPoint = 0;
var currTrack = 0;
var playTimer;
var playing = false;
var centerPointer;
var infoPanel;
/*<ShowMeterPanel>*/
/*<RealTimePlay>*/

function displayMap() {
	var osm = L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
		minZoom: 2,
		maxZoom: 19,
		attribution: '&copy; <a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a> contributors'
	});

	var osmjp = L.tileLayer("https://tile.openstreetmap.jp/{z}/{x}/{y}.png", {
		minZoom: 2,
		maxZoom: 19,
		attribution: '&copy; <a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a> contributors'
	});

	var cjm = L.tileLayer("https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png", {
		minZoom: 2,
		maxZoom: 18,
		attribution: '&copy; <a href="https://maps.gsi.go.jp/development/ichiran.html" target="_blank">崙搚抧棟堾</a>'
	});

	var pale = L.tileLayer("https://cyberjapandata.gsi.go.jp/xyz/pale/{z}/{x}/{y}.png", {
		minZoom: 2,
		maxZoom: 18,
		attribution: '&copy; <a href="https://maps.gsi.go.jp/development/ichiran.html" target="_blank">崙搚抧棟堾</a>'
	});

	var air = L.tileLayer("https://cyberjapandata.gsi.go.jp/xyz/seamlessphoto/{z}/{x}/{y}.jpg", {
		minZoom: 2,
		maxZoom: 18,
		attribution: '&copy; <a href="https://maps.gsi.go.jp/development/ichiran.html" target="_blank">崙搚抧棟堾</a> | 僨乕僞僜乕僗: Landsat8夋憸(GSI,TSIC,GEO Grid/AIST,courtesy of USGS), 奀掙抧宍(GEBCO), <a href="https://lpdaac.usgs.gov/data_access" target="_blank">悽奅塹惎儌僓僀僋夋憸</a>(LP DAAC, USGS/EROS Center)'
	});

	map = L.map("map", {layers: [/*<MapTypeId>*/]});
	var baseMaps = {"OpenStreetMap杮壠": osm, "OpenStreetMap擔杮": osmjp, "抧棟堾抧恾乮昗弨乯": cjm, "抧棟堾抧恾乮扺怓乯": pale, "嬻拞幨恀": air};
	L.control.layers(baseMaps).addTo(map);
	L.control.scale({imperial: false}).addTo(map);
	map.addControl(L.control.fullscreen());
	/*<FitBounds>*/
	/*<SetView>*/

	var pointerIcon = L.icon({
		iconUrl: "/*<PointerIconImage>*/",
		iconSize: [32, 32],
		iconAnchor: [15, 15]
	});
	centerPointer = L.marker([0, 0], {icon: pointerIcon, zIndexOffset: 9999});

	setIcon();

	setWaypoints();
	setRoutes();
	/*<DrawWaypoints>*/
	setTracks();
}

function setWaypoints() {
/*<WaypointList>*/
}

function setRoutes() {
/*<RouteList>*/
}

function setTracks() {
/*<TrackList>*/
}

function TrackPoint(lat, lon, dist, height, hr, cad, time) {
	this.latlng = L.latLng(lat, lon);
	this.dist = parseFloat(dist);
	this.height = parseInt(height);
	this.hr = parseInt(hr);
	this.cad = parseInt(cad);
	this.time = new Date(time);
}

function drawTrack(n, color, width, opacity) {
	var tp = new Array();
	var i;
	for (i=0; i<track[n].length; i++) {
		tp.push(track[n][i].latlng);
	}

	var trackPath = L.polyline(tp, {
		color: color,
		opacity: opacity,
		weight: width
	});

	trackPath.addTo(map);
}

function drawRoute(color, width, opacity) {
	var routePath = L.polyline(route, {
		color: color,
		opacity: opacity,
		weight: width
	});

	routePath.addTo(map);
}

function drawWaypoints(showDate, showTime, showLocation, showHeight) {
	var i;
	for (i=0; i<waypoints.length; i++) {
		markers[i] = createMarker(waypoints[i], showDate, showTime, showLocation, showHeight);
	}
}

function setIcon() {
	var imgPath = "https://maps.google.com/mapfiles/ms/icons/";

	var MyIcon = L.Icon.extend({
		options: {
			shadowUrl: imgPath + "msmarker.shadow.png",
			iconSize:     [32, 32],
			shadowSize:   [59, 32],
			iconAnchor:   [16, 31],
			shadowAnchor: [16, 31],
			popupAnchor:  [0, -32]
		}
	});

	markerIcon[0] = new MyIcon({iconUrl: imgPath + "red.png"});
	markerIcon[1] = new MyIcon({iconUrl: imgPath + "orange.png"});
	markerIcon[2] = new MyIcon({iconUrl: imgPath + "yellow.png"});
	markerIcon[3] = new MyIcon({iconUrl: imgPath + "green.png"});
	markerIcon[4] = new MyIcon({iconUrl: imgPath + "blue.png"});
	markerIcon[5] = new MyIcon({iconUrl: imgPath + "pink.png"});
	markerIcon[6] = new MyIcon({iconUrl: imgPath + "lightblue.png"});
	markerIcon[7] = new MyIcon({iconUrl: imgPath + "red-dot.png"});
	markerIcon[8] = new MyIcon({iconUrl: imgPath + "orange-dot.png"});
	markerIcon[9] = new MyIcon({iconUrl: imgPath + "yellow-dot.png"});
	markerIcon[10] = new MyIcon({iconUrl: imgPath + "green-dot.png"});
	markerIcon[11] = new MyIcon({iconUrl: imgPath + "blue-dot.png"});
	markerIcon[12] = new MyIcon({iconUrl: imgPath + "pink-dot.png"});
	markerIcon[13] = new MyIcon({iconUrl: imgPath + "ltblue-dot.png"});
}

function MarkerInfo(lat, lon, height, date, time, icon, name, image, url, desc, largeImage) {
	this.point = L.latLng(parseFloat(lat), parseFloat(lon));
	this.height = parseInt(height);
	this.date = date;
	this.time = time;
	this.icon = icon;
	this.name = name;
	this.image = image;
	this.url = url;
	this.desc = desc;
	this.largeImage = largeImage;
}
MarkerInfo.prototype.getHtml = MarkerInfo_getHtml;

function MarkerInfo_getHtml(showDate, showTime, showLocation, showHeight, imageLoaded) {
	var html;

	html = '<div class="marker">';
	html += '<div class="marker_subject">' + this.name + '</div>';
	if (showDate || showTime) {
		html += '<div class="marker_time">';
		if (showDate) {
			html += this.date;
		}
		if (showTime) {
			if (showDate) {
				html += '&nbsp;';
			}
			html += this.time;
		}
		html += '</div>';
	}
	if (showLocation || showHeight) {
		html += '<div class="marker_location">';
		if (showLocation) {
			var prefix_lat = (this.point.lat >= 0) ? 'N' : 'S';
			var prefix_lon = (this.point.lng >= 0) ? 'E' : 'W';
			html += '(' + prefix_lat + Math.abs(this.point.lat).toFixed(6) + ', ' + prefix_lon + Math.abs(this.point.lng).toFixed(6) + ')';
		}
		if (showHeight) {
			if (showLocation) {
				html += '&nbsp;';
			}
			html += '崅搙' + this.height + 'm';
		}
		html += '</div>';
	}
	if (this.image != '') {
		var ext = getFileExt(this.image);
		if (ext == 'jpg' || ext == 'jpeg' || ext == 'gif' || ext == 'png') {
			if (imageLoaded) {
				if (this.largeImage != '') {
					html += '<div class="marker_image"><a href="' + this.largeImage + '" target="largeImage"><img src="' + this.image + '" /></a></div>';
				}
				else {
					html += '<div class="marker_image"><img src="' + this.image + '" /></div>';
				}
			}
		}
		else {
			html += '<div class="marker_url"><a href="' + this.image + '" target="refer">娭楢僼傽僀儖</a></div>';
		}
	}
	if (this.url != '') {
		html += '<div class="marker_url"><a href="' + this.url + '" target="refer">娭楢儕儞僋</a></div>';
	}
	if (this.desc != '') {
		html += '<div class="marker_desc">' + this.desc + '</div>';
	}
	html += '</div>';

	return html;
}

function createMarker(markerInfo, showDate, showTime, showLocation, showHeight) {
	var marker = L.marker(markerInfo.point, {
		title: markerInfo.name,
		icon: markerIcon[markerInfo.icon],
	}).addTo(map);

	if (markerInfo.image != "") {
		var ext = getFileExt(markerInfo.image);
		if (ext == 'jpg' || ext == 'jpeg' || ext == 'gif' || ext == 'png') {
			var image = new Image();
			image.src = markerInfo.image;
			if (image.complete) {
				marker.bindPopup(markerInfo.getHtml(showDate, showTime, showLocation, showHeight, true), {maxWidth: 900});
			}
			else {
				image.onload = function() {
					marker.bindPopup(markerInfo.getHtml(showDate, showTime, showLocation, showHeight, true), {maxWidth: 900});
				}
				image.onerror = function() {
					marker.bindPopup(markerInfo.getHtml(showDate, showTime, showLocation, showHeight, false), {maxWidth: 900});
				}
			}
		}
		else {
			marker.bindPopup(markerInfo.getHtml(showDate, showTime, showLocation, showHeight, false), {maxWidth: 900});
		}
	}
	else {
		marker.bindPopup(markerInfo.getHtml(showDate, showTime, showLocation, showHeight, false), {maxWidth: 900});
	}

	return marker;
}

function popupMarker(num) {
	markers[num].fireEvent("click");
}

function getFileExt(filepath) {
	var strArray = filepath.split('.');
	return strArray[strArray.length - 1].toLowerCase();
}

function paddingZero(value, n) {
	// n < 13
	var str = value + "";
	str = "0000000000000".substr(0, (n - str.length)) + str;

	return str;
}

function paddingSpace(value, n) {
	// n < 11
	var str = value + "";
	str = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;".substr(0, 6 * (n - str.length)) + str;

	return str;
}

function getBrowser() {
	var agent = navigator.userAgent;

	if (agent.indexOf('Safari') >= 0) {
		return 'Safari';
	}
	else if (agent.indexOf('Opera') >= 0) {
		return 'Opera';
	}
	else if (agent.indexOf('Gecko') >= 0) {
		return 'Mozilla';
	}
	else if (agent.indexOf('MSIE') >= 0) {
		return 'MSIE';
	}
	else {
		return 'other';
	}
}

function playRoute() {
	var count = 0;
	for (i=0; i<track.length; i++) {
		count += track[i].length;
	}

	if (count > 1 && !playing) {
		centerPointer.addTo(map);

		if (showMeterPanel) {
			infoPanel = new InfoPanel();
			map.addControl(infoPanel);
		}

		playing = true;
		goForward();
	}
}

function goForward() {
	var waittime;
	var pos = track[currTrack][currPoint].latlng;
	map.panTo(pos);
	centerPointer.setLatLng(pos);

	if (showMeterPanel) {
		displayInfoPanel(currTrack, currPoint);
	}

	if (currPoint < track[currTrack].length - 1) {
		if (realTimePlay) {
			waittime = track[currTrack][currPoint+1].time.getTime() - track[currTrack][currPoint].time.getTime();
			waittime /= parseFloat(document.getElementById("playSpeed").value);
		}
		else {
			waittime = 1000 / parseFloat(document.getElementById("playSpeed").value);
		}
		currPoint++;
	}
	else {
		if (currTrack < track.length - 1) {
			waittime = 1000;
			currTrack++;
			currPoint = 0;
		}
		else {
			window.clearTimeout(playTimer);
			playing = false;
			centerPointer.remove();

			if (showMeterPanel) {
				map.removeControl(infoPanel);
			}

			return;
		}
	}
	playTimer = window.setTimeout("goForward()", waittime);
}

function stopRoute() {
	if (playing) {
		window.clearTimeout(playTimer);
		playing = false;
		centerPointer.remove();

		if (showMeterPanel) {
			map.removeControl(infoPanel);
		}
	}
}

function rewindRoute() {
	currTrack = 0;
	currPoint = 0;
	map.panTo(track[currTrack][currPoint].latlng);
}

function prevTrack() {
	if (currTrack > 0) {
		currTrack--;
		currPoint = 0;
		map.panTo(track[currTrack][currPoint].latlng);
	}
}

function nextTrack() {
	if (currTrack < track.length - 1) {
		currTrack++;
		currPoint = 0;
		map.panTo(track[currTrack][currPoint].latlng);
	}
}

var InfoPanel = L.Control.extend({
	options: {
        	position: "bottomright"
	},

	onAdd: function(map) {
		var container = document.createElement('div');
		container.style.padding = '5px';

		var outerFrame = document.createElement('div');
		outerFrame.style.width = '240px';
		outerFrame.style.height = '70px';
		if (getBrowser() == 'MSIE') {
			outerFrame.style.backgroundColor = '#FFFFFF';
		}
		else {
			outerFrame.style.backgroundColor = 'rgba(255, 255, 255, 0.65)';
		}
		outerFrame.style.border = '1px solid black';
		outerFrame.innerHTML = '<div id="time"></div><div id="speed"></div><div id="height"></div>';
		container.appendChild(outerFrame);
		return container;
	},

	writeTime: function(date) {
		var hour = paddingZero(date.getHours(), 2);
		var min = paddingZero(date.getMinutes(), 2);
		var sec = paddingZero(date.getSeconds(), 2);
		var timePanel = document.getElementById("time");
		timePanel.innerHTML = '帪崗丗' + hour + ':' + min + ':' + sec;
	},

	writeSpeed: function(distance, speed) {
		var speedPanel = document.getElementById("speed");
		var distStr = paddingSpace(distance.toFixed(2), 7);
		var speedStr = paddingSpace(speed.toFixed(1), 6);
		speedPanel.innerHTML = '嫍棧丗' + distStr + 'km&nbsp;&nbsp;懍搙丗' + speedStr + 'km/h';
	},

	writeHeight: function(height, gradient) {
		var heightStr = paddingSpace(height, 5);
		var gradStr = paddingSpace(Math.abs(gradient).toFixed(1), 4);
		if (gradient >= 0) {
			gradStr = '仾' + gradStr;
		}
		else {
			gradStr = '伀' + gradStr;
		}
		var heightPanel = document.getElementById("height");
		heightPanel.innerHTML = '崅搙丗' + heightStr + 'm&nbsp;&nbsp;岡攝丗' + gradStr + '%';
	}
});

function displayInfoPanel(ntrack, npoint) {
	infoPanel.writeTime(track[ntrack][npoint].time);
	
	var distance = 0;
	var speed = 0;
	var timespan;
	var gradient = 0;
	var elevation;
	if (npoint > 0) {
		distance = track[ntrack][npoint].dist - track[ntrack][npoint - 1].dist;
		timespan = track[ntrack][npoint].time.getTime() - track[ntrack][npoint - 1].time.getTime();
		elevation = track[ntrack][npoint].height - track[ntrack][npoint - 1].height;
		if (timespan > 0) {
			speed = 3600000 * distance / timespan;
		}
		if (distance > 0) {
			gradient = elevation / distance / 10;
		}
	}
	speed = Math.round(speed * 10) / 10;

	infoPanel.writeSpeed(track[ntrack][npoint].dist,speed);
	infoPanel.writeHeight(track[ntrack][npoint].height,gradient);
}

function calcSpeed(ntrack, npoint) {
	var speed = 0;
	if (npoint > 0) {
		var distance = track[ntrack][npoint].dist - track[ntrack][npoint-1].dist;
		var timespan = track[ntrack][npoint].time.getTime() - track[ntrack][npoint-1].time.getTime();
		if (timespan > 0) {
			speed = 3600000 * distance / timespan;
		}
	}

	return speed;
}
