import { List } from '@pilotlab/collections';
import { Signal } from '@pilotlab/signals';
import { INode } from '@pilotlab/nodes';
import { AttributeChangeActions, DataType } from '../attributeEnums';
import IAttributeChangeOptions from './iAttributeChangeOptions';
import IAttributeSetReturn from './iAttributeSetReturn';
import IAttributeFactory from './iAttributeFactory';
import IAttributes from './iAttributes';
import AttributeEventArgs from '../attributeEventArgs';


export interface IAttribute extends INode {
    /*====================================================================*
     START: Properties
     *====================================================================*/
    readonly create:IAttributeFactory;


    label:string;
    summary:string;


    /**
     * The value of the associated data.
     */
    value:any;
    readonly valuePrevious:any;


    readonly dataType:(DataType | string);


    readonly attributes:IAttributes;


    /**
     * Attributes will be considered empty if no key or value has been set.
     */
    readonly isEmpty:boolean;


    /**
     * If this function returns true, the attribute will be omitted from
     * data transfer objects when saving data to the data store.
     */
    omitFromDataStore:(value:any) => boolean;


    readonly copy:IAttribute;


    /**
     * An automatically generated unique ID that is used when animating attribute values.
     */
    readonly animationKey:string;


    isEditable:boolean;
    isHidden:boolean;
    isAllowSave:boolean;


    /**
     * Should we allow accessor properties to be generated automatically when
     * a new child Attribute is added to our Attribute collection?
     */
    isAllowAutoProperties:boolean;


    formatter:(value:any) => any;


    /*====================================================================*
     START: Signals
     *====================================================================*/
    readonly changed:Signal<AttributeEventArgs<any>>;


    /*====================================================================*
     START: Public Methods
     *====================================================================*/
    /**
     * Set the attribute value.
     */
    set(
        value:any,
        changeOptions?:IAttributeChangeOptions,
    ):IAttributeSetReturn;


    /**
     * Interrupt any animated value transitions that are in effect.
     */
    interruptAnimation():void;


    /**
     * Manually trigger a dispatch on the 'changed' and/or saveTriggered signals.
     */
    doChanged(changeAction:AttributeChangeActions):void;
} // End interface


export default IAttribute;
