import { DOM } from './dom';
import { View, ViewController } from '../view/exported';
import { IElement } from '../interface/exported';
import { DebounceBehavior, ThrottleBehavior, SignalBehavior, TriggerBehavior } from '../behavior/exported';
// built in attributes
import {
    IfAttribute,
    ValueAttribute,
    DelgateEventsAttribute,
    TriggerEventsAttribute,
    RepeatAttribute,
    MiscAttributes,
    CssAttribute,
    ModelAttribute
} from '../attribute/exported';
import { createBindingContext } from '../binding/exported';



/**
 * Main framework class, this is returned in the configure function
 *
 */
export class MF {

    private node: Node;
    private app: IElement;
    public count = 0;
    private $view: ViewController;


    constructor() {

        // polyfill IE11
        if (!(DOM.window as any).Reflect) {
            (DOM.window as any).Reflect = Object;
        }

        // register built in attributes/elements
        this.register(
            ValueAttribute,
            IfAttribute,
            DelgateEventsAttribute,
            RepeatAttribute,
            MiscAttributes,
            CssAttribute,
            ModelAttribute,
            TriggerEventsAttribute,
            SignalBehavior,
            ThrottleBehavior,
            DebounceBehavior,
            TriggerBehavior);
    }



    /**
     * sets node and app
     *
     */
    public setRootApp(app: IElement) {

        this.app = app;

        // return this instance
        return this;
    }



    /**
     * starts application
     *
     */
    public async start(node: Node) {

        this.node = node;

        // set framework to main node
        this.$view = new ViewController(node, null);
        View.parseAndCreateElement(this.app, this.node, createBindingContext(this), null, this.$view);

    }



    /**
     * register new custom attributes, custom elements
     *
     */
    public register(..._class: any[]) {

        // does not need to do anything really
        // by using them the decorator will kick in and they will be registered

    }

}
