import VectorType from '../enum/VectorType.js'
import Geometry from './Geometry.js'
import Constant from '../Constant.js'
import { mathUtil } from '../MathUtil.js'
import SelectState from '../enum/SelectState.js'

export default class Rectangle extends Geometry {
    constructor(leftTopPosition,rightDownPosition, vectorId, floor) {
        super()
        this.points = []
        this.floor = floor?floor:0
        this.angle = 0;
        this.setPoints(leftTopPosition,rightDownPosition)
        this.color = 'rgba(0,0,0,1)';
        this.geoType = VectorType.Rectangle
        this.setId(vectorId)
    }

    setPoints(p1,p2){
        this.points[0] = {
            x:p1.x,
            y:p1.y
        }

        this.points[1] = {
            x:p2.x,
            y:p1.y
        }

        this.points[2] = {
            x:p2.x,
            y:p2.y
        }

        this.points[3] = {
            x:p1.x,
            y:p2.y
        }
    }

    //左上角是0
    updatePoints(newPosition,index){

        if(mathUtil.getDistance(newPosition,this.points[0])<Constant.minAdsorb){
            return;
        }

        let nextIndex = this.getNextIndex(index)
        let lastIndex = this.getLastIndex(index)

        let oppositeIndex = this.getNextIndex(nextIndex)

        const line1 = mathUtil.createLine1(this.points[oppositeIndex],this.points[lastIndex])
        const line2 = mathUtil.createLine1(this.points[oppositeIndex],this.points[nextIndex])
        if(line1 == null || line2 == null){
            return;
        }

        const join1 = mathUtil.getLineForPoint(line1, newPosition)
        const join2 = mathUtil.getLineForPoint(line2, newPosition)

        if(mathUtil.getDistance(join1,newPosition)<Constant.minAdsorb || mathUtil.getDistance(join2,newPosition)<Constant.minAdsorb){
            return;
        }

        this.points[index] = {
            x:newPosition.x,
            y:newPosition.y
        }

        this.points[lastIndex] = {
            x:join1.x,
            y:join1.y
        }

        this.points[nextIndex] = {
            x:join2.x,
            y:join2.y
        }
    }

    updateSides(newPosition,index){
        let nextIndex = this.getNextIndex(index)
        let lastIndex = this.getLastIndex(index)
        let nextnextIndex = this.getNextIndex(nextIndex)
        
        let line = mathUtil.createLine1(this.points[index],this.points[nextIndex])
        line = mathUtil.createLine3(line, newPosition)

        const line1 = mathUtil.createLine1(this.points[lastIndex],this.points[index])
        const line2 = mathUtil.createLine1(this.points[nextIndex],this.points[nextnextIndex])
        if(line1 == null || line2 == null){
            return;
        }
        const join1 = mathUtil.getIntersectionPoint(line, line1)
        const join2 = mathUtil.getIntersectionPoint(line, line2)

        if(mathUtil.getDistance(this.points[lastIndex],join1)<Constant.minAdsorb){
            return;
        }
        mathUtil.clonePoint(this.points[index],join1)
        mathUtil.clonePoint(this.points[nextIndex],join2)
    }

    getNextIndex(index){
        let nextIndex = index + 1;
        if(nextIndex == 4){
            nextIndex = 0;
        }
        return nextIndex;
    }

    getLastIndex(index){
        let lastIndex = index - 1;
        if(lastIndex < 0){
            lastIndex = 3
        }
        return lastIndex;
    }

    isContain(position){
        for(let i=0;i<this.points.length;++i){
            const dis = mathUtil.getDistance(position, this.points[i])
            if(dis < Constant.minAdsorb){
                return {
                    vertex:i
                };
            }
        }

        for(let i=0;i<this.points.length;++i){
            let point1 = this.points[i];
            let point2 = this.points[i+1];
            if(i == this.points.length-1){
                point2 = this.points[0]
            }
            let flag = mathUtil.isContainForSegment(position, point1, point2)
            if (flag) {
                return {
                    side:i
                };
            }
        }

        let flag = mathUtil.isPointInPoly(position, this.points)
        if(flag){
            return SelectState.All
        }
        return null;
    }

    setColor(color) {
        this.color = color
    }
}
