/src/celleditor.ts
import { Cell } from './cell';
import { GameEvent, GameEventType } from './event';
import FragmentManager from './fragmentmanager';

export type CellEditorCallback = (cell: Cell) => void;

export default class CellEditor {
    container: FragmentManager
    titleRef: HTMLInputElement
    descriptionRef: HTMLTextAreaElement
    events: FragmentManager[]
    cell: Cell

    onClose: (cell: Cell) => void

    constructor() {
        this.container = new FragmentManager(`
          <div class="box hflex">
            <div class="vflex flex-auto">
              <h1>Cell Editor</h1>
              <h2>Title</h2>
              <input name="title">
              <h2>Description</h2>
              <textarea name="description" class="flex-auto"></textarea>
              <h2>Exits</h2>
              <div class="hflex">
                <label><input type="checkbox" name="exit-n">North</label>
                <label><input type="checkbox" name="exit-e">East</label>
                <label><input type="checkbox" name="exit-s">South</label>
                <label><input type="checkbox" name="exit-w">West</label>
              </div>
              <div class="hflex">
                <button id="cell-editor-close">Close</button>
              </div>
            </div>
            <div class="events">
              <h2>Events</h2>
              <div id="event-list"></div>
              <button id="add-event">Add Event</button>
            </div>
          </div>
        `);
        this.container.mountInto('cell-editor-container');

        this.container.elem.addEventListener('keydown', function(e: KeyboardEvent) {
            e.cancelBubble = true;
        });

        this.titleRef = <HTMLInputElement>this.container.q('[name=title]');
        this.descriptionRef = <HTMLTextAreaElement>this.container.q('[name=description]');

        const addEventButton = this.container.q('#add-event');
        addEventButton.addEventListener('click', this.addEventHandler.bind(this));
        this.events = []

        const closeButton = this.container.q('#cell-editor-close');
        closeButton.addEventListener('click', this.closeHandler.bind(this));
    }

    open(cell: Cell) {
        this.cell = cell;
        this.titleRef.value = cell.title;
        this.descriptionRef.value = cell.description;

        ['n', 'e', 's', 'w'].forEach( (dir, index) => {
            const checkbox = <HTMLInputElement>this.container.q(`input[name="exit-${dir}"]`);
            checkbox.checked = cell.exits[index];
        });

        for (let [k, e] of cell.events) {
            this.addEvent(e);
        }
        this.container.elem.classList.add('visible');
        this.titleRef.focus();
    }

    addEventHandler() {
        this.addEvent();
    }

    addEvent(event?: GameEvent) {
        const eventForm = new FragmentManager(`
            <h3>ID</h3>
            <input name="id">
            <h3>Type</h3>
            <select name="type">
                <option value="0">Enter</option>
                <option value="1">Leave</option>
                <option value="2">Random</option>
                <option value="3">Action</option>
            </select>
            <h3>Title</h3>
            <input name="title">
            <h3>Script</h3>
            <textarea name="script"></textarea>
            <div>
                <button name="delete">Delete Event</button>
            </div>
        `, 'div', { className: 'vflex' });
        eventForm.mount('event-list');
        this.events.push(eventForm);

        const deleteButton = eventForm.q('[name=delete]');
        deleteButton.addEventListener('click', () => {
            eventForm.unmount();
            const i = this.events.indexOf(eventForm);
            this.events.splice(i, 1);
        });

        if (!event) {
            event = new GameEvent();
        }
        (<HTMLInputElement>eventForm.q('[name=id]'))
            .value = event.id;
        (<HTMLSelectElement>eventForm.q('[name=type]'))
            .value = event.type.toString();
        (<HTMLInputElement>eventForm.q('[name=title]'))
            .value = event.title;
        (<HTMLTextAreaElement>eventForm.q('[name=script]'))
            .value = event.script;
    }

    close() {
        this.closeHandler();
    }

    closeHandler() {
        this.cell.title = this.titleRef.value;
        this.cell.description = this.descriptionRef.value;

        ['n', 'e', 's', 'w'].forEach( (dir, index) => {
            const checkbox = <HTMLInputElement>this.container.q(`input[name="exit-${dir}"]`);
            this.cell.exits[index] = checkbox.checked;
        });

        // We recreate all of the cell's events to make sure we remove any deleted ones
        this.cell.events.clear();
        for (let eventForm of this.events) {
            const id = (<HTMLInputElement>eventForm.q('[name=id]')).value;
            const type = <GameEventType>parseInt((<HTMLInputElement>eventForm.q('[name=type]')).value);
            const title = (<HTMLInputElement>eventForm.q('[name=title]')).value;
            const script = (<HTMLInputElement>eventForm.q('[name=script]')).value;

            const e = new GameEvent();

            e.id = id;
            e.type = type;
            e.title = title;
            e.script = script;

            this.cell.events.set(id, e);
        }

        for (let ev of this.events)
            ev.unmount();
        this.events = [];

        if (this.onClose) {
            this.onClose(this.cell);
            this.onClose = null;
        }
        this.container.elem.classList.remove('visible');
    }
}