/*
Social program for Ramaskrik.
Copyright (C) 2019 Harald Eilertsen <haraldei@anduin.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
function fetch_rooms(data_done) {
let req = new XMLHttpRequest()
req.addEventListener("load", data_done)
req.open("GET", "http://localhost:8000/rooms")
req.responseType = "json"
req.send()
}
function load_screenings(data_done) {
let req = new XMLHttpRequest()
req.addEventListener("load", data_done)
req.open("GET", "http://localhost:8000/screenings")
req.responseType = "json"
req.send()
}
function pluralize(num, word) {
let result = num + " " + word
if (num > 1) {
result += "s"
}
return result
}
function log_film(film) {
console.log(film["title"]
+ " ("
+ pluralize(film["screenings"].length, "screening")
+ ")")
}
function date_f(d) {
let opts = { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' }
return new Intl.DateTimeFormat('nb-NO', opts).format(d)
}
window.addEventListener("load", function() {
let screenings_by_date = new Map()
function _add(screening) {
let d = Date.parse(screening.date)
if (!screenings_by_date.has(d))
screenings_by_date.set(d, new Array())
let s = screenings_by_date.get(d)
s.push(screening)
};
function _end_time(screening) {
if (screening.end_time < screening.start_time) {
return screening.end_time
.split(':')
// Add 24 to the hour component of the time string
.map( (v, i) => i == 0 ? (parseInt(v) + 24).toString() : v)
.join(':')
}
else {
return screening.end_time
}
}
function _time_to_sec(t) {
let expl = t.split(':').map( v => parseInt(v) )
return expl[0] * 3600 + expl[1] * 60 + expl[2]
}
function _sec_to_time(v) {
let hour = Math.floor(v / 3600)
v = v % 3600
let min = Math.floor(v / 60)
let f = Intl.NumberFormat('nb-NO', { minimumIntegerDigits: 2 })
return [ f.format(hour), f.format(min) ].join(':')
}
function break_text(c, text, x, y, width) {
let len = c.measureText(text).width
if (len < width) {
c.fillText(text, x, y)
return
}
let expl = text.split(' ')
let space = c.measureText(' ').width
let llen = 0
let lpos = 0
for (let frag of expl) {
flen = c.measureText(frag).width
llen += flen
if (llen > width) {
llen = 0
lpos = 0
y += 15
}
c.fillText(frag, x + lpos, y)
lpos += flen + space
}
}
function center_text(c, text, x, y, width) {
let len = c.measureText(text).width
let xpos = Math.ceil((width - len) / 2)
c.fillText(text, x + xpos, y)
}
let margin = 30;
let xmargin = 50;
function draw_timescale(c, start, end) {
let dur = Math.ceil((end - start) / 30)
c.font = '10px Helvetica'
c.lineWidth = 'thin'
c.strokeStyle = '#ccc'
for (let y = 0; y <= dur; y += 30) {
let ypos = y + margin;
c.beginPath()
c.moveTo(35, ypos)
c.lineTo(510, ypos)
c.stroke()
c.fillText(_sec_to_time(y * 30 + start + margin), 5, ypos + 3)
}
}
function draw_room_headers(c, rooms) {
let x = 0;
c.font = '15px sans-serif'
for (let r of [...rooms]) {
center_text(c, r, 50 + x, 15, 100)
x += 150
}
}
function draw_screenings(c, screenings, start_time, rooms) {
let r = [...rooms]
c.strokeStyle = '#000'
for (let s of screenings) {
let ystart = Math.ceil((_time_to_sec(s.start_time) - start_time) / 30) + margin;
let height = Math.ceil((_time_to_sec(_end_time(s)) - start_time ) / 30) + margin - ystart;
let ri = s.room.id - 1
let xstart = xmargin + ri * 150
c.fillStyle = '#ec9'
c.fillRect(xstart, ystart, 100, height)
c.strokeRect(xstart, ystart, 100, height)
c.fillStyle = '#000'
break_text(c, s.film.title, xstart + 5, ystart + 15, 90)
}
}
load_screenings(function() {
this.response.forEach(_add)
console.log("Screenings in " + screenings_by_date.size + " days: ")
for (let date of screenings_by_date.keys()) {
let date_str = date_f(date)
console.log(date_str)
let s = screenings_by_date.get(date)
let start_time = s
.map( el => _time_to_sec(el.start_time) )
.reduce( (acc, cur) => cur < acc ? cur : acc, _time_to_sec('23:59:59') )
let end_time = s
.map( el => _time_to_sec(_end_time(el)))
.reduce( (acc, cur) => cur > acc ? cur : acc, 0 )
console.log(" Start time: " + _sec_to_time(start_time))
console.log(" End time : " + _sec_to_time(end_time))
let dur = end_time - start_time
console.log(" Duration : " + _sec_to_time(dur))
// Each line in the canvas equals half a minute
let canvas_height = Math.ceil(dur / 30) + 60
let p = document.querySelector('#program')
let day = document.createElement('section')
day.id = "program-" + date_str
day.innerHTML = '<h2>' + date_str + '</h2>'
+ '<canvas id="canvas-' + date_str + '" height="' + canvas_height + '" width="350">'
+ '</canvas>'
p.appendChild(day)
let canvas = document.getElementById('canvas-' + date_str)
let c = canvas.getContext('2d');
let rooms = new Set(s.map( el => el.room.name ))
draw_room_headers(c, rooms)
draw_timescale(c, start_time, end_time)
draw_screenings(c, s, start_time, rooms)
}
})
/*
fetch_rooms(function() {
let table = document.getElementById("screening-table")
let row = document.createElement("tr")
table.appendChild(row)
this.response.forEach(function(room) {
console.log(room["name"])
let item = document.createElement("th")
item.innerHTML = room["name"]
row.appendChild(item)
})
})
*/
console.log("Holahey!")
})