package com.github.czyzby.lml.vis.parser.impl.tag;

import com.badlogic.gdx.scenes.scene2d.Actor;
import com.github.czyzby.lml.parser.LmlParser;
import com.github.czyzby.lml.parser.impl.tag.AbstractActorLmlTag;
import com.github.czyzby.lml.parser.tag.LmlActorBuilder;
import com.github.czyzby.lml.parser.tag.LmlTag;
import com.kotcrab.vis.ui.widget.MenuItem;
import com.kotcrab.vis.ui.widget.PopupMenu;
import com.kotcrab.vis.ui.widget.Separator;

/** Handles {@link PopupMenu} actors. Can be attached only to {@link MenuItemLmlTag}s as submenus. Mapped to
 * "popupMenu", "subMenu".
 *
 * @author MJ */
public class MenuPopupLmlTag extends AbstractActorLmlTag { // Name is inverted to keep the menu tags "family" together.
    public MenuPopupLmlTag(final LmlParser parser, final LmlTag parentTag, final String rawTagData) {
        super(parser, parentTag, rawTagData);
    }

    @Override
    protected Actor getNewInstanceOfActor(final LmlActorBuilder builder) {
        return new PopupMenu(builder.getStyleName());
    }

    @Override
    protected void handlePlainTextLine(final String plainTextLine) {
        addMenuItem(new MenuItem(getParser().parseString(plainTextLine, getActor())));
    }

    @Override
    protected void handleValidChild(final LmlTag childTag) {
        if (childTag.getActor() instanceof MenuItem) {
            addMenuItem((MenuItem) childTag.getActor());
        } else if (childTag.getActor() instanceof Separator) {
            addSeparator((Separator) childTag.getActor());
        } else {
            getParser().throwErrorIfStrict("Menus can handle only menu item and separator children. Found child tag: "
                    + childTag.getTagName() + " with actor: " + childTag.getActor());
        }
    }

    /** @param menuItem will be added to the menu. Cannot be null. */
    protected void addMenuItem(final MenuItem menuItem) {
        getPopupMenu().addItem(menuItem);
    }

    /** @param separator will be added to the menu. Should not be null. */
    protected void addSeparator(final Separator separator) {
        // This is basically a copy of #addSeparator() method in PopupMenu:
        getPopupMenu().add(separator).padTop(2).padBottom(2).fill().expand().row();
    }

    /** @return casted actor. */
    protected PopupMenu getPopupMenu() {
        return (PopupMenu) getActor();
    }

    @Override
    public boolean isAttachable() {
        return true;
    }

    @Override
    public void attachTo(final LmlTag tag) {
        if (tag.getActor() instanceof MenuItem) {
            ((MenuItem) tag.getActor()).setSubMenu(getPopupMenu());
        } else {
            // Technically, these menus could be attached to any widget with on-click listener, but let's leave that for
            // now - this would require a custom listener + possibly a way to modify it.
            getParser().throwError(
                    "Popup menus can currently be attached only to MenuItems as sub-menus. Popup menu was a child of: "
                            + tag.getTagName());
        }
    }
}
