+urlbase="mpd.lua?"
+minScrollHeight=200
+
+currentState=""
+
+function GetFilename(url)
+{
+ if (url)
+ return url.split('/').pop().split('#')[0].split('?')[0];
+}
+
+function EscapeStr(str) {
+ res = str.replace(/'/g,"\\'");
+ return res;
+}
+
+function SetSize() {
+ var w = window,
+ d = document,
+ e = d.documentElement,
+ g = d.getElementsByTagName('body')[0],
+ body_h = g.clientHeight,
+ window_h = w.innerHeight|| e.clientHeight|| g.clientHeight,
+ items = d.getElementById('items'),
+ current_h = items.clientHeight,
+ new_h=(window_h-body_h)+current_h;
+ if (new_h>minScrollHeight) {
+ items.style.height=new_h+"px";
+ }
+}
+
+function toHHMMSS(seconds) {
+ var hours = Math.floor(seconds / 3600);
+ seconds -= hours*3600;
+ var minutes = Math.floor(seconds / 60);
+ seconds -= minutes*60;
+
+ if (hours < 10) {hours = "0"+hours;}
+ if (minutes < 10) {minutes = "0"+minutes;}
+ if (seconds < 10) {seconds = "0"+seconds;}
+ if (hours == 0) {
+ return minutes+':'+seconds;
+ } else {
+ return hours+':'+minutes+':'+seconds;
+ }
+}
+
+function RefreshTime() {
+ if (currentSeconds) {
+ currentTime = toHHMMSS(currentSeconds)
+ trackTime = toHHMMSS(trackSeconds)
+ nowPlayingTime = currentTime+"/"+trackTime
+ } else {
+ nowPlayingTime = "-:--/-:--"
+ }
+ document.getElementById('nowplaying_tracklen').innerHTML=nowPlayingTime;
+}
+
+function PeriodicRefreshTime() {
+ if (currentState == "play") {
+ nowTime = Date.now()
+ delta = (nowTime - updateTime)/1000
+ currentSeconds = updateSeconds + Math.round(delta)
+ if (currentSeconds > trackSeconds) {
+ currentSeconds = trackSeconds
+ }
+ RefreshTime()
+ }
+}
+
+function RefreshPageStatus() {
+
+ var req = new XMLHttpRequest();
+
+ req.onreadystatechange = function () {
+ if (this.readyState != 4 || this.status != 200) return;
+ var returnedData = JSON.parse(this.responseText);
+ trackName = GetFilename(returnedData['current_playing']);
+ trackNo = returnedData['song'];
+ currentState = returnedData['state'];
+ document.title='MPD Player: '+trackName;
+ if (trackNo) {
+ var nowPlayingTrackNo=String(1+Number(trackNo))
+ } else {
+ var nowPlayingTrackNo="-"
+ }
+ nowPlayingTrack = nowPlayingTrackNo + '/' + returnedData['playlistlength'];
+ nowPlayingName = trackName;
+ playingTime = returnedData['time']
+ if (playingTime) {
+ var splits = playingTime.split(":")
+ updateTime = Date.now()
+ currentSeconds = Number(splits[0])
+ updateSeconds = currentSeconds
+ trackSeconds = Number(splits[1])
+ } else {
+ currentSeconds = null
+ }
+ if (currentState=='stop') {
+ nowPlayingName = '<font color="gray">' + nowPlayingName+ '</font>'
+ }
+ document.getElementById('nowplaying_trackno').innerHTML=nowPlayingTrack;
+ document.getElementById('nowplaying_trackname').innerHTML=nowPlayingName;
+ RefreshTime()
+ if (currentState=="play") {
+ document.getElementById('playpausebutton').innerHTML="<span onclick=\"Command('pause')\"><img class=\"button\" title=\"Pause\" src=\"images/pause.svg\"></span>";
+ } else {
+ document.getElementById('playpausebutton').innerHTML="<span onclick=\"Command('play')\"><img class=\"button\" title=\"Play\" src=\"images/play-button.svg\"></span>";
+ }
+ if (currentState=="stop") {
+ document.getElementById('stopbutton').innerHTML="<span><img class=\"button\" src=\"images/stopoff.svg\"></span>";
+ } else {
+ document.getElementById('stopbutton').innerHTML="<span onclick=\"Command('stop')\"><img class=\"button\" title=\"Stop\" src=\"images/stop.svg\"></span>";
+ }
+ if (returnedData["repeat"]=="1") {
+ document.getElementById('repeatstate').innerHTML="<img class=\"button\" title=\"Replay is on\" src=\"images/replay.svg\"></a>";
+ } else {
+ document.getElementById('repeatstate').innerHTML="<img class=\"button\" title=\"Replay is off\" src=\"images/replayoff.svg\"></a>";
+ }
+ document.getElementById('volume_total').innerHTML="<div id=\"volume_actual\" style=\"width:"+returnedData["volume"]+"%\">";
+
+ var items = document.getElementById('items');
+ var table = items.getElementsByClassName('track');
+ var current_track="track_"+trackNo;
+ for (var i = 0; i < table.length; i++) {
+ if (table[i].id==current_track) {
+ table[i].classList.add("itemActive");
+ } else {
+ table[i].classList.remove("itemActive")
+ }
+ }
+
+ };
+
+ req.open("GET", urlbase+"status", true);
+ req.send();
+
+}
+
+function RefreshPlaylist() {
+
+var req = new XMLHttpRequest();
+
+req.onreadystatechange = function () {
+ if (this.readyState != 4 || this.status != 200) return;
+ var returnedData = JSON.parse(this.responseText);
+
+ var playlistMenuText = "<table>\
+ <tr>\
+ <td><span onclick=\"EditPlayList()\"><img class=\"medium-button\" title=\"Files\" src=\"images/folder.svg\"></span><td>\
+ <td><span onclick=\"LoadPlayList()\"><img class=\"medium-button\" title=\"Lists\" src=\"images/list.svg\"></span><td>\
+ <td><span onclick=\"SavePlayList()\"><img class=\"medium-button\" title=\"Save current list\" src=\"images/download.svg\"></span><td>\
+ <td><span onclick=\"return confirm('Clear current playlist, are you sure?') ? PlaylistCommand('clear') : false;\" ><img class=\"medium-button\" title=\"Clear current list\" src=\"images/cancel.svg\"></span><td>\
+ </tr>\
+ </table>";
+
+ var itemsText="<table>\
+ <tr id=\"items_heading\">\
+ <td></td class=\"track_number\"><td class=\"file\">Title</td><td class=\"medium-button\" colspan=\"3\">Controls</td>\
+ </tr>";
+
+ var even = 0;
+ for (var key in returnedData) {
+ var rec=returnedData[key];
+ var name=GetFilename(rec["name"]);
+ var id=rec["id"];
+
+ if (even) {
+ evText="itemEven";
+ } else {
+ evText="itemOdd";
+ };
+
+ even = ! even;
+
+ itemsText = itemsText + "<tr id=\"track_"+id+"\" class=\"track "+evText+"\">\
+ <td class=\"track_number\">\
+ <a name=\""+id+"\">"+(Number(id)+1)+"</a></td>\
+ </td>\
+ <td class=\"file\">\
+ <span class=\"link\" onclick=\"PlaylistCommand('playitem',"+id+")\">"+name+"</span>\
+ </td>\
+ <td class=\"move\">\
+ <span onclick=\"PlaylistCommand('moveup',"+id+")\"><img class=\"small-button\" title=\"Move up\" src=\"images/up-arrow.svg\"></span>\
+ </td>\
+ <td class=\"move\">\
+ <span onclick=\"PlaylistCommand('movedown',"+id+")\"><img class=\"small-button\" title=\"Move down\" src=\"images/down-arrow.svg\"></span>\
+ </td>\
+ <td class=\"remove\">\
+ <span onclick=\"PlaylistCommand('remove',"+id+")\"><img class=\"small-button\" title=\"Remove\" src=\"images/cancel.svg\"></span>\
+ </td>\
+ </tr>";
+ }
+
+ itemsText = itemsText + "</table>";
+
+ document.getElementById('items').innerHTML=itemsText;
+ document.getElementById('playlist_menu_top').innerHTML=playlistMenuText;
+ document.getElementById('playlist_menu_bottom').innerHTML=playlistMenuText;
+};
+
+req.open("GET", urlbase+"playlist", true);
+req.send();
+
+}
+
+function EditPlayList(dir) {
+
+var req = new XMLHttpRequest();
+
+req.onreadystatechange = function () {
+ if (this.readyState != 4 || this.status != 200) return;
+ var returnedData = JSON.parse(this.responseText);
+
+ var playlistMenuText = "<table>\
+ <tr>\
+ <td><span onclick=\"RefreshPlaylist()\"><img class=\"medium-button\" title=\"Home\" src=\"images/list.svg\"></span><td>\
+ <td><span onclick=\"return confirm('Add all to the list, are you sure?') ? PlaylistEditCommand('add','"+EscapeStr(dir)+"') : false;\" ><img class=\"medium-button\" title=\"Add all\" src=\"images/plus.svg\"></span><td>\
+ </tr>\
+ </table>";
+
+ var itemsText= "<table>\
+ <tr id=\"items_heading\">\
+ <td></td class=\"track_number\"><td class=\"file\">Title</td><td colspan=\"2\">Controls</td>\
+ </tr>";
+
+ var even = 0;
+ if (dir) {
+ var lastSlash=dir.lastIndexOf("/");
+ if (lastSlash>0) {
+ var upperLevel=dir.slice(0,lastSlash);
+ } else {
+ var upperLevel="";
+ }
+ even = ! even;
+ var itemsText = itemsText + "<tr class=\"itemOdd\">\
+ <td class=\"track_number\"></td>\
+ <td class=\"file\"><span class=\"link\" onclick=\"EditPlayList('"+upperLevel+"')\">..</span></td>\
+ <td></td><td></td>";
+ }
+
+ var i = 0;
+ for (var key in returnedData) {
+ var rec=returnedData[key];
+ var type=rec["type"];
+ var name=rec["name"];
+ var lastSlash=name.lastIndexOf("/");
+ if (lastSlash>0) {
+ var tailName=name.slice(lastSlash+1);
+ } else {
+ var tailName=name
+ };
+
+ if (type == "directory" || type == "file") {
+ if (even) {
+ evText="itemEven";
+ } else {
+ evText="itemOdd";
+ };
+
+ i = i + 1;
+ even = ! even;
+
+ itemsText = itemsText + "<tr class=\""+evText+"\">\
+ <td class=\"track_number\">\
+ <a name=\""+i+"\"></a></td>\
+ </td>";
+
+ if (type == "directory") {
+ itemsText = itemsText + "<td class=\"file\">\
+ <span class=\"link\" onclick=\"EditPlayList('"+EscapeStr(name)+"')\">"+tailName+"</span></td><td>\
+ <span onclick=\"PlaylistEditCommand('add','"+EscapeStr(name)+"')\"><img class=\"small-button\" title=\"Add\" src=\"images/plus.svg\"></span></td>";
+ };
+
+ if (type == "file") {
+ itemsText = itemsText + "<td class=\"file\">\
+ <span class=\"link\" onclick=\"PlaylistEditCommand('add','"+EscapeStr(name)+"')\">"+tailName+"</span></td><td>\
+ <span onclick=\"PlaylistEditCommand('add','"+EscapeStr(name)+"')\"><img class=\"small-button\" title=\"Add\" src=\"images/plus.svg\"></span></td>";
+ };
+
+ itemsText = itemsText + "</tr>";
+
+ }
+
+ }
+
+ var itemsText = itemsText+"</table>";
+ document.getElementById('items').innerHTML=itemsText;
+ document.getElementById('playlist_menu_top').innerHTML=playlistMenuText;
+ document.getElementById('playlist_menu_bottom').innerHTML=playlistMenuText;
+};
+
+if (!dir) { dir = ''; };
+
+req.open("GET", urlbase+"lists|edit|"+dir, true);
+req.send();
+
+}
+
+function LoadPlayList() {
+
+var req = new XMLHttpRequest();
+
+req.onreadystatechange = function () {
+ if (this.readyState != 4 || this.status != 200) return;
+ var returnedData = JSON.parse(this.responseText);
+ playlistMenuText="<table>\
+ <tr>\
+ <td><span onclick=\"RefreshPlaylist()\"><img class=\"medium-button\" title=\"Home\" src=\"images/list.svg\"></span><td>\
+ <td><span onclick=\"confirm('Clear current playlist, are you sure?') ? PlaylistCommandRefStatus('clear') : false;\" ><img class=\"medium-button\" title=\"Clear all\" src=\"images/cancel.svg\"></span><td>\
+ </tr>\
+ </table>";
+ itemsText="<table>\
+ <tr id=\"items_heading\">\
+ <td class=\"track_number\"></td><td class=\"file\">Name</td><td>Controls</td>\
+ </tr>";
+
+ var even = 0;
+ for (var key in returnedData) {
+ var name=returnedData[key];
+
+ if (even) {
+ evText="itemEven";
+ } else {
+ evText="itemOdd";
+ };
+
+ even = ! even;
+
+ itemsText = itemsText + "<tr class=\""+evText+"\">\
+ <td class=\"track_number\"><a name=\"0\"></a></td>\
+ <td class=\"file\"><span class=\"link\" onclick=\"PlaylistEditCommandRefFull('load','"+EscapeStr(name)+"')\">"+name+"</td>\
+ <td class=\"controls\"><span onclick=\"confirm('Delete playlist "+name+", are you sure?') ? DelPlayList('"+EscapeStr(name)+"') : false;\"><img class=\"small-button\" title=\"Delete\" src=\"images/minus.svg\"></span></td>\
+ </tr>";
+ }
+
+ itemsText=itemsText+"</table>";
+ document.getElementById('items').innerHTML=itemsText;
+ document.getElementById('playlist_menu_top').innerHTML=playlistMenuText;
+ document.getElementById('playlist_menu_bottom').innerHTML=playlistMenuText;
+};
+
+req.open("GET", urlbase+"lists|load", true);
+req.send();
+
+}
+
+function SavePlayList() {
+
+var name=window.prompt('List name','');
+
+var req = new XMLHttpRequest();
+
+req.onreadystatechange = function () {
+ if (this.readyState != 4 || this.status != 200) return;
+ if (this.responseText != 'OK') {
+ window.alert(this.responseText);
+ }
+};
+
+req.open("GET", urlbase+"lists|save|"+name, true);
+req.send();
+
+}
+
+function DelPlayList(item) {
+
+var req = new XMLHttpRequest();
+
+req.onreadystatechange = function () {
+ if (this.readyState != 4 || this.status != 200) return;
+ LoadPlayList();
+ RefreshPageStatus();
+};
+
+req.open("GET", urlbase+"lists|delete|"+item, true);
+req.send();
+
+}
+
+function RefreshPageContent() {
+ RefreshPlaylist();
+ RefreshPageStatus();
+}
+
+function Command(cmd) {
+
+var req = new XMLHttpRequest();
+
+req.onreadystatechange = function () {
+ if (this.readyState != 4 || this.status != 200) return;
+ RefreshPageStatus();
+};
+
+req.open("GET", urlbase+cmd, true);
+req.send();
+
+}
+
+function PlaylistCommand(cmd,item) {
+
+var req = new XMLHttpRequest();
+
+req.onreadystatechange = function () {
+ if (this.readyState != 4 || this.status != 200) return;
+ RefreshPageContent();
+};
+
+req.open("GET", urlbase+"cpl|"+cmd+"|"+item, true);
+req.send();
+
+}
+
+function PlaylistCommandRefStatus(cmd,item) {
+
+var req = new XMLHttpRequest();
+
+req.onreadystatechange = function () {
+ if (this.readyState != 4 || this.status != 200) return;
+ RefreshPageStatus();
+};
+
+req.open("GET", urlbase+"cpl|"+cmd+"|"+item, true);
+req.send();
+
+}
+
+function PlaylistEditCommand(cmd,item) {
+
+var req = new XMLHttpRequest();
+
+req.onreadystatechange = function () {
+ if (this.readyState != 4 || this.status != 200) return;
+ RefreshPageStatus();
+};
+
+req.open("GET", urlbase+"lists|"+cmd+"|"+item, true);
+req.send();
+
+}
+
+function PlaylistEditCommandRefFull(cmd,item) {
+
+var req = new XMLHttpRequest();
+
+req.onreadystatechange = function () {
+ if (this.readyState != 4 || this.status != 200) return;
+ RefreshPageContent();
+};
+
+req.open("GET", urlbase+"lists|"+cmd+"|"+item, true);
+req.send();
+
+}
+
+function subscribe_status() {
+ var xhr = new XMLHttpRequest();
+
+ xhr.onreadystatechange = function() {
+ if (this.readyState != 4) return;
+ if (this.status == 200) {
+ RefreshPageStatus()
+ setTimeout(subscribe_status,1000)
+ } else {
+ setTimeout(subscribe_status,15000)
+ }
+ }
+ xhr.open("GET", urlbase+"idle", true);
+ xhr.send();
+}
+
+setTimeout(subscribe_status,5000)
+setInterval(PeriodicRefreshTime, 1000);