class Workout {

// ----------
constructor(cont, plan) {
    const wo_cont = document.createElement("div");
    wo_cont.classList.add("workout-wrapper");
    cont.appendChild(wo_cont);

    // Inputs to the class. Workout plan and container to display it in
    this.container = wo_cont;
    this.plan = plan;

    // Status tracking information
    this.action = "";
    this.set_idx = 0;
    this.set_repeat_idx = 0;
    this.exercise_idx = 0;
    this.workout_done = 0;

    // // Enable debug
    // this.show_debug_status = 1;
}

// ----------
text_element(typ, txt) {
    const el = document.createElement(typ);
    el.textContent = txt;

    return el;
}

// ----------
progress_indicator(id) {
    const indicator = this.text_element("div", " ");
    indicator.setAttribute("id", id);
    indicator.classList.add("progress-indicator");
    indicator.classList.add("pending");
    return indicator;
}

// ----------
render_workout_header() {
    const hdr = this.text_element("h1", this.plan.name);
    const wo_indicator = this.progress_indicator("wo-indicator");
    hdr.appendChild(wo_indicator);
    this.container.appendChild(hdr);
}

// ----------
render_debug_status() {
    const dbg_div = document.createElement("div");
    dbg_div.classList.add("app_debug");

    const dt = document.createElement("p");
    dt.setAttribute("id", "app_debug_div");
    dbg_div.appendChild(dt);
    this.container.appendChild(dbg_div);
}

// ----------
update_debug_info() {
    if (this.show_debug_status) {
        const dt = this.container.querySelector("#app_debug_div");
        const curr_set_repeat_max_idx = this.plan.set[this.set_idx].count-1;
        const done_str = (this.workout_done === 1) ? "Done " : "";
        dt.textContent = `${done_str}Action: ${this.action} Current: Set-${this.set_idx} [${this.set_repeat_idx}/${curr_set_repeat_max_idx}]/Exercise-${this.exercise_idx}`;
    }
}

// ----------
render_exercise(prnt, el, idx) {
    const tblr = document.createElement("tr");
    tblr.setAttribute("class", `exercise-row exercise-idx-${idx} exercise-pending`);

    const sts_td = document.createElement("td");
    const sts_cb = document.createElement("input");
    sts_cb.setAttribute("type", "checkbox");
    sts_td.appendChild(sts_cb);
    sts_cb.setAttribute("disabled", true);

    // Status
    let col = sts_td;
    col.classList.add("col-status");
    tblr.appendChild(col);
    el.done = 0;

    // Name
    col = this.text_element("td", el.name);
    col.classList.add("col-name");
    tblr.appendChild(col);

    // Pattern/count
    col = this.text_element("td", `${el.pattern} x ${el.count}`);
    col.classList.add("col-pattern-count");
    tblr.appendChild(col);

    prnt.appendChild(tblr);
}

// ----------
render_set(el, idx) {
    const wo = this;

    // Table with one set
    const tbl = document.createElement("table");
    tbl.setAttribute("class", `set-table set-table-idx-${idx}`);

    const tcap = this.text_element("caption", el.name);
    for (var i = 0; i < el.count; i++) {
        const set_indicator = this.progress_indicator(`set-${idx}-${i}-indicator`);
        tcap.appendChild(set_indicator);
    }
    tbl.appendChild(tcap);

    let show_header = 0;
    if (show_header) {
        // Header of the table
        const tblh = document.createElement("thead");
        const tblhr = document.createElement("tr");

        let col = this.text_element("th", "Status");
        col.classList.add("col-status");
        tblhr.appendChild(col);
        col = this.text_element("th", "Exercise");
        col.classList.add("col-name");
        tblhr.appendChild(col);
        col = this.text_element("th", "Pattern/Count");
        col.classList.add("col-pattern-count");
        tblhr.appendChild(col);

        tblh.appendChild(tblhr);
        tbl.appendChild(tblh);
    }

    // Content of table - exercises in the set
    const tblb = document.createElement("tbody");

    el.exercise.forEach(function(ex_el,idx) {
        wo.render_exercise(tblb, ex_el, idx);
    });
    tbl.appendChild(tblb);

    this.container.appendChild(tbl);
}

// ----------
render_workout() {
    const wo = this;
    this.render_workout_header();
    if (this.show_debug_status) {
        this.render_debug_status();
    }
    this.plan.set.forEach(function(el,idx) {
        wo.render_set(el, idx);
    });
    this.render_fab();

    this.update_debug_info();
}

// ----------
update_active_item() {
    let wo = this;
    // Make current active exercise row inactive
    const curr_active_tr = this.container.querySelector(".exercise-row.active");
    let wo_set_idx = this.set_idx;
    let wo_exercise_idx = this.exercise_idx;
    let wo_set_repeat_idx = this.set_repeat_idx;

    const max_set_idx = this.plan.set.length-1;
    const max_set_repeat_idx = this.plan.set[max_set_idx].count-1;
    const max_exercise_idx = this.plan.set[max_set_idx].exercise.length-1;

    if (curr_active_tr != null) {
        curr_active_tr.classList.remove("active");
    }

    // Set active exercise row
    let qstr = `table.set-table-idx-${wo_set_idx} tr.exercise-idx-${wo_exercise_idx}`;
    console.log(`update_active_item - Looking for ${qstr}`);
    const next_active_tr = this.container.querySelector(qstr);
    if (next_active_tr != null) {
        next_active_tr.classList.add("active");
    }

    // Set set repeat indicators
    let set_tables = this.container.querySelectorAll(".set-table");
    set_tables.forEach(function(stbl, tidx) {
        let indicators = stbl.querySelectorAll(".progress-indicator");
        indicators.forEach(function(ids, iidx) {
            let ind_selector = `#set-${tidx}-${iidx}-indicator`;
            console.log(`update_active_item - Ind: ${ind_selector} for set_idx ${wo_set_idx} repeat_idx ${wo_set_repeat_idx}`);

            // if (stbl.querySelector(ind_selector) == null) return;

            console.log(`update_active_item - Ind: tidx ${tidx} is ?? set_idx ${wo_set_idx}`);
            if (tidx < wo_set_idx) {
                stbl.querySelector(ind_selector).classList.remove("pending");
                stbl.querySelector(ind_selector).classList.remove("active");
                stbl.querySelector(ind_selector).classList.add("done");
            }
            else if (tidx > wo_set_idx) {
                stbl.querySelector(ind_selector).classList.remove("done");
                stbl.querySelector(ind_selector).classList.remove("active");
                stbl.querySelector(ind_selector).classList.add("pending");
            }
            else if (tidx == wo_set_idx) {
                const ex_chkbox = stbl.querySelector(`tr.exercise-idx-${wo_exercise_idx} input`);
                if ((iidx < wo_set_repeat_idx)
                    // || ((iidx == wo_set_repeat_idx) && ex_chkbox.checked)
                    || ((iidx == wo_set_repeat_idx) && wo.plan.set[tidx].exercise[wo_exercise_idx].done)
                    ){
                    console.log(`update_active_item - Ind: iidx ${iidx} is < repeat_idx ${wo_set_repeat_idx} DONE`);
                    stbl.querySelector(ind_selector).classList.remove("pending");
                    stbl.querySelector(ind_selector).classList.remove("active");
                    stbl.querySelector(ind_selector).classList.add("done");
                }
                else if (iidx > wo_set_repeat_idx) {
                    console.log(`update_active_item - Ind: iidx ${iidx} is > repeat_idx ${wo_set_repeat_idx} PENDING`);
                    stbl.querySelector(ind_selector).classList.remove("done");
                    stbl.querySelector(ind_selector).classList.remove("active");
                    stbl.querySelector(ind_selector).classList.add("pending");
                } else {
                    console.log(`update_active_item - Ind: iidx ${iidx} is = repeat_idx ${wo_set_repeat_idx} ACTIVE`);
                    stbl.querySelector(ind_selector).classList.remove("pending");
                    stbl.querySelector(ind_selector).classList.remove("done");
                    stbl.querySelector(ind_selector).classList.add("active");
                }
            }
        });
    });

    this.plan.set.forEach(function(el,idx) {
        let sidx = idx;
        el.exercise.forEach(function(eel, eidx) {
            let qstr = `table.set-table-idx-${sidx} tr.exercise-idx-${eidx}`;
            const active_tr = wo.container.querySelector(qstr);
            active_tr.classList.remove("exercise-pending");

            qstr = `table.set-table-idx-${sidx} tr.exercise-idx-${eidx} input`;
            const active_chkbox = wo.container.querySelector(qstr);
            active_chkbox.disabled = true;
            active_chkbox.checked = (wo.plan.set[sidx].exercise[eidx].done == 1);
        });
    });

    // Mark workout done
    if (this.workout_done == 1) {
        const wo_indicator = this.container.querySelector("#wo-indicator");
        wo_indicator.classList.remove("pending");
        wo_indicator.classList.add("done");
    }
}

// ----------
handle_exercise_advance() {
    const curr_exercise_max_idx = this.plan.set[this.set_idx].exercise.length-1;
    const curr_set_repeat_max_idx = this.plan.set[this.set_idx].count-1;
    const curr_set_max_idx = this.plan.set.length-1;

    console.log(`handle_exercise_advance - Workout done ${this.workout_done} curr_exercise_max_idx = ${curr_exercise_max_idx} curr_set_max_idx = ${curr_set_max_idx}`);

    this.handle_exercise_done();

    if (this.exercise_idx === curr_exercise_max_idx) {
        if (this.set_repeat_idx == curr_set_repeat_max_idx) {
            if (this.set_idx === curr_set_max_idx) {
                if (this.workout_done === 1) {
                    console.log("handle_exercise_advance - Exercise done");
                }
            } else {
                this.set_idx += 1;
                this.set_repeat_idx = 0;
                this.exercise_idx = 0;
                this.handle_set_undone();
            }
        } else {
            this.set_repeat_idx += 1;
            this.exercise_idx = 0;
            this.handle_set_undone();
        }
    } else {
        this.exercise_idx += 1;
    }
}

// ----------
handle_exercise_regress() {
    const curr_set_max_idx = this.plan.set.length-1;
    const curr_set_repeat_max_idx = this.plan.set[this.set_idx].count-1;

    if (this.exercise_idx === 0) {
        if (this.set_repeat_idx === 0) {
            if (this.set_idx === 0) {
                console.log("handle_exercise_regress - Exercise start");
            } else {
                this.set_idx -= 1;
                this.set_repeat_idx = this.plan.set[this.set_idx].count-1;
                this.exercise_idx = this.plan.set[this.set_idx].exercise.length-1;
                this.handle_set_done();
            }
        } else {
            this.set_repeat_idx -= 1;
            this.exercise_idx = this.plan.set[this.set_idx].exercise.length-1;
            this.handle_set_done();
        }
    } else {
        this.exercise_idx -= 1;
    }

    this.handle_exercise_undone();
}

// ----------
handle_exercise_done() {
    if (this.plan.set[this.set_idx].exercise[this.exercise_idx].done == 0) {
        this.plan.set[this.set_idx].exercise[this.exercise_idx].done = 1;
    }

    console.log(this.plan.set[this.set_idx]);

    this.handle_workout_done();
}

// ----------
handle_exercise_undone() {
    if (this.plan.set[this.set_idx].exercise[this.exercise_idx].done == 1) {
        this.plan.set[this.set_idx].exercise[this.exercise_idx].done = 0;
    }
}

// ----------
handle_set_done() {
    // Set active exercise row
    let qstr = `table.set-table-idx-${this.set_idx} tr input`;
    console.log(`handle_set_done - Looking for ${qstr}`);

    this.plan.set[this.set_idx].exercise.forEach(function(ex, idx) {
        ex.done = 1;
    });
}

// ----------
handle_set_undone() {
    // Set active exercise row
    let qstr = `table.set-table-idx-${this.set_idx} tr input`;
    console.log(`handle_set_undone - Looking for ${qstr}`);

    this.plan.set[this.set_idx].exercise.forEach(function(ex, idx) {
        ex.done = 0;
    });
}

// ----------
handle_workout_done() {
    let wo = this;

    const max_set_idx = this.plan.set.length-1;
    const max_set_repeat_idx = this.plan.set[max_set_idx].count-1;
    const max_exercise_idx = this.plan.set[max_set_idx].exercise.length-1;

    if ((this.set_idx ===  max_set_idx)
        && (this.set_repeat_idx ===  max_set_repeat_idx)
        && (this.exercise_idx === max_exercise_idx)
        && (this.plan.set[this.set_idx].exercise[this.exercise_idx].done == 1)) {
        this.workout_done = 1;
    }

    console.log(`handle_workout_done - ${this.workout_done}`);
    console.log(`   compare: ${this.set_idx} === ${max_set_idx}`);
    console.log(`   compare: ${this.set_repeat_idx} === ${max_set_idx}`);
    console.log(`   compare: ${this.exercise_idx} === ${max_exercise_idx}`);
}

// ----------
handle_action(act) {
    if (this.workout_done) {
        return;
    }

    this.action = act;
    if ((act == "Button-Advance") || (act == "Key-n")) {
        this.handle_exercise_advance();
    } else if ((act == "Button-Regress") || (act == "Key-N")) {
        this.handle_exercise_regress();
    } else {
        this.action = `Unsupported action - ${act}`;
    }

    this.update_debug_info();
    this.update_active_item();
}

// ----------
render_fab() {
    const fab_wrapper = document.createElement("div");
    fab_wrapper.setAttribute("id", "fab-wrapper");

    const fab_regress = this.text_element("button", "<< Regress");
    fab_regress.classList.add("fab-button");
    fab_regress.setAttribute("id", "fab-regress");
    const fab_advance = this.text_element("button", "Advance >>");
    fab_advance.classList.add("fab-button");
    fab_advance.setAttribute("id", "fab-advance");

    fab_wrapper.appendChild(fab_regress);
    fab_wrapper.appendChild(fab_advance);

    this.container.appendChild(fab_wrapper);
}

// ----------
render() {
    const app = this;
    this.render_workout();
    this.update_active_item();

    document.addEventListener('keydown', function(ev) {
        app.handle_action(`Key-${ev.key}`);
    });

    const fab_advance = this.container.querySelector("#fab-advance");
    fab_advance.addEventListener('click', function() {
        app.handle_action('Button-Advance');
    });
    const fab_regress = this.container.querySelector("#fab-regress");
    fab_regress.addEventListener('click', function() {
        app.handle_action('Button-Regress');
    });
}

}