import ngModule from '../../module';
import './portal';
import './style.scss';

export class Slot {
    constructor($element, vnSlotService) {
        this.$element = $element;
        this.vnSlotService = vnSlotService;
        this.$content = null;
    }

    $onDestroy() {
        this.unregister();
    }

    set name(value) {
        this.unregister();
        this._name = value;
        this.vnSlotService.slots[value] = this;
    }

    get name() {
        return this._name;
    }

    unregister() {
        if (this.name)
            this.vnSlotService.slots[this.name] = undefined;
    }

    setContent($content) {
        if (this.$content) {
            this.$content.detach();
            this.$content = null;
        }

        this.$content = $content;
        if (this.$content) this.$element.append($content);
        this.$element[0].style.display = $content ? 'block' : 'none';
    }
}
Slot.$inject = ['$element', 'vnSlotService'];

ngModule.vnComponent('vnSlot', {
    controller: Slot,
    bindings: {
        name: '@?'
    }
});

export class SlotService {
    constructor() {
        this.stacks = {};
        this.slots = {};
    }

    push(slot, $transclude) {
        if (!this.stacks[slot]) this.stacks[slot] = [];
        this.stacks[slot].unshift($transclude);
        this.refreshContent(slot);
    }

    pop(slot) {
        let $content = this.stacks[slot].shift();
        this.refreshContent(slot);
        if ($content && typeof $content == 'object')
            $content.remove();
    }

    getContent(slot) {
        if (this.slots[slot])
            return this.slots[slot].$element[0].firstElementChild;
        return null;
    }

    refreshContent(slot) {
        if (!this.slots[slot]) return;
        let $content = this.stacks[slot][0];
        if (typeof $content == 'function') {
            $content(clone => {
                $content = this.stacks[slot][0] = clone;
            });
        }
        this.slots[slot].setContent($content);
    }
}
ngModule.service('vnSlotService', SlotService);