var player;
var audio_ctx;
var analyser;
var audio_data;
var canvas_ctx;
var draw_loop;
var vol_prev;

function init() {
	player = document.querySelector('#player');
	//init_analyzer();
	init_canvas();

	player.addEventListener('ended', nextTrack);
	player.addEventListener('loadedmetadata', display_duration);
	player.addEventListener('timeupdate', update_position);

	navigator.mediaSession.setActionHandler('play', playTrack);
	navigator.mediaSession.setActionHandler('pause', pauseTrack);
	navigator.mediaSession.setActionHandler('stop', stopTrack);
	navigator.mediaSession.setActionHandler('previoustrack', prevTrack);
	navigator.mediaSession.setActionHandler('nexttrack', nextTrack);

	let seek = document.querySelector('#seek-slider');
	seek.addEventListener('input', function(){
		player.currentTime = seek.value;
		display_current_time();
	});

	let vol = document.querySelector('#volume-slider');
	vol.addEventListener('input', function(){
		player.volume = vol.value/100;
		if (vol.value == 0) {
			document.querySelector('#vol-btn').style.display = 'none';
			document.querySelector('#vol-off-btn').style.display = 'initial';
		} else {
			document.querySelector('#vol-btn').style.display = 'initial';
			document.querySelector('#vol-off-btn').style.display = 'none';
		}
	});
}

async function get_rand_track() {
	let playlist = document.querySelector('#playlist-select').value;
	
	let q = new URLSearchParams();
	q.set('playlist', playlist);

	let res = await fetch("./rand_track/?" + q.toString())
	let data = await res.json();
	return data;
}

async function select_artist(event) {
	let artist = event.target.value;
	let playlist = document.querySelector('#playlist-select').value;

	let q = new URLSearchParams();
	q.set('albumartist', artist);
	q.set('playlist', playlist);
	let res = await fetch("./albums/?" + q.toString());
	let data = await res.json();

	populate_albums(data);
}

async function select_album(event) {
	let artist = document.querySelector('input[name=artist]:checked').value;
	let album = document.querySelector('input[name=album]:checked').value;
	let date = event.srcElement.parentElement.querySelector('.album_year').textContent;
	let playlist = document.querySelector('#playlist-select').value;

	let q = new URLSearchParams();
	q.set('albumartist', artist);
	q.set('album', album);
	q.set('date', date);
	q.set('playlist', playlist);
	let res = await fetch("./tracks/?" + q.toString());
	let data = await res.json();

	populate_tracks(data);
}

function populate_tracks(data) {
	clear_tracks();
	for (let i = 0; i < data.length; i++) {
		let track = document.importNode(document.querySelector('#track_template').content, true);
		track.querySelector('label').setAttribute('for', 'track_' + i);
		track.querySelector('input').setAttribute('id', 'track_' + i);
		track.querySelector('input').setAttribute('value', data[i]['title']);
		track.querySelector('.track_num').textContent = data[i]['discnumber'] + '.' + String(data[i]['tracknumber']).padStart(2, '0');
		track.querySelector('.track_title').textContent = data[i]['title'];
		let min = Math.floor(Math.round(data[i]['duration']) / 60);
		let sec = Math.round(data[i]['duration']) % 60;
		sec = String(sec).padStart(2, '0');
		track.querySelector('.track_length').textContent = min + 'm' + sec + 's';
		track.querySelector('.track').dataset.url = data[i]['filepath'];

		document.querySelector('#track_list').appendChild(track);
	}
}

function populate_albums(data) {
	clear_albums();
	clear_tracks();
	for (let i = 0; i < data.length; i++) {
		let album = document.importNode(document.querySelector('#album_template').content, true);
		album.querySelector('label').setAttribute('for', 'album_' + i);
		album.querySelector('input').setAttribute('id', 'album_' + i);
		album.querySelector('input').setAttribute('value', data[i]['album']);
		album.querySelector('img').setAttribute('src', data[i]['cover_art_path']);
		album.querySelector('.album_name').textContent = data[i]['album'];
		album.querySelector('.album_year').textContent = data[i]['date'];

		document.querySelector('#album_list').appendChild(album);
	}
}

function populate_artists(data) {
	clear_artists();
	clear_albums();
	clear_tracks();
	for (let i = 0; i < data.length; i++) {
		let artist = document.importNode(document.querySelector('#artist_template').content, true);
		artist.querySelector('label').setAttribute('for', 'artist_' + i);
		artist.querySelector('input').setAttribute('id', 'artist_' + i);
		artist.querySelector('input').setAttribute('value', data[i]);
		artist.querySelector('.artist_name').textContent = data[i];

		document.querySelector('#artist_list').appendChild(artist);
	}
}

function select_track(event) {
	let track = {}
	track['artist'] = document.querySelector('input[name=artist]:checked').value;
	track['album'] = document.querySelector('input[name=album]:checked').value;
	track['title'] = document.querySelector('input[name=track]:checked').value;

	let art_url = document.querySelector('input[name=album]:checked').parentElement.querySelector('img').src;
	art_url = art_url.replace('64x64', '256x256');
	let artwork = [{'src': art_url, 'sizes': '256x256', 'type': 'image/jpeg'}];
	track['artwork'] = artwork;

	let track_url = new URL(event.srcElement.parentElement.querySelector('.track').dataset.url, window.location);

	update_now_playing(track);
	player.src = track_url;
	playTrack();
}

async function select_playlist(event) {
	let playlist = document.querySelector('#playlist-select').value;
	document.cookie = "playlist=" + playlist + ";max-age=" + 60*60*24*365;

	let q = new URLSearchParams();
	q.set('playlist', playlist);
	let res = await fetch("./artists/?" + q.toString());
	let data = await res.json();

	populate_artists(data);
}

function clear_tracks() {
	let tracks = document.querySelector('#track_list');
	while (tracks.firstChild) {
		tracks.removeChild(tracks.lastChild);
	}
}

function clear_albums() {
	let albums = document.querySelector('#album_list');
	while (albums.firstChild) {
		albums.removeChild(albums.lastChild);
	}
}

function clear_artists() {
	let artists = document.querySelector('#artist_list');
	while (artists.firstChild) {
		artists.removeChild(artists.lastChild);
	}
}

async function nextTrack() {
	track = await get_rand_track();
	player.src = track.source;
	update_now_playing(track);
	playTrack();
}

function prevTrack() {
	// TODO: implement a history array
}

async function playTrack() {
	if (!audio_ctx) {
		init_analyzer();
	}
	if (!player.src) {
		return nextTrack();
	}
	player.play(); 
	navigator.mediaSession.playbackState = "playing";

	if (document.querySelector("#visualizer-select").value === 'bar_graph') {
		bar_graph();
	}

	document.querySelector("#play-btn").style.display = "none";
	document.querySelector("#pause-btn").style.display = "initial";
}

function pauseTrack() {
	player.pause();
	navigator.mediaSession.playbackState = "paused";

	document.querySelector("#play-btn").style.display = "initial";
	document.querySelector("#pause-btn").style.display = "none";
}

function stopTrack() {
	player.pause();
	player.load();
	navigator.mediaSession.playbackState = "none";

	document.querySelector("#play-btn").style.display = "initial";
	document.querySelector("#pause-btn").style.display = "none";
}

function setMediaSession(track) {
	navigator.mediaSession.metadata = new MediaMetadata({
		title: track.title,
		artist: track.artist,
		album: track.album,
		artwork: track.artwork
	});
}

function update_now_playing(track) {
	document.querySelector('#now_playing_artist').textContent = track.artist;
	document.querySelector('#now_playing_album').textContent = track.album;
	document.querySelector('#now_playing_title').textContent = track.title;
	document.querySelector('#cover_art').firstChild.src = track.artwork[0].src;
	setMediaSession(track);
}

function update_position() {
	if (!player.duration){return;}
	navigator.mediaSession.setPositionState({
		duration: Math.floor(player.duration),
		playbackRate: player.playbackRate,
		position: Math.floor(player.currentTime)
	});

	document.querySelector('#seek-slider').value = Math.floor(player.currentTime);
	display_current_time();
}

function calculate_time(raw_secs) {
	let mins = Math.floor(raw_secs / 60);
	let secs = Math.round(raw_secs % 60);
	let ret = mins + ':' + String(secs).padStart(2,'0');
	return ret;
}

function display_duration() {
	let dur = document.querySelector('#duration');
	dur.textContent = calculate_time(player.duration);

	document.querySelector('#seek-slider').max = Math.floor(player.duration);
}

function display_current_time() {
	cur = document.querySelector('#current-time');
	cur.textContent = calculate_time(player.currentTime);
}

function volume_off() {
	let vol = document.querySelector('#volume-slider');
	vol_prev = vol.value;
	vol.value = 0;
	player.volume = 0;

	document.querySelector('#vol-btn').style.display = 'none';
	document.querySelector('#vol-off-btn').style.display = 'initial';
}

function volume_restore() {
	let vol = document.querySelector('#volume-slider');
	vol.value = vol_prev;
	player.volume = vol_prev / 100;

	document.querySelector('#vol-btn').style.display = 'initial';
	document.querySelector('#vol-off-btn').style.display = 'none';
}

// --- visualizer ---
function select_visualizer(event) {
	if (event.target.value == 'bar_graph') {
		bar_graph();
	} else if (event.target.value == 'disabled') {
		cancelAnimationFrame(draw_loop);
		let canvas = document.querySelector('#visualizer');
		canvas_ctx.clearRect(0, 0, canvas.width, canvas.height);
	}
}

function init_analyzer() {
	audio_ctx = new AudioContext();
	analyser = audio_ctx.createAnalyser();
	let source = audio_ctx.createMediaElementSource(player);

	source.connect(analyser);
	source.connect(audio_ctx.destination);
}

function init_canvas() {
	let canvas = document.querySelector('#visualizer');
	canvas_ctx = canvas.getContext('2d');
	canvas_ctx.clearRect(0, 0, canvas.width, canvas.height);
}

function bar_graph() {
	analyser.fftSize = 256;
	analyser.minDecibels = -90;
	analyser.maxDecibels = -10;
	analyser.smoothingTimeConstant = 0.85;
	audio_data = new Uint8Array(analyser.frequencyBinCount);

	draw();
}

function draw() {
	draw_loop = requestAnimationFrame(draw);

	analyser.getByteTimeDomainData(audio_data);
	let canvas = document.querySelector('#visualizer');

	canvas_ctx.fillStyle = "rgb(0 0 0)";
	canvas_ctx.fillRect(0, 0, canvas.width, canvas.height);

	const barWidth = (canvas.width / analyser.frequencyBinCount) * 2.5;
	let barHeight;
	let x = 0;

	for (let i = 0; i < analyser.frequencyBinCount; i++) {
		barHeight = audio_data[i];

		canvas_ctx.fillStyle = `rgb(${barHeight + 100} 50 50)`;
		canvas_ctx.fillRect(x, canvas.height - barHeight, barWidth, barHeight);

		x += barWidth + 1;
	}
}