import { observable } from "mobx";
import { EventEmitter, EventHandler } from "./EventEmitter";
import { GridType } from "../types";

export enum CellEvent {
    ValueChanged,
    TypeChanged,
    EditStart,
    EditEnd
}

export class GridCellModel extends EventEmitter<CellEvent> {
    @observable
    editing : boolean;

    @observable
    value : any;

    @observable
    temp : any;

    @observable
    type : GridType;

    private column : string;

    constructor(value : any, column : string, eventHandler? : EventHandler<CellEvent>) {
        super();

        this.column = column;
        this.editing = false;

        if (typeof value === "object" && !!value) {
            this.type = value.type;
            this.value = value.value;
        }
        else {
            this.value = value;
            this.type = null;
        }

        this.temp = this.value;

        if (eventHandler) {
            this.addEventHandler(eventHandler);
        }
    }

    getColumn() {
        return this.column;
    }

    setValue(value : any, noEvent? : boolean) {
        this.value = value;
        this.temp = value;

        if (noEvent) {
            return;
        }

        this.triggerEvent(CellEvent.ValueChanged, {
            value: value
        });
    }

    setEditing(editing : boolean, noEvent? : boolean) {
        if (this.editing === editing) {
            return;
        }

        this.editing = editing;

        if (noEvent) {
            return;
        }

        if (editing) {
            this.triggerEvent(CellEvent.EditStart, {});
        }
        else {
            this.triggerEvent(CellEvent.EditEnd, {});
        }
    }

    setType(type : GridType, noEvent? : boolean) {

        if (typeof type === "string") {
            this.type = {
                kind: type
            };
        }
        else {
            this.type = type;
        }

        if (noEvent) {
            return;
        }

        this.triggerEvent(CellEvent.TypeChanged, {
            type: type
        });
    }

    onEvent(event : CellEvent, ...args : any[]) {

        switch (event) {
            case CellEvent.TypeChanged:
                this.setType(args[1], true);
                break;
            case CellEvent.ValueChanged:
                this.setValue(args[1], true);
                break;
        }
    }
}
