declare namespace Component {
    type spriteImage = string | number | PIXI.Texture | HTMLCanvasElement | HTMLVideoElement | HTMLImageElement
    type addon = (core: any) => void
    type type = "Text" | "Sprite" | "Container" | "Rect" | "Circle" | "AnimatedSprite"
    interface config {
        uiDesignWidth: number
    }
}

declare namespace Layout {
    type element = PIXI.Sprite | PIXI.Graphics | PIXI.Text
    interface style {
        width?: string | number,
        height?: string | number,
        left?: string | number,
        right?: string | number,
        bottom?: string | number,
        top?: string | number,
        centerX?: string | number,
        centerY?: string | number,
        rotation?: number | string,
        scale?: number,
        opacity?: number,
        backgroundColor?: number | string
        backgroundImage?: PIXI.Texture
        backgroundFrame?: number[]
        borderWidth?: number,
        borderColor?: number | string,
        anchor?: { x: number, y: number },
        zIndex?: number,
        textAlign?: 'left' | 'center' | 'right'
        content?: string,
        color?: string | number,
        fontSize?: number | string,
        fontWeight?: "normal" | "bold" | "bolder" | "lighter" | "100" | "200" | "300" | "400" | "500" | "600" | "700" | "800" | "900"
        fontStyle?: "normal" | "italic" | "oblique"
        fontFamily?: string | string[]
        lineHeight?: number,
        [restProps: string]: any,

        // AnimatedSprite 专属
        animatedFrames?: PIXI.Texture[]
        animatedLoop?: boolean
        animationSpeed?: number
    }
    interface point {
        x: number,
        y: number,
    }
    interface size {
        width: number,
        height: number,
    }
    interface scale {
        x: number,
        y: number,
    }
    interface config {
        uiDesignRatio: number
        Component: {
            on: (name: string, closure: () => void) => void
            emit: (name: string, data?: any) => void
        }
    }
    interface transform {
        rotation: (angle: number | string) => number
        length: (containerLength: number, value: string | number) => number,
        pos: (containerLength: number, spriteLength: number, value: number | string) => number,
        actualScale: (container: element) => { x: number, y: number },
        actualSize: (target: element) => size,
        getRatio: (target: element) => number
        elementSize: (
            target: element,
            style: style,
            containerSize: size,
        ) => size
        elementPos: (
            size: size,
            style: style,
            containerSize: size,
        ) => {
            x: number,
            y: number,
            rotation: number,
        }
        container: (element: element) => containerStatus
        rlayout2pixilayout: (container: containerStatus, anchor: point, rlayout: layout) => layout
        pixilayout2rlayout: (container: containerStatus, anchor: point, pixilayout: layout) => layout
    }
    interface containerStatus {
        element: element,
        width: number,
        height: number,
        ratio: number,
        scale: {
            x: number,
            y: number,
        },
    }
    interface layout {
        width: number
        height: number
        x: number
        y: number
        rotation: number
    }
}

interface componentBase {
    layout: {
        update: (style?: Layout.style) => void
        setScale: (scale: number) => void
    }
    appendTo: (container: any) => void
    append: (child: any) => void
    before: (element: any) => void
    after: (element: any) => void
    insertBefore: (element: any) => void
    insertAfter: (element: any) => void
    remove: () => void
    getRelativeBounds: () => { width: number, height: number, x: number, y: number }
    getGlobalBounds: () => { width: number, height: number, x: number, y: number }
}

interface componentSprite extends PIXI.Sprite, componentBase {}
interface componentText extends PIXI.Text, componentBase {}
interface componentRect extends PIXI.Text, componentBase {}
interface componentCircle extends PIXI.Text, componentBase {}

declare module '@amoy/components' {
    function configComponents(config?: Component.config): void
    function Sprite(image: Component.spriteImage, style?: Layout.style): componentSprite
    function AnimatedSprite(animatedFrames: PIXI.Texture[], style?: Layout.style): componentSprite
    function Text(centent: string, style?: Layout.style): componentText
    function Rect(style?: Layout.style): componentRect
    function Circle(style?: Layout.style): componentCircle
    function Container(style?: Layout.style): componentSprite
}