import CanvasRenderer from '../CanvasRenderer';
import { SCALE_MODES, BLEND_MODES } from '../../const';
import { Matrix, GroupD8 } from '../../math';
import Sprite from '../../display/Sprite';
import { DisplayObject } from '../../display/DisplayObject';
import Graphics from '../../graphics/Graphics';
import { getTintedTexture } from '../../utils';

const canvasRenderWorldTransform = new Matrix();


/**
 * Renderer dedicated to drawing and batching sprites.
 *
 * @class
 * @private
 */
export default class CanvasSpriteRenderer {
    renderer: CanvasRenderer;
    /**
     * @param {CanvasRenderer} renderer -The renderer sprite this batch works for.
     */
    constructor(renderer: CanvasRenderer) {
        this.renderer = renderer;
    }

    /**
     * Renders the sprite object.
     * 渲染带texture的显示对象，Sprite,Graphic
     * @param {Sprite} sprite - the sprite to render when using this spritebatch
     */
    render(sprite: any) {
        const texture = sprite._texture;
        const renderer = this.renderer;

        const width = texture._frame.width;
        const height = texture._frame.height;

        let wt = sprite.transform.worldMatrix;
        let dx = 0;
        let dy = 0;

        if (texture.orig.width <= 0 || texture.orig.height <= 0 || !texture.baseTexture.source) return;

        //  Ignore null sources
        if (!texture.valid) return

        //设置混色模式
        renderer.setBlendMode(sprite.blendMode);
        //透明度
        renderer.context.globalAlpha = sprite._worldAlpha;


        // If smoothingEnabled is supported and we need to change the smoothing property for sprite texture
        const smoothingEnabled = texture.baseTexture.scaleMode === SCALE_MODES.LINEAR;

        if (renderer.smoothProperty && renderer.context[renderer.smoothProperty] !== smoothingEnabled) {
            // 如果遇到性能问题，先禁掉
            renderer.context[renderer.smoothProperty] = smoothingEnabled;
        }
        if (sprite._anchorTexture) {
            if (texture.trim) {
                dx = (texture.trim.width / 2) + texture.trim.x - (sprite._anchorTexture.x * texture.orig.width);
                dy = (texture.trim.height / 2) + texture.trim.y - (sprite._anchorTexture.y * texture.orig.height);
            }
            else {

                dx = (0.5 - sprite._anchorTexture.x) * texture.orig.width;
                dy = (0.5 - sprite._anchorTexture.y) * texture.orig.height;
            }
            if (texture.rotate) {
                canvasRenderWorldTransform.copy(wt)
                wt = canvasRenderWorldTransform;
                GroupD8.matrixAppendRotationInv(wt, texture.rotate, dx, dy);
                // the anchor has already been applied above, so lets set it to zero
                dx = 0;
                dy = 0;
            }

            dx -= width / 2;
            dy -= height / 2;
        } else {
            dx = sprite["offsetX"] || 0;
            dy = sprite["offsetY"] || 0;
            // console.log(sprite["offsetX"])
        }

        renderer.context.setTransform(
            wt.a,
            wt.b,
            wt.c,
            wt.d,
            wt.tx,
            wt.ty
        );

        //处理outerBlend
        const outerBlend = renderer._outerBlend;
        if (outerBlend) {
            renderer.context.save();
            renderer.context.beginPath();
            renderer.context.rect(
                dx,
                dy,
                width,
                height
            );
            renderer.context.clip();
        }

        //判断调色
        if (sprite.tint !== 0xFFFFFF) {
            if (sprite.cachedTint !== sprite.tint || sprite.tintedTexture.tintId !== sprite._texture._updateID) {
                sprite.cachedTint = sprite.tint;
                //在sprite的destroy里置空，_texture上的tintCache暂时没法清
                sprite.tintedTexture = getTintedTexture(sprite._texture, sprite.tint);
            }

            renderer.context.drawImage(
                sprite.tintedTexture,
                0,
                0,
                width,
                height,
                dx,
                dy,
                width,
                height
            );
        }
        else {
            //考虑是否分开，
            renderer.context.drawImage(
                texture.baseTexture.source,
                texture._frame.x,
                texture._frame.y,
                width,
                height,
                dx,
                dy,
                width,
                height
            );
        }
        //如果处理过outerBlend
        if (outerBlend)  renderer.context.restore();
        
        //以防万一，设置一次
        renderer.setBlendMode(BLEND_MODES.NORMAL);
    }

    /**
     * destroy the sprite object.
     *
     */
    destroy() {
        this.renderer = null;
    }
}