import * as PIXI from 'pixi.js'
import { getValue } from '../../utils'

export function patch(layout: any) {
    switch (layout.target['type']) {
        case 'view':
        case 'rect':
            rect(layout)
            break
        case 'circle':
            circle(layout)
            break
        case 'text':
            text(layout)
            break
        case 'animatedsprite': {
            const { target, style = {} } = layout
            const { animatedLoop = true, animatedSpeed = 60 } = style
            if (+animatedSpeed) {
                // 处理帧率
                target.animationSpeed = +animatedSpeed >= 1 ? 
                    (1 / 60 * (+animatedSpeed)) : 
                    +animatedSpeed
            }

            target.loop = animatedLoop === 'false' ? false : !!animatedLoop
            target.replay = () => target.gotoAndPlay(0)
            target.play()
        }
        case 'sprite':
        default:
            sprite(layout)
            break
    }
}

const isGraphicsRepaint = (layout) => {
    if (layout && layout.styleHasChanged('width', 'height', 'borderWidth', 'borderColor', 'backgroundColor')) {
        return true
    }
    return false 
}

function rect(layout: any) {
    const { pixilayout, target, transform } = layout
    const { x, y, width, height, rotation } = pixilayout
    if (isGraphicsRepaint(layout)) {
        const style = getValue(layout, 'style') || {}
        const {
            backgroundColor,
            borderWidth = 0,
            borderColor = 0x000000,
            borderRadius = 0,
        } = style

        const _borderWidth = transform.length(width, borderWidth)
        const _borderRadius = transform.length(width, borderRadius)
        const _width = width - _borderWidth
        const _height = height - _borderWidth

        const { x: pivotX, y: pivotY } = target.pivot
        // 清除重新绘制
        target.clear()
        // 填充颜色
        // alpha 为 0 时，事件会失效，穿透到底部；
        const alpha = backgroundColor !== undefined ? 1 : 0.00001
        const bgColor = backgroundColor !== undefined ? backgroundColor : 0xFFFFFF
        target.beginFill(bgColor, alpha)
        // 绘制边框
        target.lineStyle(_borderWidth, borderColor, 1)
        // 根据不同的 radius 绘制对应的形状
        if (_borderRadius >= width / 2) {
            // 椭圆的定位锚点在圆心
            target.drawEllipse(0, 0, _width / 2, _height / 2)
        } else if (_borderRadius > 0) {
            // 圆角矩形与矩形的定位锚点不在中心
            target.drawRoundedRect(-_width * pivotX, -_height * pivotY, _width, _height, _borderRadius)
        } else {
            target.drawRect(-_width * pivotX, -_height * pivotY, _width, _height)
        }
        target.endFill()
    }

    // 设置位置
    if (target.x !== x) target.x = x
    if (target.y !== y) target.y = y
    if (target.rotation !== rotation) target.rotation = rotation
}

function circle(layout: any) {
    const { pixilayout, target, transform } = layout
    const { x, y, width, height } = pixilayout

    if (isGraphicsRepaint(layout)) {
        const style = getValue(layout, 'style') || {}
        const {
            backgroundColor,
            borderWidth = 0,
            borderColor = 0x000000,
        } = style
        const _borderWidth = transform.length(width, borderWidth)
        const _width = width - _borderWidth
        const _height = height - _borderWidth

        // 清除重新绘制
        target.clear()
        // 填充颜色
        const alpha = backgroundColor ? 1 : 0
        const bgColor = backgroundColor ? backgroundColor : 0xFFFFFF
        target.beginFill(bgColor, alpha)
        // 绘制边框
        target.lineStyle(_borderWidth, borderColor, 1)
        target.drawEllipse(0, 0, _width / 2, _height / 2)
        target.endFill()
    }

    // 设置位置
    if (target.x !== x) target.x = x
    if (target.y !== y) target.y = y
}

function text(layout: any) {
    const { target, pixilayout: { x, y, width, height, rotation }, style } = layout
    const { content } = style

    target.style = new PIXI.TextStyle(layout.textStyle)
    target.text = content
    
    if (target.width !== width) target.width = width
    if (target.height !== height) target.height = height
    if (target.x !== x) target.x = x
    if (target.y !== y) target.y = y
    if (target.rotation !== rotation) target.rotation = rotation
}

function sprite(layout: any) {
    const { target, pixilayout } = layout
    const { width, height, x, y, rotation } = pixilayout
    if (target.width !== width) target.width = width
    if (target.height !== height) target.height = height
    if (target.x !== x) target.x = x
    if (target.y !== y) target.y = y
    if (target.rotation !== rotation) target.rotation = rotation
}
