sourceafQuickFlux::EntityMeta.fan

using gfx::Image
using fwt::Menu
using fwt::MenuItem
using fwt::ToolBar
using fwt::Tree
using flux::CommandId
using flux::Frame
using afIoc::Inject
using afIoc::Registry

class EntityMeta {
    
    @Inject protected Registry      registry
    @Inject protected Frame         frame
    @Inject internal EntityMetaSrc  entityMetaSrc
    @Inject internal IconSrc        iconSrc
    
    Entity entity
    Bool visible    := true
    Str:Obj data    := [:]
    
    protected Entity:EntityMeta metaMap
    
    new make(Entity entity, Entity:EntityMeta metaMap, |This| inject) {
        inject(this)
        this.entity = entity
        this.metaMap = metaMap
    }
    
    virtual Str text() { entity.displayName }

    virtual Image? icon() { iconSrc[entity.displayIcon] }
    
    virtual once Entity? parent() { null }

    virtual once EntityMeta? parentNode() { toMeta(parent) }

    virtual Entity[] children() { Entity#.emptyList }

    /* - */ EntityMeta[] childrenAsNodes() {
        children.map { toMeta(it) }
    }

    virtual Menu populateMenu(Menu menu) {
        addCmd(menu, CmdEditEntity#, [entity])
        addCmd(menu, CmdDeleteEntity#, [entity])
        return menu
    }
    
    virtual ToolBar populateToolBar(ToolBar toolBar) {
        toolBar.addCommand(frame.command(CommandId.save))
        return toolBar
    }

    virtual Void action() { 
        (registry.autobuild(CmdEditEntity#, [entity]) as CmdEditEntity).invoke(null)
    }

    virtual Void expand(Tree tree) {
        if (parent != null)
            parentNode.expand(tree)
        tree.setExpanded(entity, true)
    }

    // it never fuggin works - forget it!
    virtual Void refresh(Tree tree) {
        if (parent != null)
            parentNode.refresh(tree)
        tree.refreshNode(entity)
    }

    virtual Void show(Tree tree) {
        if (parent != null)
            parentNode.show(tree)
        tree.show(entity)
    }

    protected EntityMeta? toMeta(Entity? entity) {
        if (entity == null)
            return null
        return metaMap.getOrAdd(entity) {
            entityMetaSrc.toMeta(entity, metaMap)
        }
    }
    
    protected Void addCmd(Menu menu, Type type, Obj?[] ctorArgs := Obj#.emptyList) {
        menu.add(MenuItem.makeCommand(registry.autobuild(type, ctorArgs)))
    }

}