import { observable } from "mobx";
import { Column, SelectOption, GridType, Menu } from "../types";
import { EventEmitter, EventHandler } from "./EventEmitter";

export enum ColumnEvent {
    DescriptionChanged,
    TitleChanged,
    ReadOnlyChanged,
    TypeChanged,
    VisibleChanged
}

export class GridColumnModel extends EventEmitter<ColumnEvent> {

    property : string;

    @observable
    description : string;

    @observable
    title : string;

    @observable
    readOnly : boolean;

    @observable
    type : GridType;

    @observable
    visible : boolean;

    @observable
    order : number;

    // @observable
    selected : boolean;

    customMenus : Menu[];

    contextId : string;

    constructor(col : Column, order : number, eventHandler? : EventHandler<ColumnEvent>) {
        super();

        this.customMenus = col.menu;
        this.readOnly = col.ReadOnly;
        this.title = col.Title;
        this.visible = col.Visible;
        this.description = col.Description;
        this.property = col.Property;
        this.order = order;
        this.selected = false;

        this.contextId = "col-context-menu-" + this.property;

        this.type = typeof col.Type === "string"
            ? { kind: col.Type }
            : col.Type;

        if (eventHandler) {
            this.addEventHandler(eventHandler);
        }
    }

    private onPropertyChaged(property : string, value : any) {
        if (property === "type" && typeof value === "string") {
            this.type.kind = value;
            return;
        }

        this[property] = value;
    }

    onEvent(event : ColumnEvent, ...args : any[]) {

        switch (event) {
            case ColumnEvent.DescriptionChanged:
                this.description = args[0];
                break;
            case ColumnEvent.TitleChanged:
                this.title = args[0];
                break;
            case ColumnEvent.ReadOnlyChanged:
                this.readOnly = args[0];
                break;
            case ColumnEvent.TypeChanged:
                if (args && args.length > 0 && typeof args[1] === "string") {
                    this.type.kind = args[1];
                }
                break;
            case ColumnEvent.VisibleChanged:
                this.visible = args[0];
                break;
            default:
                break;
        }
    }

    setSelected(selected : boolean) {
        this.selected = selected;
    }

    setTitle(title : string, noEvent? : boolean) {
        this.title = title;

        if (noEvent) {
            return;
        }

        this.triggerEvent(ColumnEvent.TitleChanged, {
            title: title
        });
    }

    setDescription(description : string, noEvent? : boolean) {
        this.description = description;

        if (noEvent) {
            return;
        }

        this.triggerEvent(ColumnEvent.DescriptionChanged, {
            description: description
        });
    }

    setReadOnly(readOnly : boolean, noEvent? : boolean) {
        this.readOnly = readOnly;

        if (noEvent) {
            return;
        }

        this.triggerEvent(ColumnEvent.ReadOnlyChanged, {
            readOnly: readOnly
        });
    }

    setType(type : GridType, noEvent? : boolean) {
        this.type = type;

        if (noEvent) {
            return;
        }

        this.triggerEvent(ColumnEvent.TypeChanged, {
            type: type
        });
    }

    setVisible(visible : boolean, noEvent? : boolean) {
        this.visible = visible;

        if (noEvent) {
            return;
        }

        this.triggerEvent(ColumnEvent.VisibleChanged, {
            visible: visible
        });
    }

    getDescriptor() : SelectOption {
        return {
            value: this.property,
            description: this.description
        };
    }
}
