import { Bounds } from './objects/bounds';
import { Rectangle } from './objects/rectangle';
import { Container } from './objects/container';
import { CompObject } from './compObj';
import { Matrix } from './matrix';

export class ObjsContainer {
    aabb = new Bounds();
    tempBound = new Bounds();
    parent = new Container();

    rect = new Rectangle();
    pivotIndex = 0;
    selected:CompObject[] = [];

    constructor(selected:any[]) {
        this.selected = selected;

        this.parent.sortableChildren = false;
        if (selected.length > 0) {
            this.init();
        }
    }

    clone() {
        const ret = new ObjsContainer([]);
        const parent = this.parent;

        ret.parent.pivot = parent.pivot;
        ret.parent.skew = parent.skew;
        ret.parent.scale = parent.scale;
        ret.parent.rotation = parent.rotation;
        ret.parent.position = parent.position;
        ret.rect.copyFrom(this.rect);
        ret.parent.updateTransform();
        ret.setPivot(this.pivotIndex);

        return ret;
    }

    getBound() {
        //加上parent的旋转和平移
        this.tempBound.clear();
        this.tempBound.addFrame(this.parent.transform, 0, 0, this.rect.width, this.rect.height);

        return this.tempBound.getRectangle();
    }

    get width() {
        return  this.rect.width
    }

    get height() {
        return this.rect.height;
    }

    testClick(sx:number,sy:number)
    {
        let w = this.width;
        let h = this.height;
        let local = {x:0,y:0} as any;
        this.parent.worldTransform.applyInverse({x:sx,y:sy} as any, local);

        if(  local.x < 0 || local.x > w ) return false;
        if(  local.y < 0 || local.y > h ) return false;

        return true;
    }

    init() {
        //获取选择对象的aabb（画布空间）
        this.aabb.clear();
        let n = this.selected.length;
        const selected = this.selected;
        const selectedRotation = 0;

        if (n == 1) { //单对象
            let obj = selected[0];
            let rect = new Rectangle(0, 0, obj.width , obj.height);
            this.rect = rect;
            this.parent.transform.setFromMatrix(obj.worldTransform);
            this.parent.updateTransform();
            this.parent.addChildWorldNoChange(obj);
            this.parent.updateTransform();
            return;
        }


        while (n--) {
            let obj = selected[n];
            let box = obj.calculateBounds();
            this.aabb.addBounds(box);
        }

        //构建当前对象的转换矩阵
        let rect = new Rectangle();
        this.aabb.getRectangle(rect);
        let center = rect.center;

        this.rect = rect;


        //设置位置
        let p = this.parent.position;
        p.x = center.x;
        p.y = center.y;

        //设置旋转中心点
        let pivot = this.parent.pivot;
        pivot.x = rect.width / 2;
        pivot.y = rect.height / 2;

        //设置旋转
        this.parent.scale = { x: 1, y: 1 } as any;
        this.parent.width = rect.width;
        this.parent.height = rect.height;

        //设置旋转
        this.parent.rotation = selectedRotation;

        // this.parent.scale = {x:1.5, y:1.5};
        this.parent.updateTransform();

        //选择的对象坐标从画布空间转到选框坐标,
        n = selected.length;
        for (let i = 0; i < n; i++) {
            let obj = selected[i];
            this.parent.addChildWorldNoChange(obj);
        }
        this.parent.updateTransform();
    }

    rotate(r:number) {
        this.parent.rotation = r;
        this.parent._boundsID++;
        this.parent.updateTransform();

        this.updateCompState();
    }

    //index
    // 0 ---- 1
    // |  4   |
    // 3 -----2
    setPivot(index:number) {
        let rect = this.rect;
        let pivots = [{ x: 0, y: 0 }, { x: rect.width, y: 0 }, { x: rect.width, y: rect.height }, { x: 0, y: rect.height }, { x: rect.width / 2, y: rect.height / 2 }];
        let targetPivot = pivots[index];

        let point = { x: targetPivot.x, y: targetPivot.y } as any;


        this.parent.worldTransform.apply(point, point);

        this.parent.pivot = targetPivot as any;
        this.parent.position.x = point.x;
        this.parent.position.y = point.y;

        this.parent.updateTransform();

        this.pivotIndex = index;

        return { x: point.x, y: point.y};
    }

    getPivotXY(index:number) {
        let rect = this.rect;
        let pivots = [{ x: 0, y: 0 }, { x: rect.width, y: 0 }, { x: rect.width, y: rect.height }, { x: 0, y: rect.height }, { x: rect.width / 2, y: rect.height / 2 }];
        let targetPivot = pivots[index];

        let point = { x: targetPivot.x, y: targetPivot.y } as any;
        this.parent.worldTransform.apply(point, point);

        let yIndex = 0, xIndex = 0;
        if (index == 3) {
            yIndex = 0;
            xIndex = 2;
        } else if (index == 0) {
            yIndex = 3;
            xIndex = 1;
        } else if (index == 1) {
            yIndex = 2;
            xIndex = 0;
        } else if (index == 2) {
            yIndex = 1;
            xIndex = 3;
        }

        let pointY = pivots[yIndex];
        let pY = { x: pointY.x, y: pointY.y } as any;
        this.parent.worldTransform.apply(pY, pY);

        let pointX = pivots[xIndex];
        let pX = { x: pointX.x, y: pointX.y } as any;
        this.parent.worldTransform.apply(pX, pX);

        let xVec = { x: (pX.x - point.x), y: (pX.y - point.y) };
        let yVec = { x: (pY.x - point.x), y: (pY.y - point.y) };

        return { x: xVec, y: yVec };
    }

    scale(x:number, y:number) {
        this.parent.scale.x = x;
        this.parent.scale.y = y;
        this.parent.updateTransform();
        this.updateCompState();
    }

    scaleX(x:number) {
        this.parent.scale.x = x;
        this.parent.updateTransform();
        this.updateCompState();
    }

    scaleY(y:number) {
        this.parent.scale.y = y;
        this.parent.updateTransform();
        this.updateCompState();
    }

    applyChildWidth(option:{scaleX?:number, scaleY?:number}) {
        // if (this.selected.length != 1) return;
        const obj = this.selected[0];

        //先移除
        this.parent.removeChildWorldNoChange(obj);
        const m = new Matrix();
        m.scale(option.scaleX ? option.scaleX : 1, option.scaleY? option.scaleY  : 1)
        m.invert();
        m.prepend(obj.worldTransform)
        obj.transform.setFromMatrix(m)
        if (option.scaleX) {
            obj.width = option.scaleX * obj.width;
        }
        if (option.scaleY) {
            obj.height = option.scaleY * obj.height;
        }
        
        obj.updateTransform();
        this.parent.addChildWorldNoChange(obj);
    }
    scaleSize(x:number, y:number) {

        let preW = this.parent.scale.x * this.rect.width;
        let preH = this.parent.scale.y * this.rect.height;

        this.parent.scale.y = y 
        this.parent.scale.x = x

        const Width = this.parent.scale.x * this.rect.width;
        const Height = this.parent.scale.y * this.rect.height;

        this.parent.updateTransform();

        this.applyChildWidth({scaleX: Width / preW, scaleY: Height/preH})
        this.updateCompState();

    }

    scaleWidth(x:number) {
        const prew = this.parent.scale.x * this.rect.width;
        //怎么改对应的偏移值
        this.parent.scale.x = x
        const w = this.parent.scale.x * this.rect.width;

        this.parent.updateTransform();
        this.applyChildWidth({scaleX: w / prew })
        this.updateCompState();
    }

    scaleHeight(y:number) {
        const preH = this.parent.scale.y * this.rect.height;
        this.parent.scale.y = y
        const h = this.parent.scale.y * this.rect.height;
        this.parent.updateTransform();
        this.applyChildWidth({scaleY: h / preH});
        this.updateCompState();
    }

    translate(x:number, y:number) {
        this.parent.x += x;
        this.parent.y += y;
        this.parent.updateTransform();
        this.updateCompState();
    }

    destroy() {//选中的对象坐标转到画布空间坐标
        let selected = this.selected;
        let n = selected.length;
        while (n--) {
            let child = selected[n];
            this.parent.removeChildWorldNoChange(child)
        }
        this.selected = [];
    }

    updateCompState() {
        let n = this.selected.length;
        while (n--) {
            let child = this.selected[n];
            child.comp.layout.transformMatrix = child.worldTransform.getMatrixStr();
        }
    }
}