import { Vector3 } from "three";

import * as utils from "./../engine/engine_three_utils.js";
import { Behaviour, GameObject } from "./Component.js";

export class BasicIKConstraint extends Behaviour {

    private from!: GameObject;
    private to!: GameObject;
    private hint!: GameObject;
    private desiredDistance: number = 1;

    onEnable(): void {
        // console.log(this);
    }

    update() {
        if (!this.from || !this.to || !this.hint) return;

        // console.log(this);

        // find center
        const toPos = utils.getWorldPosition(this.to).clone();
        const fromPos = utils.getWorldPosition(this.from).clone();
        const dist = toPos.distanceTo(fromPos);

        const dir0 = toPos.clone();
        dir0.sub(fromPos);
        const center = fromPos.clone();
        center.add(toPos);
        center.multiplyScalar(0.5);
        
        // find direction we should offset in
        const hintDir = utils.getWorldPosition(this.hint).clone();
        hintDir.sub(center);
        
        const offsetDir = new Vector3();
        offsetDir.crossVectors(hintDir, dir0);
        offsetDir.crossVectors(dir0, offsetDir);
        offsetDir.normalize();

        const halfDist = dist * 0.5;
        const stretchDistance = Math.max(this.desiredDistance, halfDist);
        const offsetLength = Math.sqrt(stretchDistance * stretchDistance - halfDist * halfDist);
        
        const resultPos = offsetDir.clone();
        resultPos.multiplyScalar(offsetLength);
        resultPos.add(center);
        utils.setWorldPosition(this.gameObject, resultPos);

        const lookPos = center.clone();
        lookPos.sub(offsetDir);
        this.gameObject.lookAt(lookPos);
    }
}