"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DragLabelDropWorldUC = void 0;
exports.makeDragLabelDropWorldUC = makeDragLabelDropWorldUC;
const core_1 = require("@vived/core");
const core_2 = require("@vived/core");
const SceneRayPickUC_1 = require("../../Babylon/UC/SceneRayPickUC");
const BaseAppState_1 = require("../../BaseApp/Entity/BaseAppState");
const ChallengeEntity_1 = require("../../Challenge/Entities/ChallengeEntity");
const LabelDropRepo_1 = require("../Entities/LabelDropRepo");
const CorrectAnimationUC_1 = require("./CorrectAnimationUC");
const DropOnNothingAnimationUC_1 = require("./DropOnNothingAnimationUC");
const IncorrectAnimationUC_1 = require("./IncorrectAnimationUC");
class DragLabelDropWorldUC extends core_1.AppObjectUC {
    static get(appObjects) {
        return (0, core_1.getSingletonComponent)(DragLabelDropWorldUC.type, appObjects);
    }
}
exports.DragLabelDropWorldUC = DragLabelDropWorldUC;
DragLabelDropWorldUC.type = "DragLabelDropWorldUC";
function makeDragLabelDropWorldUC(appObject) {
    return new DragLabelDropWorldUCImp(appObject);
}
class DragLabelDropWorldUCImp extends DragLabelDropWorldUC {
    get repo() {
        return this.getCachedSingleton(LabelDropRepo_1.LabelDropRepo.type);
    }
    get challenge() {
        return this.getCachedSingleton(ChallengeEntity_1.ChallengeEntity.type);
    }
    get baseApp() {
        return this.getCachedSingleton(BaseAppState_1.BaseAppState.type);
    }
    initializeDrag(labelDropID, ray) {
        if (!this.repo || !this.challenge)
            return;
        if (this.challenge.selectedChallenge !== "LABEL_DROP")
            return;
        if (this.baseApp?.isAuthoring === true)
            return;
        if (this.currentAnimation) {
            this.currentAnimation.cancel();
            this.repo.resultIsCorrect = undefined;
            this.repo.draggingID = undefined;
        }
        const pick = this.doPick(ray);
        if (!pick)
            return;
        this.positionHelper(pick);
        this.positionDragLabelFromHelper();
        this.repo.draggingID = labelDropID;
        this.repo.dragMode = LabelDropRepo_1.LabelDropDragMode.WORLD;
        this.repo.dragAlpha = 1;
        this.dragStartPosition = pick;
        this.isDragging = true;
    }
    positionHelper(worldPosition) {
        if (!this.repo)
            return;
        const helper = this.repo.dragHelperTransform;
        helper.worldPosition = worldPosition;
        const localZ = helper.localPosition.z * this.percentOfPickDepth;
        helper.localPosition = new core_2.Vector3(0, 0, localZ);
        helper.localRotation = core_2.Quaternion.Identity();
    }
    doPick(ray) {
        const scenePick = (0, SceneRayPickUC_1.sceneRayPick)(ray, this.appObjects);
        if (scenePick && scenePick.worldPickPoint) {
            return scenePick.worldPickPoint;
        }
        const zeroParallaxPlane = core_2.ParametricPlane.FromPointNormal(core_2.Vector3.Zero(), core_2.Vector3.Forward());
        const zeroParallaxPick = zeroParallaxPlane.intersectLine(ray);
        return zeroParallaxPick;
    }
    positionDragLabelFromHelper() {
        if (!this.repo)
            return;
        this.repo.dragLabelTransform.worldPosition = this.repo.dragHelperTransform.worldPosition;
        this.repo.dragLabelTransform.worldRotation = this.repo.dragHelperTransform.worldRotation;
    }
    updateDrag(ray) {
        if (!this.isDragging)
            return;
        if (!this.repo || !this.challenge)
            return;
        if (this.challenge.selectedChallenge !== "LABEL_DROP")
            return;
        if (this.baseApp?.isAuthoring === true)
            return;
        const pick = this.doPick(ray);
        if (!pick)
            return;
        this.positionHelper(pick);
        this.positionDragLabelFromHelper();
    }
    async releaseDrag(ray) {
        if (!this.baseApp)
            return;
        if (!this.isDragging)
            return;
        this.isDragging = false;
        if (!this.repo || !this.challenge)
            return;
        if (this.challenge.selectedChallenge !== "LABEL_DROP")
            return;
        if (this.baseApp?.isAuthoring === true)
            return;
        if (!this.repo.draggingID) {
            this.warn("Trying to release a label drop without an ID");
            return;
        }
        const pickID = (0, SceneRayPickUC_1.sceneRayPick)(ray, this.appObjects)?.appObjectID;
        if (!pickID) {
            const animationUC = DropOnNothingAnimationUC_1.LabelDropOnNothingAnimationUC.get(this.appObjects);
            if (!animationUC) {
                this.warn("Unable to find LabelDropOnNothingAnimationUC");
                return;
            }
            this.currentAnimation = animationUC;
            animationUC.desiredFinalPosition = this.dragStartPosition;
            const didComplete = await animationUC.start();
            if (didComplete)
                this.onAnimationComplete();
            return;
        }
        const isCorrect = this.repo.submitLabelDrop(this.repo.draggingID, pickID);
        if (isCorrect) {
            const animationUC = CorrectAnimationUC_1.LabelDropCorrectAnimationUC.get(this.appObjects);
            if (!animationUC) {
                this.warn("Unable to find LabelDropCorrectAnimationUC");
                return;
            }
            this.currentAnimation = animationUC;
            const didComplete = await animationUC.start();
            if (didComplete)
                this.onAnimationComplete();
        }
        else {
            const animationUC = IncorrectAnimationUC_1.LabelDropIncorrectAnimationUC.get(this.appObjects);
            if (!animationUC) {
                this.warn("Unable to find LabelDropIncorrectAnimationUC");
                return;
            }
            this.currentAnimation = animationUC;
            animationUC.desiredFinalPosition = this.dragStartPosition;
            const didComplete = await animationUC.start();
            if (didComplete)
                this.onAnimationComplete();
        }
    }
    onAnimationComplete() {
        this.currentAnimation = undefined;
        if (!this.repo || !this.baseApp)
            return;
        this.repo.draggingID = undefined;
        this.repo.resultIsCorrect = undefined;
        if (this.repo.getRemainingLabelDrops().length === 0) {
            this.baseApp.isReviewing = true;
        }
    }
    constructor(appObject) {
        super(appObject, DragLabelDropWorldUC.type);
        this.percentOfPickDepth = 0.95;
        this.isDragging = false;
        this.dragStartPosition = core_2.Vector3.Zero();
    }
}
//# sourceMappingURL=DragLabelDropWorldUC.js.map