import { __decorate, __metadata } from "tslib";
import { jsx as _jsx } from "react/jsx-runtime";
import Button from "@material-ui/core/Button";
import { AutoBind } from "../Common/AutoBind";
import { FlowStepSequence } from "./Structure/FlowStepSequence";
import { FlowStepRegistration } from "./Utilities/RegisterFlowStep";
import { BaseFlowStep } from "./Steps/BaseFlowStep";
import { StateManager } from "../CommonUI/StateManagement/StateManager";
import { DataUtilities } from "../Common/DataUtilities";
import { FlowConstants } from "./CommonUI/FlowConstants";
import { CandidateSequence } from "./Structure/CandidateSequence";
import { FlowStepOutputInstructionType } from "./Structure/FlowStepOutputInstructions";
import { HTMLShapeGeometry, HTMLUtilities } from "../CommonUI/HTMLUtilities";
import { ReactRenderHook } from "../CommonUI/ReactRenderHook";
import { XDataDefinition } from "../Common/Data/XDataDefinition";
import { SequenceDisplayBehavior } from "./Structure/DisplayBehavior/SequenceDisplayBehavior";
import { DiagramDisplayBehavior } from "./Structure/DisplayBehavior/DiagramDisplayBehavior";
import { HorizontalDisplayBehavior } from "./Structure/DisplayBehavior/HorizontalDisplayBehavior";
import { PositionData } from "./DesignerUI/FlowEditContext.PositionData";
import { FlowViewMode } from "./DesignerUI/FlowViewMode";
import { FlowBuilderPage } from "./DesignerUI/FlowBuilderPage";
export class FlowEditContext {
    constructor(flowEditor) {
        this.flowStartDataDefinition = new XDataDefinition();
        this.mode = FlowBuilderPage.Flow;
        this._designerScrollTop = 0;
        this._draggingControl = null;
        this.candidateSequences = [];
        this._dragOverSequenceId = undefined;
        this._contextControl = null;
        this.isShowEditor = false;
        this._selectedStepStrategy = null;
        this._selectedSequenceStrategy = null;
        this._isShowDescription = false;
        this._isShowErrorBranch = false;
        this._isCollapsed = false;
        this._selectedSequenceForError = null;
        this._viewMode = FlowViewMode.NORMAL;
        // for stack color change only on diagram mode.
        this._selectedForColor = undefined;
        // showing connections for error or end
        this._showErrorOrEndConnections = null;
        this.flowEditor = flowEditor;
    }
    get designerScrollTop() {
        return this._designerScrollTop;
    }
    set designerScrollTop(top) {
        this._designerScrollTop = top;
        StateManager.propertyChanged(this, "designerScrollTop");
    }
    get draggingControl() {
        return this._draggingControl;
    }
    set draggingControl(con) {
        this._draggingControl = con;
        StateManager.propertyChanged(this, "draggingControl");
    }
    get displayBehavior() {
        switch (this._viewMode) {
            case FlowViewMode.NORMAL:
                return new SequenceDisplayBehavior(this, this.flow);
            case FlowViewMode.DIAGRAM:
                return new DiagramDisplayBehavior(this, this.flow);
            default:
                return new HorizontalDisplayBehavior(this, this.flow);
        }
    }
    // ------------------------
    // handling flow structure changes
    // ------------------------
    onViewModeChanged() {
        this.refreshSequences();
        this.delayPosition();
    }
    onDeleteConnection() {
        this.refreshSequences();
        this.delayPosition();
    }
    onContextInitialized() {
        this.delayPosition(true);
    }
    onClearSelectionInContext() {
        this.delayPosition();
    }
    onSequenceBeingDragged(sequence, x, y) {
        this.delayPosition();
    }
    onSequenceDragEnding(sequence, x, y) {
        this.delayPosition(true);
    }
    onStepAdded(sequence, step) {
        // if sequence is collapsed, set it expanded and select added step.
        if (sequence instanceof FlowStepSequence && this.displayBehavior.isCollapsed(sequence)) {
            this.displayBehavior.setIsCollapsed(sequence, false);
            this.setSelection(step);
        }
        this.delayPosition();
        this.refreshSequence(sequence);
    }
    onStepRemoved(sequence, step) {
        this.delayPosition();
        this.refreshSequence(sequence);
    }
    onStepMoved(fromSequence, toSequence, step, index) {
        // if to sequence is collapsed, set it expanded and select added step.
        if (toSequence instanceof FlowStepSequence && this.displayBehavior.isCollapsed(toSequence)) {
            this.displayBehavior.setIsCollapsed(toSequence, false);
            this.setSelection(step);
        }
        this.delayPosition();
        this.refreshSequence(fromSequence);
        this.refreshSequence(toSequence);
    }
    onStepMovedInSequence(fromSequence, step, newIndex) {
        this.delayPosition();
    }
    onStepEdit(sequence, step) {
        this.delayPosition();
    }
    onStepPathEdit(sequence, step, path) {
        this.delayPosition();
    }
    onSequencesCombined(sequence, combineTo) {
        this.delayPosition();
        this.refreshSequence(sequence);
    }
    onSequenceAdded(sequence) {
        this.delayPosition(true);
        this.refreshSequence(sequence);
    }
    onSequenceRemoved(sequence) {
        this.delayPosition(true);
        this.refreshSequence(sequence);
    }
    onSequenceUpdate(sequence) {
        this.delayPosition(true);
        this.refreshSequence(sequence);
    }
    onSequenceExpanded(sequence) {
        this.delayPosition();
        this.refreshLines();
    }
    onSequenceCollapsed(sequence) {
        this.delayPosition();
        this.refreshLines();
    }
    onSequenceConnected(sequence) {
        this.delayPosition();
        this.refreshLines();
        this.refreshSequence(sequence);
    }
    delayPosition(alwaysRefresh = false) {
        ReactRenderHook.registerCallback("position", () => {
            if (this.positionCandidateSequences(true)) {
                this.refreshSequences();
            }
            if (alwaysRefresh)
                this.refreshSequences();
        });
    }
    // ------------------------
    // end - handling flow structure changes
    // ------------------------
    // ------------------------
    // force refresh
    // ------------------------
    refreshSequences() {
        StateManager.propertyChanged(this, "candidateSequences");
        StateManager.propertyChanged(this.flow, "sequences");
        // it calls refresh lines
        this.refreshLines();
    }
    refreshLines() {
        StateManager.propertyChanged(this, "connections");
    }
    refreshSequence(sequence) {
        //        Scheduler.getScheduler('ui', 100).addToSchedule('refreshSeq', () => {
        StateManager.propertyChanged(sequence, "steps");
        //        });
    }
    // ------------------------
    // end - force refresh
    // ------------------------
    getCandidateSequences() {
        return this.candidateSequences;
    }
    findCandidateSequence(id) {
        for (let c of this.candidateSequences) {
            if (c._id === id)
                return c;
        }
        return null;
    }
    getCandidateOrRealSequence(id) {
        for (let cs of this.candidateSequences) {
            if (cs._id === id)
                return cs;
        }
        for (let rs of [...this.flow.sequences, this.flow.endSequence, this.flow.errorSequence]) {
            if (rs._id === id)
                return rs;
        }
        return undefined;
    }
    getSequenceByXY(x, y) {
        for (let s of [...this.flow.sequences, this.flow.endSequence, this.flow.errorSequence]) {
            // if (x > s.x && x < s.x + s.width && y > s.y && y < s.y + s.height)
            //     return s;
            let sequenceShape = HTMLUtilities.getGeometry(s._id);
            if (sequenceShape) {
                if (x > s.x && x < s.x + sequenceShape.width && y > s.y && y < s.y + sequenceShape.height)
                    return s;
            }
        }
        return null;
    }
    purgeCandidateSequences() {
        this.syncCandidates();
        this.positionCandidateSequences(false);
    }
    syncCandidates() {
        let sequenceIds = this.flow.sequences.map((s) => s._id);
        let wasChanged = false;
        // remove the candidate that has same id with sequence.
        this.candidateSequences = this.candidateSequences.filter((c) => {
            if (sequenceIds.indexOf(c._id) < 0) {
                let instruction = Reflect.get(c, "instruction");
                if (instruction) {
                    if (instruction.connectedSequenceId !== c._id) {
                        wasChanged = true;
                        return false;
                    }
                    if (!instruction.stepId) {
                        wasChanged = true;
                        // path declares no step
                        return false;
                    }
                    let step = this.flow.find(instruction.stepId);
                    // step still exists
                    if (!step) {
                        wasChanged = true;
                        return false;
                    }
                    // candidate declares no path name
                    if (!instruction.pathName || instruction.pathName === "") {
                        wasChanged = true;
                        return false;
                    }
                    // is outcome the same
                    if (!step.isCurrentOutcome(instruction.pathName)) {
                        wasChanged = true;
                        return false;
                    }
                    // its not set to branch
                    if (instruction.strategy !== FlowStepOutputInstructionType.BRANCH) {
                        wasChanged = true;
                        return false;
                    }
                    return true;
                }
                else {
                    // this is a valid one
                    return true;
                }
            }
            else {
                wasChanged = true;
                return false;
            }
        });
        // add missing sequences
        for (let seq of this.flow.sequences) {
            for (let step of this.displayBehavior.getSequenceStepsForPaths(seq)) {
                let paths = this.displayBehavior.getPathsForStep(step);
                if (paths && paths.length > 0) {
                    for (let inst of paths) {
                        if (inst.strategy === FlowStepOutputInstructionType.BRANCH && inst.connectedSequenceId) {
                            if (!this.getCandidateOrRealSequence(inst.connectedSequenceId)) {
                                // its missing, we need to add
                                let cs = new CandidateSequence(inst);
                                cs._id = inst.connectedSequenceId;
                                this.candidateSequences.push(cs);
                                // mark as changed
                                wasChanged = true;
                            }
                        }
                    }
                }
            }
        }
        return wasChanged;
    }
    positionCandidateSequences(requirePurge = true) {
        let wasRepositioned = false;
        if (requirePurge) {
            wasRepositioned = this.syncCandidates();
        }
        // lookup position and set for instructions by sequence.
        for (let sequence of this.flow.sequences) {
            this.displayBehavior.setCandidateDesiredPositionForSeqeuence(sequence);
        }
        // lookup position and set for all instructions
        // for (let inst of this.flow.getAlternateOutputPaths()) {
        // set candidate desired position by view mode.
        // this.displayBehavior.setCandidateDesiredPositionForStepStrategy(inst, this.flow);
        // let pos = HTMLUtilities.getGeometry(inst.getElementId(), FlowConstants.DESIGN_SURFACE_ID);
        // if (pos) {
        //     let insty = pos.top + 18 - (candidateStyles.height / 2);
        //     let instx= pos.left + FlowConstants.PATH_CANDIDATE_SHIFT;
        //     // when it's step for sequence strategy
        //     if (inst.stepId.endsWith('_end')) {
        //         insty = insty - 20;
        //         // let seq = this.flow.findSequenceByStepId(inst.stepId)
        //         // if not collapsed, set candidate for sequence strategy to bottom of sequence
        //         // otherwise, it's set side of sequence like as other candidate for normal step pathes.
        //         // if (!this.displayBehavior.isCollapsed(seq!)) {
        //         //     // for hidden step instruction only applied when expanded;
        //         //     insty = insty + FlowConstants.SEQUENCE_STRATEGY_Y_OFFSET;
        //         //     instx = instx - FlowConstants.SEQUENCE_STRATEGY_X_OFFSET;
        //         // }
        //     }
        //   //  inst.postionHistory.push({x: instx, y: insty, from: 'poll'});
        //     inst.candidateStackY = insty;
        //     inst.candidateStackX = instx;
        // }
        // }
        let workingSet = [];
        for (let realS of this.candidateSequences) {
            let geo = HTMLUtilities.getGeometry(realS.getElementId());
            if (!geo) {
                // todo: need to get width and height from display behavior
                geo = new HTMLShapeGeometry(realS.desiredY, realS.desiredX, FlowConstants.PATH_CANDIDATE_HEIGHT, FlowConstants.PATH_CANDIDATE_WIDTH);
            }
            else {
                geo.left = realS.desiredX;
                geo.top = realS.desiredY;
            }
            geo.bottomPadding = 5;
            workingSet.push(new PositionData(geo, false, true, realS, realS.x, realS.y));
        }
        // add real sequences to this
        for (let realS of this.flow.sequences) {
            let geo = HTMLUtilities.getGeometry(realS.getElementId());
            if (!geo) {
                // todo: need to get width and height from display behavior
                geo = new HTMLShapeGeometry(realS.x, realS.y, this.displayBehavior.getSequenceMainSize(realS).width, this.displayBehavior.getSequenceMainSize(realS).height || FlowConstants.DEFAULT_STACK_HEIGHT);
            }
            geo.topPadding = FlowConstants.TITLE_AREA_HEIGHT;
            geo.bottomPadding = this.displayBehavior.getSequenceExtraSize(realS).height || 0;
            geo.rightPadding = this.displayBehavior.getSequenceExtraSize(realS).width;
            geo.top = realS.desiredY;
            geo.left = realS.desiredX;
            workingSet.push(new PositionData(geo, false, false, realS, realS.x, realS.y));
            if (geo) {
                realS.height = geo.height;
            }
        }
        for (let candS of workingSet) {
            candS.sequence.reset();
        }
        // sort working set
        workingSet = workingSet.sort((a, b) => {
            // sort real above candidates
            if (a.isCandidate !== b.isCandidate) {
                if (a.isCandidate)
                    return 1;
                else
                    return -1;
            }
            if (a.shape.top + a.shape.left > b.shape.top + b.shape.left) {
                return 1;
            }
            else {
                return -1;
            }
        });
        for (let positionThis of workingSet) {
            // find any that are in vertical range
            let consider = [];
            // console.log('positioning', positionThis)
            for (let otherPostion of workingSet) {
                if (!otherPostion.positioned)
                    continue;
                if (positionThis.inRange(otherPostion))
                    consider.push(otherPostion);
            }
            // position so its missed
            PositionData.positionOneSequence(positionThis, consider);
        }
        if (wasRepositioned)
            return true;
        for (let o of workingSet) {
            if (o.initialX !== o.sequence.x || o.initialY !== o.sequence.y) {
                return true;
            }
        }
        return false;
    }
    positionSequenceToFarRight(nonPathCandidate) {
        let farX = 0;
        for (let reals of this.flow.sequences) {
            let possibleX = reals.x + reals.width;
            if (possibleX > farX)
                farX = possibleX;
        }
        for (let cands of this.candidateSequences) {
            let possibleX = cands.x + FlowConstants.PATH_CANDIDATE_WIDTH; // replace with width of path candidates
            if (possibleX > farX)
                farX = possibleX;
        }
        nonPathCandidate.x = farX + 30;
    }
    set dragOverSequence(sequence) {
        let oldSequence = null;
        // same sequence no need to update.
        if (sequence && sequence._id === this._dragOverSequenceId)
            return;
        if (this._dragOverSequenceId) {
            oldSequence = this.flow.find(this._dragOverSequenceId);
        }
        if (sequence) {
            this._dragOverSequenceId = sequence._id;
            StateManager.propertyChanged(sequence, "dragOverSequence");
        }
        else {
            this._dragOverSequenceId = undefined;
        }
        if (oldSequence) {
            StateManager.propertyChanged(oldSequence, "dragOverSequence");
        }
    }
    get dragOverSequenceId() {
        return this._dragOverSequenceId;
    }
    canCombine(combine, withSequence) {
        // todo: fix this
        // if (combine instanceof CandidateSequence) {
        //
        //     // ui should not allow this
        //     if (step.sequence?._id === withSequence._id)
        //         return false;
        // }
        if (combine instanceof CandidateSequence) {
            let sequence = this.flow.findSequenceByStepId(combine.instruction.stepId);
            if (sequence) {
                // ui should not allow this
                if ((sequence === null || sequence === void 0 ? void 0 : sequence._id) === withSequence._id)
                    return false;
                return this.flow.canLink(sequence, withSequence);
            }
        }
        else if (combine instanceof FlowStepSequence) {
            return this.flow.canLink(combine, withSequence);
        }
        return true;
    }
    combineSequences(combine, withSequence) {
        // ui should not allow this
        if (!this.canCombine(combine, withSequence)) {
            this.notification = {
                message: "You can not link to this sequence.",
                onSuccess: () => { },
            };
            return;
        }
        if (withSequence instanceof CandidateSequence) {
            throw new Error("Can not combine / link the candidate sequences");
        }
        else if (combine instanceof CandidateSequence && combine.instruction) {
            // linking
            let step = this.flow.find(combine.instruction.stepId);
            let inst = step.findOutputInstruction(combine.instruction.pathName);
            inst.connectedSequenceId = withSequence._id;
            StateManager.changed(inst);
            // remove candidate sequence
            this.candidateSequences = this.candidateSequences.filter((c) => c._id !== combine._id);
            StateManager.propertyChanged(this, "candidateSequences");
            StateManager.propertyChanged(this, "connections");
        }
        else if (combine instanceof FlowStepSequence) {
            // combining
            for (let s of combine.steps) {
                this.flow.moveToSequence(s, combine, withSequence);
            }
            for (let seq of this.flow.sequences) {
                if (seq._id === combine._id)
                    continue;
                for (let s of seq.steps) {
                    for (let ins of s.getOutcomeInstructions()) {
                        if (ins.connectedSequenceId === combine._id &&
                            ins.strategy === FlowStepOutputInstructionType.BRANCH) {
                            ins.connectedSequenceId = withSequence._id;
                        }
                    }
                }
            }
            // delete combine
            let idx = this.flow.sequences.indexOf(combine);
            this.deleteSequence(idx);
        }
        // check, second sequence MUST be a FlowStepSequence, not a CanidateSequence
        // if combine is FlowStepSequence AND has steps, copy those steps to withSquence
        // look through all steps to see if the combine ID is used, if so, change it to the withSequence.id
        // delete combine
        this.onSequencesCombined(combine, withSequence);
    }
    cloneFlowElement(s) {
        let val;
        if (s instanceof FlowStepSequence) {
            val = new FlowStepSequence();
            DataUtilities.spreadDataWithoutFunction(val, DataUtilities.clone(s), [
                "_id",
                "_steps",
                "_hiddenStep",
                "_strategy",
            ]);
            for (let step of s.steps) {
                val.addStep(this.cloneFlowElement(step));
            }
            val.strategy = this.displayBehavior.getInitialSequenceStrategy();
            // copying the sequence strategy.
            // val.strategy = s.strategy;
            // let fromInst = s.hiddenStep.getOutcomeInstructions()[0];
            // let toInst = val.hiddenStep.getOutcomeInstructions()[0]
            // toInst.errorMessage = fromInst.errorMessage;
            // if (s.strategy === FlowStepSequenceStrategy.LINK) {
            //     if (fromInst.connectedSequenceId) {
            //         let s = this.getCandidateOrRealSequence(fromInst.connectedSequenceId);
            //         if (s instanceof FlowStepSequence) {
            //             toInst.connectedSequenceId = s._id;
            //         } else {
            //             toInst.connectedSequenceId = DataUtilities.generateUniqueId();
            //         }
            //     }
            // }
        }
        else if (s instanceof BaseFlowStep) {
            let registeredControl = FlowStepRegistration.getByName(s.type);
            val = registeredControl.create();
            DataUtilities.spreadDataWithoutFunction(val, DataUtilities.clone(s), [
                "_id",
                "_nonDefaultOutputInstructions",
            ]);
            let paths = s.getOutcomes();
            if (paths) {
                for (let i of paths) {
                    val.findOutputInstruction(i.name);
                }
            }
        }
        else {
            throw new Error("Unknown element type");
        }
        return val;
    }
    onCopy(selectedId) {
        let elem = this._lastSelectionElement;
        if (selectedId) {
            elem = this.flow.find(selectedId);
            this.contextControl = null;
        }
        if (!elem)
            return;
        if (elem instanceof FlowStepSequence && !elem.canCopy) {
            this.notification = {
                message: "You can not copy this sequence",
                onSuccess: () => { },
            };
        }
        else {
            this.clipboardElement = this.cloneFlowElement(elem);
        }
    }
    onCut(selectedId) {
        let elem = this._lastSelectionElement;
        if (selectedId) {
            elem = this.flow.find(selectedId);
            this.contextControl = null;
        }
        if (!elem)
            return;
        if (elem instanceof FlowStepSequence) {
            if (!elem.canCopy) {
                this.notification = {
                    message: "You can not copy this sequence",
                    onSuccess: () => { },
                };
                return;
            }
            let idx = this.flow.sequences.indexOf(elem);
            if (idx > 0) {
                if (elem.steps.length > 0) {
                    this.notification = {
                        message: "This sequence has the steps. Do you want to cut it really?",
                        onSuccess: () => {
                            this.clipboardElement = this.cloneFlowElement(elem);
                            this.deleteSequence(idx);
                        },
                        onCancel: () => { },
                    };
                }
                else {
                    this.deleteSequence(idx);
                }
            }
            else {
                this.notification = {
                    message: "Primary Stack can not be cut. But it's copied to clipboarded",
                    onSuccess: () => { },
                };
            }
        }
        else {
            this.clipboardElement = this.cloneFlowElement(elem);
            this.flow.remove(elem);
        }
    }
    deleteSequence(idx) {
        this.flow.deleteSequenceByIndex(idx);
        StateManager.propertyChanged(this.flow, "sequences");
        this.purgeCandidateSequences();
    }
    onDelete(selectedId) {
        let elem = this._lastSelectionElement;
        if (selectedId) {
            elem = this.flow.find(selectedId);
            this.contextControl = null;
        }
        if (!elem)
            return;
        if (elem instanceof FlowStepSequence) {
            if (!elem.canDelete) {
                this.notification = {
                    message: "You can not delete this sequence",
                    onSuccess: () => { },
                };
                return;
            }
            let idx = this.flow.sequences.indexOf(elem);
            if (idx > 0) {
                if (elem.steps.length > 0) {
                    this.notification = {
                        message: "This sequence has the steps. If you delete this, you will lost all data. it's okay?",
                        onSuccess: () => {
                            this.deleteSequence(idx);
                        },
                        onCancel: () => { },
                    };
                }
                else {
                    this.deleteSequence(idx);
                }
            }
            else {
                this.notification = {
                    message: "Primary Stack can not be deleted.",
                    onSuccess: () => { },
                };
            }
        }
        else {
            this.flow.remove(elem);
            this.purgeCandidateSequences();
        }
    }
    onPaste() {
        if (!this.clipboardElement || (!this.selectionElement && !(this.clipboardElement instanceof FlowStepSequence)))
            return;
        if (this.clipboardElement instanceof FlowStepSequence) {
            let newSeq = this.cloneFlowElement(this.clipboardElement);
            newSeq._id = DataUtilities.generateUniqueId();
            newSeq.desiredY += 20;
            newSeq.desiredX += 20;
            newSeq.x += 20;
            newSeq.y += 20;
            this.flow.addSequence(newSeq);
            this.onSequenceAdded(newSeq);
        }
        else if (!(this.clipboardElement instanceof FlowStepSequence) &&
            !(this.selectionElement instanceof FlowStepSequence) &&
            this.selectionElement) {
            for (let s of this.flow.sequences) {
                let idx = s.steps.indexOf(this.selectionElement);
                if (idx >= 0) {
                    let elem = this.cloneFlowElement(this.clipboardElement);
                    elem._id = DataUtilities.generateUniqueId();
                    this.flow.add(elem, s._id, idx);
                    this.onStepAdded(s, elem);
                    break;
                }
            }
        }
    }
    get flow() {
        return this.flowEditor.flow;
    }
    get selection() {
        var _a;
        return (_a = this._selectionElement) === null || _a === void 0 ? void 0 : _a._id;
    }
    get selectionElement() {
        return this._selectionElement;
    }
    get lastSelectionElement() {
        return this._lastSelectionElement;
    }
    setSelection(selection) {
        this._selectionElement = selection;
        StateManager.changed(selection);
        if (this._lastSelectionElement) {
            StateManager.changed(this._lastSelectionElement);
        }
        this._lastSelectionElement = selection;
        StateManager.propertyChanged(this, "selectionElement");
        this.showEditLayer();
    }
    clearSelection() {
        this._selectionElement = undefined;
        StateManager.propertyChanged(this, "selectionElement");
        this.hideEditLayer();
    }
    get clipboardElement() {
        return this._clipboardElement;
    }
    set clipboardElement(elem) {
        this._clipboardElement = elem;
        StateManager.propertyChanged(this, "clipboardElement");
    }
    get contextControl() {
        return this._contextControl;
    }
    set contextControl(control) {
        this._contextControl = control;
        StateManager.propertyChanged(this, "contextControl");
    }
    set notification(n) {
        this._notification = n;
        StateManager.propertyChanged(this, "notification");
    }
    get notification() {
        return this._notification;
    }
    get draggingElemType() {
        return this._draggingElemType;
    }
    set draggingElemType(type) {
        this._draggingElemType = type;
    }
    toggleEditLayer() {
        this.isShowEditor = !this.isShowEditor;
        StateManager.propertyChanged(this, "isShowEditor");
    }
    hideEditLayer() {
        this.isShowEditor = false;
        StateManager.propertyChanged(this, "isShowEditor");
    }
    showEditLayer() {
        this.isShowEditor = true;
        StateManager.propertyChanged(this, "isShowEditor");
    }
    refresh() {
        StateManager.changed(this.flowEditor);
    }
    set selectedStepStrategy(s) {
        this._selectedStepStrategy = s;
        StateManager.propertyChanged(this, "selectedStepStrategy");
    }
    setSelectedStepStrategy(elem, step) {
        let elemGeo = HTMLUtilities.getGeometryFromElement(elem, FlowConstants.DESIGN_SURFACE_ID);
        this.selectedStepStrategy = {
            position: {
                x: (elemGeo === null || elemGeo === void 0 ? void 0 : elemGeo.left) || 0,
                y: (elemGeo === null || elemGeo === void 0 ? void 0 : elemGeo.top) || 0,
            },
            step,
        };
    }
    get selectedStepStrategy() {
        return this._selectedStepStrategy;
    }
    set selectedSequenceStrategy(s) {
        this._selectedSequenceStrategy = s;
        StateManager.propertyChanged(this, "selectedSequenceStrategy");
    }
    setSelectedSequenceStrategy(elem, sequence) {
        let elemGeo = HTMLUtilities.getGeometryFromElement(elem, FlowConstants.DESIGN_SURFACE_ID);
        this.selectedSequenceStrategy = {
            position: {
                x: (elemGeo === null || elemGeo === void 0 ? void 0 : elemGeo.left) || 0,
                y: (elemGeo === null || elemGeo === void 0 ? void 0 : elemGeo.top) || 0,
            },
            sequence,
        };
    }
    get selectedSequenceStrategy() {
        return this._selectedSequenceStrategy;
    }
    set isShowDescription(show) {
        this._isShowDescription = show;
        this.flow.toggleShowDescription(show);
        StateManager.propertyChanged(this, "isShowDescription");
    }
    get isShowDescription() {
        return this._isShowDescription;
    }
    set isShowErrorBranch(show) {
        this._isShowErrorBranch = show;
        StateManager.propertyChanged(this, "isShowErrorBranch");
    }
    get isShowErrorBranch() {
        return this._isShowErrorBranch;
    }
    set isCollapsed(show) {
        this._isCollapsed = show;
        this.flow.toggleCollapsed(show);
        StateManager.propertyChanged(this, "isCollapsed");
    }
    get isCollapsed() {
        return this._isCollapsed;
    }
    set selectedSequenceForError(s) {
        this._selectedSequenceForError = s;
        StateManager.propertyChanged(this, "selectedSequenceForError");
    }
    setSelectedSequenceForError(elem, sequence) {
        let elemGeo = HTMLUtilities.getGeometryFromElement(elem, FlowConstants.DESIGN_SURFACE_ID);
        this.selectedSequenceForError = {
            position: {
                x: sequence.x,
                y: ((elemGeo === null || elemGeo === void 0 ? void 0 : elemGeo.top) || 0) + 15,
            },
            sequence,
        };
    }
    get selectedSequenceForError() {
        return this._selectedSequenceForError;
    }
    set viewMode(mode) {
        if (mode !== this._viewMode) {
            this.notification = {
                message: `Do you want to change to ${mode} flow style?`,
                type: "confirm",
                actions: [
                    {
                        items: [
                            {
                                renderUI: () => {
                                    return (_jsx(Button, Object.assign({ variant: "contained", color: "primary", onClick: () => {
                                            this._viewMode = mode;
                                            this.candidateSequences = [];
                                            StateManager.propertyChanged(this, "viewMode");
                                            // if primary stack is empty, then it's set with initial strategy
                                            if (this.flow.sequences[0].steps.length === 0) {
                                                this.flow.sequences[0].strategy = this.displayBehavior.getInitialSequenceStrategy();
                                            }
                                            this.onViewModeChanged();
                                            this.notification = undefined;
                                        }, "data-testid": "btn-dialog-view-change" }, { children: "Change" }), void 0));
                                },
                            },
                            {
                                renderUI: () => {
                                    return (_jsx(Button, Object.assign({ variant: "contained", onClick: () => {
                                            this.notification = undefined;
                                        }, "data-testid": "btn-dialog-cancel" }, { children: "Cancel" }), void 0));
                                },
                            },
                        ],
                    },
                ],
            };
        }
    }
    get viewMode() {
        return this._viewMode;
    }
    get selectedForColor() {
        return this._selectedForColor;
    }
    set selectedForColor(sel) {
        this._selectedForColor = sel;
        StateManager.propertyChanged(this, "selectedForColor");
    }
    setSelectedForColor(sequence, element) {
        let pos = HTMLUtilities.getGeometryFromElement(element, FlowConstants.DESIGN_SURFACE_ID);
        this.selectedForColor = {
            instance: sequence,
            position: {
                x: ((pos === null || pos === void 0 ? void 0 : pos.left) || 0) + 24,
                y: (pos === null || pos === void 0 ? void 0 : pos.top) || 0,
            },
        };
    }
    get showErrorOrEndConnections() {
        return this._showErrorOrEndConnections;
    }
    set showErrorOrEndConnections(isShow) {
        this._showErrorOrEndConnections = isShow;
        StateManager.propertyChanged(this, "showErrorOrEndConnections");
    }
}
__decorate([
    AutoBind,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Object)
], FlowEditContext.prototype, "cloneFlowElement", null);
__decorate([
    AutoBind,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], FlowEditContext.prototype, "onCopy", null);
__decorate([
    AutoBind,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], FlowEditContext.prototype, "onCut", null);
__decorate([
    AutoBind,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Number]),
    __metadata("design:returntype", void 0)
], FlowEditContext.prototype, "deleteSequence", null);
__decorate([
    AutoBind,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], FlowEditContext.prototype, "onDelete", null);
__decorate([
    AutoBind,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], FlowEditContext.prototype, "onPaste", null);
__decorate([
    AutoBind,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], FlowEditContext.prototype, "toggleEditLayer", null);
__decorate([
    AutoBind,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], FlowEditContext.prototype, "hideEditLayer", null);
__decorate([
    AutoBind,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], FlowEditContext.prototype, "showEditLayer", null);
__decorate([
    AutoBind,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [HTMLElement, BaseFlowStep]),
    __metadata("design:returntype", void 0)
], FlowEditContext.prototype, "setSelectedStepStrategy", null);
__decorate([
    AutoBind,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [HTMLElement, FlowStepSequence]),
    __metadata("design:returntype", void 0)
], FlowEditContext.prototype, "setSelectedSequenceStrategy", null);
__decorate([
    AutoBind,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [HTMLElement, FlowStepSequence]),
    __metadata("design:returntype", void 0)
], FlowEditContext.prototype, "setSelectedSequenceForError", null);
//# sourceMappingURL=FlowEditContext.js.map