/**
 * @mergeTarget
 * @module Src/Core/Components
 */
import { LisioEvent } from "../engine-types";
/**
 * ## How to create a component ?
 *
 *  In this section we will learn hwo to create a component more and more complexe to explore main features of components.
 *
 * ### How to create a component which only render basic HTML ?
 *
 * It's very simple to create a component, to do so you need to create a class which extends {@link LisioComponent} and implements {@link LisioComponent.render}.\
 * Here an exemple of a text component :
 * ```
 *  class Text extends LisioComponent{
 *    render(hasToLoadAssests: boolean){
 *      "<p>I'm a paragraph</p>";
 *    }
 * }
 * ```
 *
 * ### How to create a component which only render complexe HTML ?
 *
 * Everything you can do in HTML can aslo be done here, for exemple create a bit more complexe HTML structure :
 * ```
 *  class Page extends LisioComponent{
 *    render(hasToLoadAssests: boolean){
 *      `<div>
 *        <p>I'm a paragraph</p>
 *        <p>I'm a second paragraph</p>
 *       </div>`;
 *    }
 * }
 * ```
 *
 * ### How to create a component which render children components ?
 *
 * Now we gonne take advantage of component-based architecture. We will modify and use our Text component in our Page component.\
 * First of all, you have to make text of p tag dynamic :
 * ```
 *  class Text extends LisioComponent{
 *    private _text: string = "";
 *
 *    render(hasToLoadAssests: boolean){
 *      `<p>${this._text}</p>`;
 *    }
 *
 *    constructor(text:string ){
 *        super(Text.name);
 *        this._text = text;
 *    }
 * }
 * ```
 * Now the text displayed in p can be dynamically change in Page :
 * ```
 *  class Page extends LisioComponent{
 *    render(hasToLoadAssests: boolean){
 *      `<div>
 *          <children></children>
 *       </div>`;
 *    }
 *
 *    constructor(){
 *        super(Page.name);
 *        this._children.push(
 *            new Text("I'm a paragraph"),
 *            new Text("I'm a second paragraph")
 *        );
 *    }
 * }
 * ```
 * Children tag was added to indicates were children components have to be inserted.
 *
 * ### How to create a component with attributes like id or className ?
 *
 * You can pass id, class or some aria attributes in parameter of class constructor.\
 * You can also add your own attribute by modifying Text class. You have to add an attribute and affected it a value in constructor to be used when renderer method will be called.
 * ```
 *  class Text extends LisioComponent{
 *    private _text: string = "";
 *
 *    private _customAttribute: string;
 *
 *    render(hasToLoadAssests: boolean){
 *      `<p id="${this._id}" class="${this._cssClass}"} my-custom-attribute=${this._customAttribute}>${this._text}</p>`;
 *    }
 *
 *    constructor(text:string, id:string, class: string, customAttribute: string){
 *        super(Text.name, id, class);
 *        this._text = text;
 *        this._customAttribute = customAttribute;
 *    }
 * }
 *
 * new Text("Im' a paragraph", "paragraph-1", "red-paragraph");
 * ```
 *
 * ### How to create a component with event listeners ?
 *
 * To add event listeners you have to do same as you did with children but using {@link LisioComponent._eventListeners | _eventListeners} and respect {@link Src/Core.LisioEvent | LisioEvent} type structure:
 * ```
 *  class Text extends LisioComponent{
 *    private _text: string = "";
 *
 *    render(hasToLoadAssests: boolean){
 *      `<p>${this._text}</p>`;
 *    }
 *
 *    constructor(text:string){
 *        super(Text.name);
 *        this._text = text;
 *        const eventListener: LisioEvent = {
 *          type: "click",
 *          handler: () => {
 *            console.log("click");
 *          }
 *        }
 *    }
 * }
 * ```
 * Depending on your need your event type or your handler can be dynamic.
 *
 * ## Documentation
 * Abstract class representing a Lisio component.\
 * It aims to provides base attributes and methods for children components.\
 * If you need to create a component it has to extend this class.\
 * To execute his responsability this class provides :
 *  * Method for render
 *  * Method called after render
 *  * Method to add children dynamically
 *  * Method to attach event listeners
 *  * Method to show or hide component
 *  * Method to add class before render
 */
declare abstract class LisioComponent {
    /**
     * Protected attribute to store component name
     * @source
     */
    protected _componentName: string;
    /**
     * Protected attribute to store html element of the component
     * @source
     */
    protected _htmlElement?: HTMLElement;
    /**
     * Protected attribute to store component id
     * @source
     */
    protected _id?: string;
    /**
     * Protected attribute to store component children
     * @source
     */
    protected _children: LisioComponent[];
    /**
     * Protected attribute to store all event listeners
     * @source
     */
    protected _eventListeners: LisioEvent[];
    /**
     * Protected attribute to store CSS class
     * @source
     */
    protected _cssClass: Set<string>;
    /**
     * Protected attribute to store component attributes
     * @source
     */
    protected _attributes: Map<string, string>;
    /**
     * Getter for attribute {@link _componentName | _componentName}
     * @returns Returns _componentName attribute
     * @source
     */
    get componentName(): string;
    /**
     * Getter for attribute {@link _htmlElement | _htmlElement}
     * @returns Returns _htmlElement attribute
     * @source
     */
    get htmlElement(): HTMLElement | undefined;
    /**
     * Setter for attribute {@link _htmlElement | _htmlElement}
     * @param {HTMLElement} value -  HTML element of component
     * @returns Returns nothing
     * @source
     */
    set htmlElement(value: HTMLElement);
    /**
     * Getter for attribute {@link _id | _id}
     * @returns Returns _id attribute
     * @source
     */
    get id(): string | undefined;
    /**
     * Getter for attribute {@link _children | _children}
     * @returns Returns _children attribute
     * @source
     */
    get children(): LisioComponent[];
    /**
     * Getter for attribute {@link _attributes | _attributes}
     * @returns Returns _attributes attribute
     * @source
     */
    get attributes(): Map<string, string>;
    /**
     * @async
     * Public asbtract method to render a component
     * @param {boolean | undefined} hasToLoadAssets - Indicates if component has to load assets
     * @returns Returns a promise containing stringified HTML of component
     * @source
     */
    abstract render(hasToLoadAssets?: boolean): Promise<string>;
    /**
     * @async
     * Public asbtract method to render a component
     * @returns Returns a promise containing stringified HTML of component
     */
    abstract render(): Promise<string>;
    /**
     * @virtual
     * Public virtual method to make things just after rendered
     * @returns Returns nothing
     * @source
     */
    postRender(): void;
    /**
     * Public method to add children dynamically.\
     * This method does :
     *  * Add child to children array
     *  * Send child to be rendered if needed
     * @param {LisioComponent[]} children - Chidlren to add and render if needed
     * @param {"append" | "before"} insertMode - Insert mode of children
     * @param {LisioComponent} refererComponent - referer component to insert children
     * @returns Returns nothing
     * @source
     */
    protected addChildren(children: LisioComponent[], insertMode: "append" | "before", refererComponent?: LisioComponent): void;
    /**
     * Public method to delete children dynamically.\
     * This method does :
     *  * Remove child in children array
     *  * Remove child from DOM if needed
     * @param {LisioComponent[]} childrenToDelete - Children to delete
     * @returns Returns nothing
     * @source
     */
    protected removeChildren(childrenToDelete: LisioComponent[]): void;
    /**
     * Public method to attach event listeners to HTML element
     * @returns Returns nothing
     * @source
     */
    attachEventListeners(): void;
    /**
     * Public method to show or hide a component
     * @param {boolean} isShown - Indicates if component has to be shown
     * @returns Returns nothing
     * @source
     */
    showHideElement(isShown: boolean): void;
    /**
     * Public method to add classes to component
     * @param {string[]} classes - Classes to add.\ Exemple : ["classA", "classB"]
     * @returns Returns nothing
     * @source
     */
    addClasses(classes: string[]): void;
    /**
     * Public method to remove classes to component
     * @param {string[]} classes - Classes to remove.\ Exemple : ["classA", "classB"]
     * @returns Returns nothing
     * @source
     */
    removeClasses(classes: string[]): void;
    /**
     * Public method to toggle classes to component
     * @param {string[]} classes - Classes to toggle.\ Exemple : ["classA", "classB"]
     * @returns Returns nothing
     * @source
     */
    toggleClasses(classes: string[]): void;
    /**
     * Protected method to render all attributes
     * @source
     */
    protected renderAttributes(): string;
    /**
     * Protected method to render all classes
     * @source
     */
    protected renderClasses(): string;
    /**
     * Public method to render add attributes
     * @param {string} attributeName - Attribute name to add
     * @param {string} attributeValue - Attribute value to add
     * @returns Returns nothing
     * @source
     */
    addAttributes(attributeName: string, attributeValue: string): void;
    /**
     * Public method to render remove attributes
     * @param {string} attributeName - Attribute name to remove
     * @returns Returns nothing
     * @source
     */
    removeAttributes(attributeName: string): void;
    /**
     * Public method to search a child by his id in all children
     * @param {string} childId - Id of desired child
     * @returns Returns element if found, else undefined
     * @source
     */
    findChildById(childId: string): LisioComponent | undefined;
    /**
     * Public method to search a child by his component name in all children
     * @param {string} childName - Name of desired child
     * @returns Returns element if found, else undefined
     * @source
     */
    findChildByName(childName: string): LisioComponent | undefined;
    /**
     * Public method to search a child by his class in all children
     * @param {string} childClass - Class of desired child
     * @returns Returns element if found, else undefined
     * @source
     */
    findChildByClass(childClass: string): LisioComponent | undefined;
    /**
     * Public method to search a child by his class in all children
     * @param {string} childAttribute - Attribute of desired child
     * @param {string | undefined} childAttributeValue - Attribute value of desired child
     * @returns Returns element if found, else undefined
     * @source
     */
    findChildByAttribute(childAttribute: string, childAttributeValue?: string): LisioComponent | undefined;
    /**
     * Constructor for class {@link LisioComponent | LisioComponent}
     * @param {string} componentName - Component name
     * @param {string | undefined} id - Component id
     * @param {string[] | undefined} cssClasses - Component CSS classes
     * @param {Map<string, string> | undefined} attributes - Component attributes
     * @source
     */
    constructor(componentName: string, id?: string, cssClasses?: string[], attributes?: Map<string, string>);
}
export { LisioComponent };
