import { AttributeController } from './attributeController';
import { ElementController } from './elementController';
import { InterpolateController } from './interpolateController';
import { IControllerObject } from '../interface/exported';

/**
 * Holds all elements/attributes and interpolates, so we can clear them later
 *
 */
export class ViewController {
    private items: IControllerObject;
    private childViewControllers: ViewController[];
    private count = 0;


    constructor(private htmlNode: Node, private viewController?: any) {
        if (viewController) {
            this.viewController.addChildView(this);
        }
    }


    /**
     * Get class instance from parent
     * @param _customElement custom element class you want to try and search for
     */
    public searchForInstance(_customElement: any): any | null {
        for (const k in this.items) {
            if (this.items && this.items[k]) {
                if (this.items[k].classInstance) {
                    if (this.items[k].classInstance instanceof _customElement) {
                        return this.items[k].classInstance;
                    }
                }
            }
        }
        if (this.viewController) {
            const y = this.viewController.searchForInstance(_customElement);
            if (y) {
                return y;
            }
        }

        return null;
    }


    /**
     * adds to internal object so we can call detached later
     *
     */
    public addElement(_class: ElementController) {
        this.count++;
        if (!this.items) {
            this.items = {};
        }
        this.items['e' + this.count] = _class;
    }



    /**
     * adds to internal object so we can call detached later
     *
     */
    public addAttribute(attibuteController: AttributeController): void {
        this.count++;
        if (!this.items) {
            this.items = {};
        }
        this.items['a' + this.count] = attibuteController;
    }



    /**
     * adds to internal object so we can call detached later
     *
     */
    public addInterpolate(interpolateController: InterpolateController): void {
        this.count++;
        if (!this.items) {
            this.items = {};
        }
        this.items['i' + this.count] = interpolateController;
    }



    /**
     * returns current element
     *
     */
    public getElement(): Node {
        return this.htmlNode;
    }


    public addChildView(viewController: ViewController) {

        if (!this.childViewControllers) {
            this.childViewControllers = [];
        }
        this.childViewControllers.push(viewController);
    }



    /**
     * remove it self from parent so we dont get memory leak
     *
     */
    public removeChildView(viewController: ViewController) {

        if (this.childViewControllers) {
            const i = this.childViewControllers.indexOf(viewController);
            if (i !== -1) {
                this.childViewControllers.splice(i, 1);
            }
        }

    }



    /**
     * calls detached on all attributes/elements and interpolates binded on view
     *
     */
    public clearView(): void {

        if (this.childViewControllers) {
            while (this.childViewControllers.length) {
                const view = this.childViewControllers.pop();
                view.clearView();
            }
        }

        if (this.items) {
            for (const item in this.items) {
                if (this.items[item].detached) {
                    this.items[item].detached();
                    this.items[item] = null;
                }
            }
        }

        if (this.viewController) {
            this.viewController.removeChildView(this);
        }

        this.childViewControllers = null;
        this.items = null;
        this.htmlNode = null;
        this.viewController = null;

    }



}
