<?php
include_once("../includes/ctrlacc.php");
include_once("../includes/CreaComando.php");
include_once("../includes/timezone.php");
include_once("../clases/AdoPhp.php");

function add_cal_to_db ($desc, $j) {
    global $cadenaconexion;
    $cmd = CreaComando ($cadenaconexion);
    if (!$cmd) {
        die ($TbMsg['ACCESS_ERROR']);
    }
    $cmd->CreaParametro ('@desc',      $desc, 0);
    $cmd->CreaParametro ('@json_text', $j,    0);
    $cmd->texto = 'INSERT INTO calendarios (description, json_text) VALUES (@desc, @json_text);';
    if (!$cmd->Ejecutar()) {
        return $cmd->DescripUltimoError();
    }
    return;
}

function modify_cal_in_db ($id, $desc, $j) {
    global $cadenaconexion;
    $cmd = CreaComando ($cadenaconexion);
    if (!$cmd) {
        die ($TbMsg['ACCESS_ERROR']);
    }
    $cmd->CreaParametro ('@id',        $id,   0);
    $cmd->CreaParametro ('@desc',      $desc, 0);
    $cmd->CreaParametro ('@json_text', $j,    0);
    $cmd->texto = 'UPDATE calendarios SET description=@desc, json_text=@json_text WHERE idcalendario=@id;';
    if (!$cmd->Ejecutar()) {
        return $cmd->DescripUltimoError();
    }
    return;
}

function fetch_cal_from_db ($id) {
    global $cadenaconexion;
    $cmd = CreaComando ($cadenaconexion);
    if (!$cmd) {
        die ($TbMsg['ACCESS_ERROR']);
    }
    $cmd->CreaParametro ('@id', $id, 0);
    $cmd->texto = 'SELECT description, json_text FROM calendarios WHERE idcalendario=@id;';
    $rs = new Recordset;
    $rs->Comando = &$cmd;

    if (!$rs->Abrir()) return (false);

    $rs->Primero();
    if ($rs->EOF) {
        return array ('', '{"remotepc_calendar":{"timezone":"' . $tz . '","ruleset":[]}}');
    }
    $desc = $rs->campos['description'];
    $json = $rs->campos['json_text'];
    return array ($desc, $json);
}

function process_post ($cal_id, $desc, $json_str) {
    $errors = array();

    if (empty ($desc)) {
        array_push ($errors, 'Description of new calendar is unset');
    }
    if (sizeof ($errors)) {
        return $errors;
    }

    if (-1 == $cal_id) {
        $db_err = add_cal_to_db ($desc, $json_str);
    } else {
        $db_err = modify_cal_in_db ($cal_id, $desc, $json_str);
    }

    if ($db_err) {
        array_push ($errors, $db_err);
    }

    if (!sizeof ($errors)) {
        header ('Location: calendars.php');
    }
    return $errors;
}


$error_str = '';
function parse_params() {
    global $tz, $error_str;

    if (isset ($_GET['cal_id']) && isset ($_POST['cal_id'])) {
        $error_str = "Got a cal_id in both a GET and a POST??\n";
        return 0;
    }

    if (isset ($_GET['cal_id'])) {
        $cal_id = $_GET['cal_id'];
        $is_get = 1;
    } elseif (isset ($_POST['cal_id'])) {
        $cal_id = $_POST['cal_id'];
        $is_get = 0;
    } else {
        $error_str = "Didn't get a cal_id in neither GET nor POST\n";
        return 0;
    }

    $ret = 0;
    if (-1 == $cal_id) {
        // nuevo calendario
        // seguro que es un POST

        if (!isset ($_POST['desc']) and !isset ($_POST['json_str'])) {
            // en la lista de calendarios han pinchado en el boton de "nuevo calendario" 
            $desc = '';
            $json = '{"remotepc_calendar":{"timezone":"' . $tz . '","ruleset":[{"remote":false,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"from_hr":"8","to_hr":"17"}]}}';   // hagamos que los calendarios nuevos por defecto ya tengan una regla lun-vie 8-17
            $ret = 1;

        } else {
            // en los detalles del calendario han pinchado en "crear"
            $desc = $_POST['desc'];
            $json = $_POST['json_str'];
            $errors = process_post ($cal_id, $desc, $json);
            if (sizeof ($errors)) {
                $error_str = implode (',', $errors);
                //printf ('after process_post(), error_str (%s)', $error_str);
            } else { 
                $ret = 1;
            }
        }

    } else {
        // puede ser GET o POST

        if ($is_get) {  // si GET: ver calendario
            list ($desc, $json) = fetch_cal_from_db ($cal_id);
            $ret = 1;

        } else {        // si POST: modificar calendario
            $desc = $_POST['desc'];
            $json = $_POST['json_str'];
            $errors = process_post ($cal_id, $desc, $json);
            if (sizeof ($errors)) {
                $error_str = implode (',', $errors);
            } else {
                $ret = 1;
            }
        }
    }
    return array ($ret, $cal_id, $desc, $json);
}

list ($ok, $cal_id, $desc, $json) = parse_params();
?>

<html>
<head>
<title>Administración web de calendarios</title>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<link rel="shortcut icon" href="images/iconos/logocirculos.png" type="image/png" />
<link rel="stylesheet" type="text/css" href="estilos.css" />
<script language="javascript">

// recibimos las globales del php
var tz = "<?= $tz ?>";
var cal_id = <?= $cal_id ?>;
var jsdesc = "<?= $desc ?>";   // if js vars have the same name as html elems, then things like document.forms[0].desc.value return "[object htmlinputelement]" rather than the actual value. Hence, "jsdesc".
var cal = <?= $json ?>;        // este json en php es un string, pero al ponerlo sin comillas aqui se transforma en un objeto automagicamente :)

// copypaste from elsewhere to handle the calendar popup
function vertabla_calendario(ofecha) {
    currentFecha=ofecha;
    url="../varios/calendario_ventana.php?fecha="+ofecha.value;
    window.open(url,"vf","top=160,left=250,height=220,width=150,scrollbars=no")
}

function anade_fecha(fecha){
    currentFecha.value=fecha
}
// end of copypaste


// https://stackoverflow.com/questions/15141762/how-to-initialize-a-javascript-date-to-a-particular-time-zone
function dateWithTimeZone (timeZone, year, month, day, hour, minute, second) {
    let date = new Date (Date.UTC (year, month-1, day, hour, minute, second));

    let utcDate = new Date (date.toLocaleString ('en-US', { timeZone: "UTC"    }));
    let tzDate  = new Date (date.toLocaleString ('en-US', { timeZone: timeZone }));
    let offset = utcDate.getTime() - tzDate.getTime();

    date.setTime (date.getTime() + offset);

    return date;
};

days_of_week = [
    ['mon', 'Lun'],
    ['tue', 'Mar'],
    ['wed', 'Mié'],
    ['thu', 'Jue'],
    ['fri', 'Vie'],
    ['sat', 'Sáb'],
    ['sun', 'Dom']
];

function json2tbl() {
    new_tbl = document.createElement ('table');

    // desc
    tr = document.createElement ('tr');
    tr.innerHTML = '<td>Descripción</td><td><input type="text" name="desc" value="' + jsdesc + '" onblur="jsdesc=document.forms[0].desc.value;"/></td>';
    new_tbl.appendChild (tr);

    rule_no = -1;

    // para cada regla en el ruleset, añadir un tr
    for (idx in cal.remotepc_calendar.ruleset) {
        rule_no++;
        rule_id = 'rule' + rule_no;
        rule = cal.remotepc_calendar.ruleset[idx];
        if (!rule.remote) {
            tr = document.createElement ('tr');

            // un td con los radio "presencial" (checked) y "remoto", y el boton de borrar
            td = document.createElement ('td');
            td.innerHTML = '<input type="radio" name="' + rule_id + '" value="onsite" checked="checked" onclick=\'set_rule_onsite("' + rule_no + '");\' /> Período presencial<br>';
            td.innerHTML += '<input type="radio" name="' + rule_id + '" value="except" onclick=\'set_rule_exception("' + rule_no + '");\' /> Excepción<br>';
            td.innerHTML += '<input type="button" name="' + rule_id + '_delete" value="Borrar regla" onclick=\'del_rule("' + rule_no + '");\' />';
            tr.appendChild (td);

            html = '';
            // y otro td con los dias...
            days_of_week.forEach (dow => {
                if (rule[dow[0]] != undefined) {
                    html += '<input type="checkbox" name="' + rule_id + '_' + dow[0] + '" checked />' + dow[1] + ' ';
                } else {
                    html += '<input type="checkbox" name="' + rule_id + '_' + dow[0] + '" />' + dow[1] + ' ';
                }
            });

            // ...la hora inicio...
            html += 'de <select name="' + rule_id + '_from_hr">';
            for (var h = 0; h <= 23; h++) {
                if (h == rule.from_hr) {
                    html += '<option value="' + h + '" selected>' + h + ':00</option>';
                } else {
                    html += '<option value="' + h + '"         >' + h + ':00</option>';
                }
            }
            html += '</select>';

            // ...y la hora fin
            html += 'a <select  name="' + rule_id + '_to_hr">';
            for (var h = 0; h <= 23; h++) {
                if (h == rule.to_hr) {
                    html += '<option value="' + h + '" selected>' + h + ':59</option>';
                } else {
                    html += '<option value="' + h + '"         >' + h + ':59</option>';
                }
            }
            html += '</select>';

            td = document.createElement ('td');
            td.innerHTML = html;
            tr.appendChild (td);

            new_tbl.appendChild (tr);

        } else {
            tr = document.createElement ('tr');

            // un td con los radio "presencial" y "remoto" (checked), y el boton de borrar
            td = document.createElement ('td');
            td.innerHTML = '<input type="radio" name="' + rule_id + '" value="onsite" onclick=\'set_rule_onsite("' + rule_no + '");\' /> Período presencial<br>';
            td.innerHTML += '<input type="radio" name="' + rule_id + '" value="except" checked="checked" onclick=\'set_rule_exception("' + rule_no + '");\' /> Excepción<br>';
            td.innerHTML += '<input type="button" name="' + rule_id + '_delete" value="Borrar regla" onclick=\'del_rule("' + rule_no + '");\' />';
            tr.appendChild (td);

            html = '';
            // y otro td con reason,from,to
            html += 'Motivo: <input type="text" name="' + rule_id + '_reason" value="' + rule.reason + '" /> ';
            from_ts = new Intl.DateTimeFormat ('es-ES', { year: 'numeric', month: 'numeric', day: 'numeric', timeZone: tz }).format (new Date (1000 * rule.from_ts));
            to_ts   = new Intl.DateTimeFormat ('es-ES', { year: 'numeric', month: 'numeric', day: 'numeric', timeZone: tz }).format (new Date (1000 * rule.to_ts  ));
            html += 'de <input onclick="vertabla_calendario(this)" name="' + rule_id + '_from_ts" value="' + from_ts + '" /> ';
            html += 'a <input  onclick="vertabla_calendario(this)" name="' + rule_id + '_to_ts"   value="' + to_ts   + '" />';
            td = document.createElement ('td');
            td.innerHTML = html;
            tr.appendChild (td);

            new_tbl.appendChild (tr);

        }
    }
    
    // boton Añadir regla
    tr = document.createElement ('tr');
    tr.innerHTML = '<tr><td colspan="2"><input type="submit" value="Añadir regla" onclick=\'add_rule(); return false;\' /></td></tr>';
    new_tbl.appendChild (tr);
    
    // boton Crear/Modificar calendario
    tr = document.createElement ('tr');
    btn_lbl = -1 == cal_id ? 'Crear' : 'Modificar';
    tr.innerHTML = '<tr><td colspan="2"><input type="submit" value="' + btn_lbl + ' calendario" onclick=\'tbl2json(); document.forms[0].json_str.value = JSON.stringify(cal); document.forms[0].action="./calendars-modify.php";\' /></td></tr>';
    new_tbl.appendChild (tr);

    return new_tbl;
}

function replace_tbl() {
    old_tbl = document.getElementById ('tbl');
    parentElement = old_tbl.parentElement;

    try {
        new_tbl = json2tbl();
        new_tbl.id = 'tbl';
        new_tbl.border = 1;
        parentElement.replaceChild (new_tbl, old_tbl);
    } catch (error) {
        console.error ("Error parsing JSON:", error);
    }
}

function tbl2json() {
    f = new FormData (document.forms[0]);
    re = /^rule(\d+)(_(.*))?$/;
    ruleset = [];
    for (let [key, val] of f.entries()) {
        if ('cal_id' == key) { cal_id = val; continue; }
        if ('desc'   == key) { jsdesc = val; continue; }
        m = re.exec (key);
        if (m === null) { continue; } // no match

        rule = m[1];
        k = m[3];
        if (k === undefined) {
            // rule0, rule1...
            if      ('onsite' == val) { ruleset[rule] = { 'remote': false }; }
            else if ('except' == val) { ruleset[rule] = { 'remote': true  }; }
            continue;
        }

        // rule0_whatever, rule1_whatever...
        if (['mon','tue','wed','thu','fri','sat','sun'].indexOf (k) >= 0) { val = true; }    // val is "on", turn it into boolean
        if ('from_ts' == k) {
            m = /^(\d+)\/(\d+)\/(\d+)$/.exec (val);
            if (m != null) {
                day = m[1];
                month = m[2];
                year = m[3];
                val = dateWithTimeZone (tz, year, month, day, 0, 0, 0).getTime() / 1000;
            }
        }
        if ('to_ts' == k) {
            m = /^(\d+)\/(\d+)\/(\d+)$/.exec (val);
            if (m != null) {
                day = m[1];
                month = m[2];
                year = m[3];
                val = dateWithTimeZone (tz, year, month, day, 23, 59, 59).getTime() / 1000;
            }
        }
        ruleset[rule][k] = val;
    }

    cal = { 'remotepc_calendar': { 'timezone': tz, ruleset: ruleset } };
}

function set_rule_onsite (idx) {
    rule_no = parseInt(idx);
    rule_id = 'rule' + rule_no;
    tbl = document.getElementById ('tbl');
    tr = tbl.rows[rule_no+1];

    // comprobar si ya está checked, entonces no hacer nada
    if (!cal.remotepc_calendar.ruleset[idx].remote) { return; }

    td = tr.cells[1];
    td.innerHTML = ' \
        <input type="checkbox" name="' + rule_id + '_mon" />Lun <input type="checkbox" name="' + rule_id + '_tue" />Mar <input type="checkbox" name="' + rule_id + '_wed" />Mié <input type="checkbox" name="' + rule_id + '_thu" />Jue <input type="checkbox" name="' + rule_id + '_fri" />Vie <input type="checkbox" name="' + rule_id + '_sat" />Sáb <input type="checkbox" name="' + rule_id + '_sun" />Dom, \
        de <select name="' + rule_id + '_from_hr"><option value="0">0:00</option> <option value="1">1:00</option> <option value="2">2:00</option> <option value="3">3:00</option> <option value="4">4:00</option> <option value="5">5:00</option> <option value="6">6:00</option> <option value="7">7:00</option> <option value="8" selected>8:00</option> <option value="9">9:00</option> <option value="10">10:00</option> <option value="11">11:00</option> <option value="12">12:00</option> <option value="13">13:00</option> <option value="14">14:00</option> <option value="15">15:00</option> <option value="16">16:00</option> <option value="17"         >17:00</option> <option value="18">18:00</option> <option value="19">19:00</option> <option value="20">20:00</option> <option value="21">21:00</option> <option value="22">22:00</option> <option value="23">23:00</option> </select> \
        a <select  name="' + rule_id + '_to_hr"  ><option value="0">0:59</option> <option value="1">1:59</option> <option value="2">2:59</option> <option value="3">3:59</option> <option value="4">4:59</option> <option value="5">5:59</option> <option value="6">6:59</option> <option value="7">7:59</option> <option value="8"         >8:59</option> <option value="9">9:59</option> <option value="10">10:59</option> <option value="11">11:59</option> <option value="12">12:59</option> <option value="13">13:59</option> <option value="14">14:59</option> <option value="15">15:59</option> <option value="16">16:59</option> <option value="17" selected>17:59</option> <option value="18">18:59</option> <option value="19">19:59</option> <option value="20">20:59</option> <option value="21">21:59</option> <option value="22">22:59</option> <option value="23">23:59</option> </select> \
    ';

    tbl2json();
}

function set_rule_exception (idx) {
    rule_no = parseInt(idx);
    rule_id = 'rule' + rule_no;
    tbl = document.getElementById ('tbl');
    tr = tbl.rows[rule_no+1];

    // comprobar si ya está checked, entonces no hacer nada
    if (cal.remotepc_calendar.ruleset[idx].remote) { return; }

    td = tr.cells[1];
    td.innerHTML = ' \
        Motivo: <input type="text" name="' + rule_id + '_reason" /> \
        de <input onclick="vertabla_calendario(this)" name="' + rule_id + '_from_ts" /> \
        a <input  onclick="vertabla_calendario(this)" name="' + rule_id + '_to_ts" /> \
    ';

    tbl2json();
}

function add_rule() {
    cal.remotepc_calendar.ruleset.push ({});

    replace_tbl();
}

function del_rule (idx) {
    tbl2json();
    cal.remotepc_calendar.ruleset.splice (idx, 1);
    replace_tbl();
}

document.addEventListener("DOMContentLoaded", function(){
    replace_tbl();
});
</script>


</head>

<body>
    <?php if ($error_str) { printf ('<p>Error: (%s)</p>', $error_str); } ?>
    <form method="post">
        <input type="hidden" name="cal_id" value="<?= $cal_id ?>" />
        <input type="hidden" name="json_str" value="" />
        <p><table id="tbl"></table></p>
    </form>
</body>
</html>
