const { ccclass, property } = cc._decorator;

@ccclass
export default class Test extends cc.Component {

    private rect1: cc.Node;
    private circle1: cc.Node;
    private circle2: cc.Node;
    private rect2: cc.Node;
    private circle3: cc.Node;
    private circle4: cc.Node;

    private debug: cc.Graphics;

    protected start(): void {
        this.rect1 = this.node.getChildByName("rect1");
        this.circle1 = this.node.getChildByName("circle1");
        this.circle2 = this.node.getChildByName("circle2");
        this.rect2 = this.node.getChildByName("rect2");
        this.circle3 = this.node.getChildByName("circle3");
        this.circle4 = this.node.getChildByName("circle4");
        this.debug = this.node.getChildByName("debug").getComponent(cc.Graphics);

        this.initTouch(this.rect1, this.circle1, this.circle2);
        this.initTouch(this.rect2, this.circle3, this.circle4);
    }
    private initTouch(rect: cc.Node, circle1: cc.Node, circle2: cc.Node): void {
        let oldP: cc.Vec2;
        const touch_start = (evt: cc.Event.EventTouch) => {
            oldP = evt.getLocation();
        };
        const touch_move = (evt: cc.Event.EventTouch) => {
            const p = evt.getLocation();
            evt.target.x += p.x - oldP.x;
            evt.target.y += p.y - oldP.y;
            oldP = p;
            const dx = circle2.x - circle1.x;
            const dy = circle2.y - circle1.y;
            rect.x = circle1.x;
            rect.y = circle1.y;
            rect.width = Math.sqrt(dx * dx + dy * dy);
            rect.angle = Math.atan2(dy, dx) * 180 / Math.PI;
            circle2.x = rect.x + dx;
            circle2.y = rect.y + dy;
            this.checkHit();
        };
        rect.on(cc.Node.EventType.TOUCH_START, touch_start);
        rect.on(cc.Node.EventType.TOUCH_MOVE, (evt: cc.Event.EventTouch) => {
            const p = evt.getLocation();
            circle1.x = rect.x += p.x - oldP.x;
            circle1.y = rect.y += p.y - oldP.y;
            oldP = p;
            const rad = rect.angle * Math.PI / 180;
            circle2.x = rect.x + Math.cos(rad) * rect.width;
            circle2.y = rect.y + Math.sin(rad) * rect.width;
            this.checkHit();
        });
        circle1.on(cc.Node.EventType.TOUCH_START, touch_start);
        circle1.on(cc.Node.EventType.TOUCH_MOVE, touch_move);
        circle2.on(cc.Node.EventType.TOUCH_START, touch_start);
        circle2.on(cc.Node.EventType.TOUCH_MOVE, touch_move);
    }

    private checkHit(): void {
        this.debug.clear();

        this.debug.moveTo(this.circle1.x, this.circle1.y);
        this.debug.lineTo(this.circle2.x, this.circle2.y);
        this.debug.circle(this.circle1.x, this.circle1.y, 4);
        this.debug.circle(this.circle2.x, this.circle2.y, 4);
        this.debug.moveTo(this.circle3.x, this.circle3.y);
        this.debug.lineTo(this.circle4.x, this.circle4.y);
        this.debug.circle(this.circle3.x, this.circle3.y, 4);
        this.debug.circle(this.circle4.x, this.circle4.y, 4);

        const bananaResult = this.banana(this.circle1.x, this.circle1.y, this.circle2.x, this.circle2.y, this.circle3.x, this.circle3.y, this.circle4.x, this.circle4.y);
        this.debug.circle(bananaResult.x, bananaResult.y, 6);
        console.log(bananaResult.k1, bananaResult.k2);

        this.debug.stroke();
    }

    //线段 (x1, y1) - (x2, y2) 和 (x3, y3) - (x4, y4) 交点
    public banana(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, x4: number, y4: number): { x: number, y: number, k1: number, k2: number } {
        const dx12 = x2 - x1;
        const dy12 = y2 - y1;
        const dx34 = x4 - x3;
        const dy34 = y4 - y3;
        const dx13 = x3 - x1;
        const dy13 = y3 - y1;
        const dd = dx12 * dy34 - dy12 * dx34;
        const k1 = (dx13 * dy34 - dy13 * dx34) / dd;
        const k2 = (dx13 * dy12 - dy13 * dx12) / dd;
        return { x: x1 + k1 * dx12, y: y1 + k1 * dy12, k1: k1, k2: k2 };
    }

}
