import { SelectCtrl } from ".";
import { ObjsContainer } from "./ObjsContainer";
import { CompObject } from "./compObj";


/**
 * 吸附功能实现
 */
export class AssistMagnetCtrl { 
    ctrl: SelectCtrl

    constructor(ctrl: SelectCtrl) {
        this.ctrl = ctrl;
    }

    rulerYs:number[]= [];
    rulerXs:number[]= [];

    clientX = 0;
    clientY = 0;
    currRefYs:number[] = [];
    currRefXs:number[] = []
    otherSlides : CompObject[] = [];

    getMinValues(srcYs:number[], refYs: number[]) {
        //找出最近的参考线
        let n = srcYs.length;
        let out :{min: number, v:number, o:number}[] = [];
        while(n--) {
            const srcY = srcYs[n];
            let k = refYs.length;
            let currMinY = 10000;
            let currMinRefY = -10000;
            let lastOffset = 0;
            for (let i=0; i<k; i++) {
                 const o = srcY - refYs[i]
                if (Math.abs(o) <= currMinY) {
                    currMinY = Math.abs(o);
                    currMinRefY = refYs[i]
                    lastOffset = o;
                    continue;
                } 
                break
            }
            out.push({min: currMinY, v: currMinRefY, o: lastOffset})
        }
        out = out.sort((a, b)=>(a.min-b.min))

        let min = out[0].min;
        const sames = [out[0].v];
        let m = out.length;
        for(let i=1; i<m; i++) {
            if (Math.abs(out[i].min- min) < 1) {
                sames.push(out[i].v);
            } else {
                break;
            }
        }
        return {offset: out[0].o, min: min,  values: sames};
    }

    test(e:MouseEvent) {

        this.clientX = e.clientX;
        this.clientY = e.clientY;
    
        const eps = 6;
        const Objc = this.ctrl.objContainer as ObjsContainer
        const bund = Objc.getBound();
        const box = this.ctrl.getCurrCardBox();

        //包围盒的上 中 下 三条横线
        const srcY1 = (bund.y + box.top)*2.0
        const srcYs = [srcY1,  srcY1 + bund.height, srcY1 + bund.height*2];
        if (this.rulerYs.length < 1) {
            this.rulerYs.push(box.top *2.0) //card上边线
            this.rulerYs.push(box.top *2.0 + box.height )//中线
            this.rulerYs.push((box.top  + box.height) * 2.0) //下边线

            //所有参考线
            const rulers = this.ctrl.assistRuler?.rulers || [];
            let n = rulers.length;
            while(n--) {
                if (rulers[n].horz != undefined) 
                this.rulerYs.push(box.top *2 + (rulers[n].horz as number));
            }
            //添加card内的其他对象
            this.otherSlides = this.ctrl.getUnSelectChilds();

            this.otherSlides.forEach(item=>{
                const b = item.getBox();
                const y = (b.y + box.top) *2.0
                if (this.rulerYs.indexOf(y) == -1) {
                    this.rulerYs.push(y)
                }
                const y1 = y + b.h
                if (this.rulerYs.indexOf(y1) == -1) {
                    this.rulerYs.push(y1)
                }
                const y2 = y + b.h *2
                if (this.rulerYs.indexOf(y2) == -1) {
                    this.rulerYs.push(y2)
                }
            })
            this.rulerYs = this.rulerYs.sort((a,b)=>a-b)


        }
        this.currRefYs = [];
        const {offset, min, values} = this.getMinValues(srcYs, this.rulerYs)
        if (min < eps) {//找到了最近点，进行磁铁吸附
            this.clientY = e.clientY - offset / 2.0;
            this.currRefYs = values;
        }

        //包围盒的左 中 右三条横线
        const srcX1 = (bund.x + box.left)*2.0
        const srcXs = [srcX1,  srcX1 + bund.width, srcX1 + bund.width*2];
        if (this.rulerXs.length < 1) {
            this.rulerXs.push(box.left *2.0) //card上边线
            this.rulerXs.push(box.left *2.0 + box.width )//中线
            this.rulerXs.push((box.left  + box.width) * 2.0) //下边线

            //所有参考线
            const rulers = this.ctrl.assistRuler?.rulers || [];
            let n = rulers.length;
            while(n--) {
                if (rulers[n].verz != undefined) 
                this.rulerXs.push(box.left *2 + (rulers[n].verz as number));
            }

            //添加card内的其他对象
            this.otherSlides.forEach(item=>{
                const b = item.getBox();
                const x = (b.x + box.left) *2.0
                if (this.rulerXs.indexOf(x) == -1) {
                    this.rulerXs.push(x)
                }
                const x1 = x + b.w
                if (this.rulerXs.indexOf(x1) == -1) {
                    this.rulerXs.push(x1)
                }
                const x2  = x + b.w *2
                if (this.rulerXs.indexOf(x2) == -1) {
                    this.rulerXs.push(x2)
                }
            })
            this.rulerXs = this.rulerXs.sort((a,b)=>a-b)
        }

        this.currRefXs = [];
        const ret = this.getMinValues(srcXs, this.rulerXs)
        if (ret.min < eps) {//找到了最近点，进行磁铁吸附
            this.clientX = e.clientX - ret.offset / 2.0;
            this.currRefXs = ret.values;
        }
    }

    onMouseUp() {
        this.rulerYs = [];
        this.rulerXs = [];
        this.currRefXs = [];
        this.currRefYs = [];
    }

    draw() {
        if ( !(this.currRefXs.length > 0 || this.currRefYs.length > 0) ) {
            return;
        }

        const ctx = this.ctrl._selCtx;
        let n = this.currRefXs.length;
        ctx.lineWidth = 2;
        ctx.strokeStyle = "orange"; 
        // 清除虚线样式
        // ctx.setLineDash([]);

        while(n--) {
            let x = this.currRefXs[n]
            ctx.beginPath();
            ctx.moveTo(x, 0)
            ctx.lineTo(x, this.ctrl._selCanvaseSize.h);
            ctx.stroke();
            ctx.closePath();
        }

        const box = this.ctrl.getViewPortBox();
        n = this.currRefYs.length;
        while(n--) {
            let y = this.currRefYs[n]
            ctx.beginPath();
            ctx.moveTo(box.left*2, y)
            ctx.lineTo(box.right*2, y);
            ctx.stroke();
            ctx.closePath();
        }
    }
}