import Component from "../Component";
import InnerNode from "../../Data/InnerNode";

export default abstract class Structure extends Component{
    protected dataNode: InnerNode;
    protected contents: Component[] = [];
    public classes: string[] = [];
    public index: string|null = null;
    public displayDefaultNotice: boolean|null = null;

    protected constructor(params: Partial<Structure> = {}) {
        super(params);
        Object.assign(this, params);
    }

    public cleanHtml() {
        this.contents.forEach(c => c.cleanHtml());
        super.cleanHtml();
    }

    public updateVisibility() {
        super.updateVisibility();
        this.dataNode.isVisible = this.visible;
    }

    protected addStandardContainerProperties(container: HTMLElement): void {
        if (this.index != null) container.classList.add("pad-" + this.index);
        container.classList.add("pad-form-group", ...(this.classes));
        container.classList.toggle("pad-invalid", !this.dataNode.isValid);
        container.classList.toggle("pad-hidden", !this.visible);
        this.dataNode.onValidChange.add(event => {
            container.classList.toggle("pad-invalid", !event.isValid);
        });
        this.dataNode.onServerSideErrorsChange.add(event => {
            container.classList.toggle("pad-server-side-errors", event.errors.length !== 0);
        });
    }

    public addChildren(...children: Component[]): this {
        children.forEach(c => {
            this.contents.push(c)
        });
        return this;
    }

    public setDataNode(dataNode: InnerNode): this {
        this.dataNode = dataNode;
        return this;
    }

    public getDataNode(): InnerNode {
        return this.dataNode;
    }

    get isDisplayDefaultNotice(): boolean{
        return this.displayDefaultNotice ?? this.parent?.isDisplayDefaultNotice ?? false;
    }
}