import { html, css, LitElement, unsafeCSS, PropertyValues } from "lit";
import { LitElementWw } from "@webwriter/lit";
import {
customElement,
property,
query,
queryAssignedElements,
} from "lit/decorators.js";
//Drawflow Imports
import { DrawflowNode } from "drawflow";
import { WebWriterGamebookButton } from "../components/gamebook/gamebook-components/gamebook-button/webwriter-gamebook-button";
import { WebWriterGamebookPage } from "../components/gamebook/gamebook-components/gamebook-containers/gamebook-page/webwriter-gamebook-page";
import { WebWriterGamebookPopup } from "../components/gamebook/gamebook-components/gamebook-containers/gamebook-popup/webwriter-gamebook-popup";
import { WebWriterGamebookBranch } from "../components/gamebook/gamebook-components/gamebook-containers/gamebook-branch/webwriter-gamebook-branch";
import { WebWriterGamebookBranchButton } from "../components/gamebook/gamebook-components/gamebook-branch-button/webwriter-gamebook-branch-button";
import { provide, consume, createContext } from "@lit/context";
import {
editorState,
GamebookEditorState,
} from "./gamebook-editor-state-context";
@customElement("gamebook-container-manager")
export class GamebookContainerManager extends LitElementWw {
@queryAssignedElements({
flatten: true,
selector:
"webwriter-gamebook-page, webwriter-gamebook-popup, webwriter-gamebook-branch",
})
accessor gamebookContainers;
@query("slot") accessor slot;
@consume({ context: editorState, subscribe: true })
@property({ type: Object, attribute: true, reflect: false })
public accessor editorStore = new GamebookEditorState("Default");
static get scopedElements() {
return {
// "webwriter-gamebook-page": WebWriterGamebookPage,
// "webwriter-gamebook-popup": WebWriterGamebookPopup,
// "webwriter-gamebook-branch": WebWriterGamebookBranch,
};
}
/*
*/
constructor() {
super();
}
/*
*/
protected firstUpdated(_changedProperties: any): void {
const event = new CustomEvent("managerInitialized", {
bubbles: true,
composed: true,
});
this.dispatchEvent(event);
if (this.editorStore.selectedContainer !== undefined) {
//Extraced the drawflowNodeId from the serialized container
const value = this.editorStore.selectedContainer.attributes.find(
(attr) => attr.name === "drawflownodeid"
).value;
if (value) {
const event = new CustomEvent("containerSelectFirstUpdate", {
detail: { id: value },
bubbles: true,
composed: true,
});
this.dispatchEvent(event);
} else {
const event = new CustomEvent("containerError", {
detail: { id: value },
bubbles: true,
composed: true,
});
this.dispatchEvent(event);
}
}
}
/*
*/
render() {
return html` `;
}
/*
*/
public _deleteGamebookContainersById(drawflowNodeId: Number) {
this.gamebookContainers.forEach((container) => {
if (container.drawflowNodeId == drawflowNodeId) {
container.remove();
}
});
}
/*
*/
public _notifyContainerGotDeleted(drawflowNodeId: Number) {
const event = new CustomEvent("containerDeleted", {
detail: { id: drawflowNodeId },
bubbles: true,
composed: true,
});
this.dispatchEvent(event);
}
/*
*/
public _deleteAllGamebookContainers() {
this.gamebookContainers.forEach((container) => {
container.remove();
});
//("delete successfull", this.gamebookContainers);
}
/*
*/
public _getContainerByDrawflowNodeId(id: number) {
const container = this.gamebookContainers.find(
(container) => container.drawflowNodeId === id
);
if (!container) {
console.error(`No container found with drawflowNodeId: ${id}`);
}
return container;
}
/*
*/
public _renameContainer(id: string, title: string) {
const container = this.gamebookContainers.find(
(container) => container.getAttribute("drawflowNodeId") == id
);
(container as WebWriterGamebookPage).pageTitle = title;
}
/*
*/
public _showGamebookContainerById(nodeId: number) {
let isContainerShown = false; // Flag to track if any container is shown
this.gamebookContainers.forEach((container) => {
if (container.drawflowNodeId == nodeId) {
container.show();
isContainerShown = true; // Set flag to true when a container is shown
} else {
container.hide();
}
});
if (!isContainerShown) {
console.error(`No container found with drawflowNodeId: ${nodeId}`);
}
}
/*
*/
public _hideAllGamebookContainers() {
this.gamebookContainers.forEach((container) => {
container.hide();
});
}
/*
*/
public addConnectionButtonToContainer(
outputNode: DrawflowNode,
inputNode: DrawflowNode,
output_class: string,
input_class: string
) {
const container = this.gamebookContainers.find(
(container) => container.getAttribute("drawflowNodeId") == outputNode.id
);
const connButton = document.createElement(
"webwriter-gamebook-button"
) as WebWriterGamebookButton;
connButton.setAttribute("name", inputNode.data.title);
connButton.setAttribute("dataTargetId", inputNode.id.toString());
// Ensure uniqueness by adding a unique identifier
connButton.setAttribute(
"identifier",
`${outputNode.id}-${output_class}-${inputNode.id}-${input_class}`
);
container.appendChild(connButton);
}
/*
*/
public addSmartBranchButtonToContainer(
outputNode: DrawflowNode,
inputNode: DrawflowNode,
output_class: string,
input_class: string
) {
const container = this.gamebookContainers.find(
(container) => container.getAttribute("drawflowNodeId") == outputNode.id
);
const branchButton = document.createElement(
"webwriter-gamebook-branch-button"
) as WebWriterGamebookBranchButton;
branchButton.setAttribute("name", inputNode.data.title);
branchButton.setAttribute("dataTargetId", inputNode.id.toString());
// Ensure uniqueness by adding a unique identifier
branchButton.setAttribute(
"identifier",
`${outputNode.id}-${output_class}-${inputNode.id}-${input_class}`
);
container.appendChild(branchButton);
container.branchesOff = inputNode.id;
const branchContainer = this.gamebookContainers.find(
(container) => container.getAttribute("drawflowNodeId") == inputNode.id
);
branchContainer.incomingContainerId = outputNode.id;
}
/*
*/
public removeButtonFromContainer(
outputId: string,
inputId: string,
outputClass: string,
inputClass: string
) {
const container = this.gamebookContainers.find(
(container) => container.getAttribute("drawflowNodeId") == outputId
);
const button = Array.from(
container.buttons as NodeListOf
).find((button) => {
return (
(button as any).identifier ===
`${outputId}-${outputClass}-${inputId}-${inputClass}`
);
});
if (button) {
button.setAttribute("identifier", "x");
button.remove();
if (button instanceof WebWriterGamebookBranchButton) {
container.branchesOff = -1;
const branchContainer = this.gamebookContainers.find(
(container) => container.getAttribute("drawflowNodeId") == inputId
);
branchContainer.incomingContainerId = -1;
branchContainer.clearRules();
}
}
}
/*
*/
public updateButtonIdsAfterOutputRemove(
containerId: string,
removed_output_class: string
) {
const container = this.gamebookContainers.find(
(container) => container.getAttribute("drawflowNodeId") == containerId
);
// Extract the number from the output_class parameter
const removedOutputClassNumber = parseInt(
removed_output_class.split("_")[1],
10
);
// Iterate over each linkButton to update its identifier
if (container.buttons) {
container.buttons.forEach((button) => {
const [output_id, output_class, input_id] =
button.identifier.split("-");
const buttonOutputClassNumber = parseInt(
output_class.split("_")[1],
10
);
// Check if the linkButton should be updated
if (buttonOutputClassNumber > removedOutputClassNumber) {
// Generate the new identifier with incremented output_class
const newIdentifier = `${output_id}-output_${
buttonOutputClassNumber - 1
}-${input_id}-input_1`;
// Update the identifier
button.setAttribute("identifier", newIdentifier);
}
});
}
}
/*
*/
public highlightButtonInContainer(containerId, identifier) {
const container = this.gamebookContainers.find(
(container) => container.getAttribute("drawflowNodeId") == containerId
);
if (
container instanceof WebWriterGamebookPage ||
container instanceof WebWriterGamebookPopup
) {
const connButton = container.buttons.find(
(button) => button.identifier === identifier
);
if (connButton) {
if (!connButton.classList.contains("ww-selected")) {
connButton.classList.add("highlighted");
}
}
}
}
/*
*/
public unhighlightButtonInContainer(containerId, identifier) {
const container = this.gamebookContainers.find(
(container) => container.getAttribute("drawflowNodeId") == containerId
);
if (
container instanceof WebWriterGamebookPage ||
container instanceof WebWriterGamebookPopup
) {
const connButton = container.buttons.find(
(button) => button.identifier === identifier
);
if (connButton) {
connButton.classList.remove("highlighted");
}
}
}
/*
*/
public selectButtonInContainer(containerId, identifier) {
const container = this.gamebookContainers.find(
(container) => container.getAttribute("drawflowNodeId") == containerId
);
const connButton = container.buttons.find(
(button) => button.identifier === identifier
);
if (connButton) {
connButton.focus();
}
}
/*
*/
public createContainerFromNode(node) {
switch (node.class) {
case "page":
case "origin":
return this._createContainerElement(
node,
"webwriter-gamebook-page",
node.class == "origin" ? "1" : "0"
);
break;
case "popup":
return this._createContainerElement(node, "webwriter-gamebook-popup");
break;
case "branch":
return this._createContainerElement(node, "webwriter-gamebook-branch");
break;
}
}
/*
*/
private _createContainerElement(
node: DrawflowNode,
tagName: string,
originPage?: string
) {
const container = document.createElement(tagName) as HTMLElement;
container.setAttribute("drawflowNodeId", node.id.toString());
container.setAttribute("pageTitle", node.data.title);
if (originPage) {
container.setAttribute("originPage", originPage);
}
(container as any).hide();
return container;
}
/*
*/
public importContainers(template: Array