"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LabelDropRepo = exports.LabelDropDragMode = void 0;
exports.makeLabelDropRepo = makeLabelDropRepo;
const core_1 = require("@vived/core");
const Transform3D_1 = require("../../Transform3D");
const LabelDropItemEntity_1 = require("./LabelDropItemEntity");
var LabelDropDragMode;
(function (LabelDropDragMode) {
    LabelDropDragMode["SCREEN"] = "SCREEN";
    LabelDropDragMode["WORLD"] = "WORLD";
})(LabelDropDragMode || (exports.LabelDropDragMode = LabelDropDragMode = {}));
class LabelDropRepo extends core_1.AppObjectEntityRepo {
    constructor() {
        super(...arguments);
        this.challengeID = "LABEL_DROP";
        this.name = "Label Drop";
        this.helpHeading = "Label Drop Challenge Help";
        this.consumerHelpText = "You are being challenged to drop these labels on the correct objects in the scene.";
        this.authorHelpText = "Challenge the user to drop labels onto specific objects.";
    }
    static get(appObjects) {
        return (0, core_1.getSingletonComponent)(LabelDropRepo.type, appObjects);
    }
}
exports.LabelDropRepo = LabelDropRepo;
LabelDropRepo.type = "LabelDropRepo";
LabelDropRepo.LABEL_DROP_ANSWER_REQUIRED = "At least one label drop answer item is required";
function makeLabelDropRepo(appObj) {
    Transform3D_1.Transform3D.addIfMissing(appObj);
    return new LabelDropRepoImp(appObj);
}
class LabelDropRepoImp extends LabelDropRepo {
    get validationMessage() {
        if (this.getAll().length === 0) {
            return LabelDropRepo.LABEL_DROP_ANSWER_REQUIRED;
        }
        else {
            return null;
        }
    }
    deleteItem(id) {
        const item = this.getForAppObject(id);
        if (!item)
            return;
        this.removeForAppObject(id);
        item.appObject.dispose();
    }
    deleteAllItems() {
        const items = this.getAll();
        items.forEach((item) => {
            this.removeForAppObject(item.id);
            item.appObject.dispose();
        });
    }
    get editingID() {
        return this._editingID;
    }
    set editingID(val) {
        if (val === this._editingID)
            return;
        if (val !== undefined && this.getForAppObject(val) === undefined)
            return;
        this._editingID = val;
        this.notifyOnChange();
    }
    get isEditingNewAnswer() {
        return this._isEditingNewAnswer;
    }
    set isEditingNewAnswer(val) {
        if (val === this._isEditingNewAnswer)
            return;
        this._isEditingNewAnswer = val;
        this.notifyOnChange();
    }
    get draggingID() {
        return this._draggingID;
    }
    set draggingID(val) {
        if (val === this._draggingID)
            return;
        this._draggingID = val;
        this.notifyOnChange();
    }
    get screenPosition() {
        return this._screenPosition;
    }
    set screenPosition(val) {
        if (core_1.Vector2.Equal(val, this._screenPosition))
            return;
        this._screenPosition = val;
        this.notifyOnChange();
    }
    get dragMode() {
        return this._dragMode;
    }
    set dragMode(val) {
        if (val === this._dragMode)
            return;
        this._dragMode = val;
        this.notifyOnChange();
    }
    get resultIsCorrect() {
        return this._resultIsCorrect;
    }
    set resultIsCorrect(val) {
        if (val === this._resultIsCorrect)
            return;
        this._resultIsCorrect = val;
        this.notifyOnChange();
    }
    get dragAlpha() {
        return this._dragAlpha;
    }
    set dragAlpha(val) {
        let valToUse = val;
        if (val < 0) {
            valToUse = 0;
        }
        else if (val > 1) {
            valToUse = 1;
        }
        if (valToUse === this._dragAlpha)
            return;
        this._dragAlpha = valToUse;
        this.notifyOnChange();
    }
    addLabelDropSubmissionObserver(observer) {
        this._submissionObserverList.add(observer);
    }
    removeLabelDropSubmissionObserver(observer) {
        this._submissionObserverList.remove(observer);
    }
    constructor(appObj) {
        super(appObj, LabelDropRepo.type);
        this._submissionObserverList = new core_1.ObserverList();
        this.labelDropItemFactory = (id) => {
            const ao = this.appObjects.getOrCreate(id);
            return new LabelDropItemEntity_1.LabelDropItemEntity(ao);
        };
        this.makeLabelDropItem = (id) => {
            const idToUse = id ?? (0, core_1.generateUniqueID)();
            const dropItem = this.labelDropItemFactory(idToUse);
            this.add(dropItem);
            return dropItem;
        };
        this.getRemainingLabelDrops = () => {
            const remainingList = [];
            this.getAll().forEach((item) => {
                if (item.answeredCorrectly !== true) {
                    remainingList.push(item.id);
                }
            });
            return remainingList;
        };
        this.submitLabelDrop = (labelDropID, hitAppObjectID) => {
            const item = this.getForAppObject(labelDropID);
            if (!item) {
                this.warn("Unable to find label drop item");
                return false;
            }
            const isCorrect = item.submitLabelDrop(hitAppObjectID);
            const result = {
                id: labelDropID,
                isCorrect,
            };
            this._submissionObserverList.notify(result);
            this.resultIsCorrect = isCorrect;
            this.notifyOnChange();
            return isCorrect;
        };
        this.reset = () => {
            this.getAll().forEach((item) => {
                item.reset();
            });
            this.notifyOnChange();
        };
        this._editingID = undefined;
        this._isEditingNewAnswer = false;
        this._draggingID = undefined;
        this._screenPosition = core_1.Vector2.Zero();
        this._dragMode = LabelDropDragMode.SCREEN;
        this._resultIsCorrect = undefined;
        this._dragAlpha = 0;
        this.dragLabelTransform = Transform3D_1.Transform3D.addIfMissing(appObj);
        const dragHelperTransformAO = appObj.appObjectRepo.getOrCreate("LabelDropDragHelper");
        this.dragHelperTransform = Transform3D_1.Transform3D.addIfMissing(dragHelperTransformAO);
        this.appObjects.registerSingleton(this);
    }
}
//# sourceMappingURL=LabelDropRepo.js.map