import { IMAGES, Miscellaneous, SPRITE_SPECS, SpriteSpec, Sprites, } from "../config"; import { Entity, EntityNames } from "."; import { BoundingBox, ComponentNames, Grid, Highlight, Interactable, LambdaTerm, Pushable, Sprite, } from "../components"; import { Coord2D } from "../interfaces"; import { openModal, closeModal } from "../utils"; export class FunctionBox extends Entity { private static spriteSpec: SpriteSpec = SPRITE_SPECS.get( Sprites.FUNCTION_BOX, ) as SpriteSpec; constructor(gridPosition: Coord2D, code: string) { super(EntityNames.FunctionBox); this.addComponent( new BoundingBox( { x: 0, y: 0, }, { width: FunctionBox.spriteSpec.width, height: FunctionBox.spriteSpec.height, }, 0, ), ); this.addComponent(new Pushable()); this.addComponent(new Grid(gridPosition)); this.addComponent( new Sprite( IMAGES.get(FunctionBox.spriteSpec.sheet)!, { x: 0, y: 0 }, { width: FunctionBox.spriteSpec.width, height: FunctionBox.spriteSpec.height, }, FunctionBox.spriteSpec.msPerFrame, FunctionBox.spriteSpec.frames, ), ); this.addComponent(new LambdaTerm(code)); this.addComponent(makeLambdaTermHighlightComponent(this)); } } export const makeLambdaTermHighlightComponent = (entity: Entity) => { const onUnhighlight = () => { closeModal(); entity.removeComponent(ComponentNames.Interactable); }; const onHighlight = () => { let modalOpen = false; const interaction = () => { if (modalOpen) { modalOpen = false; closeModal(); return; } const code = entity.getComponent( ComponentNames.LambdaTerm, )!.code; openModal( `

${code}


`, ); modalOpen = true; document.getElementById("close")!.addEventListener("click", () => { closeModal(); document.getElementById(Miscellaneous.CANVAS_ID)!.focus(); }); }; entity.addComponent(new Interactable(interaction)); }; return new Highlight(onHighlight, onUnhighlight); };