import * as PIXI from 'pixi.js'
import { Graphics, Sprite, Text, Texture, AnimatedSprite } from "pixi.js"
import { eventify, usesify, error } from "../utils"
import addons from "../addons"
 // @ts-ignore
import transparentImage from '../images/transparent.png'

@usesify(addons)
@eventify
export default class Component {
    public static debug: boolean
    public static pixiComponents = [Graphics, Sprite, Text]

    public static use(addons: Component.addon | Component.addon[]) {
        const _addons = Array.isArray(addons) ? addons : [addons]
        _addons.map((addon: (core: any) => void) => addon(this))
    }

    public static on: (name: string, closure: () => void) => void
    public static emit: (name: string, ...data: any) => void

    private transparentTexture: Texture
    public uiDesignRatio: number
    constructor(config: Required<Component.config>) {
        const { uiDesignWidth, debug } = config
        this.uiDesignRatio = uiDesignWidth / window.innerWidth
        this.transparentTexture = Texture.from(transparentImage)
        
        Component.debug = debug
        Component.emit('init', config)
    }
    /**
     * @param { Component.type } type - 需要创建的元素类型
     * @param { Layout.style } style - 创建元素所需的配置参数
     */
    public createElement(type: Component.type, style: Layout.style) {
        Component.emit('beforeCreated', style)

        const instance = this.createInstance(type, style)
        instance['type'] = type.toLowerCase()

        Component.emit('created beforeMounted', {
            instance,
            style,
            uiDesignRatio: this.uiDesignRatio,
        })

        return instance
    }

    private createInstance(type: Component.type, style: Layout.style) {
        const {
            backgroundColor = 0xffffff,
            backgroundImage: image = this.transparentTexture,
            backgroundFrame,
            animatedFrames,
            content,
        } = style

        switch (type.toLowerCase()) {
            case "view":
                // 默认值充满父级
                if (!style['width'])style.width = '100%'
                if (!style['height'])style.height = '100%'
            case "rect": {
                const instance = new Graphics()
                instance.beginFill(backgroundColor as number)
                // 初始化宽高为1， 便于 pivot 统一设置为 0.5
                instance.drawRect(0, 0, 1, 1)
                instance.endFill()
                return instance
            }
            case "circle": {
                const instance = new Graphics()
                instance.beginFill(backgroundColor as number)
                instance.drawEllipse(0, 0, 1, 1)
                instance.endFill()
                return instance
            }
            case "text": {
                return new Text(content !== undefined ? String(content) : '')
            }
            case "animatedsprite": {
                if (animatedFrames) {
                    if (typeof animatedFrames === 'string') {
                        return AnimatedSprite.fromImages(animatedFrames.split(/,|\s/))
                    } else if (Array.isArray(animatedFrames)) {
                        if (animatedFrames[0] instanceof Texture) {
                            return new AnimatedSprite(animatedFrames as Texture[])
                        } else if (typeof animatedFrames[0] === 'string') {
                            return AnimatedSprite.fromFrames(animatedFrames as string[])
                        }
                    }
                } else {
                    error('animatedsprite should have the animations frames(texture array)!')
                }
            }
            case "sprite":
            default: {
                const texture = image instanceof PIXI.Texture ? image : Texture.from(image)
                if (backgroundFrame) {
                    const [x, y, w, h] = backgroundFrame as number[]
                    if (backgroundFrame.length === 4) {
                        texture.frame = new PIXI.Rectangle(x, y, w, h)
                    } else {
                        error('backgroundFrame is error!')
                    }
                }
                return new Sprite(texture)
            }
        }
    }
}
