package electrosphere.menu.ingame;

import java.util.List;

import electrosphere.engine.Globals;
import electrosphere.game.data.voxel.VoxelData;
import electrosphere.game.data.voxel.VoxelType;
import electrosphere.menu.WindowStrings;
import electrosphere.menu.WindowUtils;
import electrosphere.renderer.ui.elements.Button;
import electrosphere.renderer.ui.elements.ImagePanel;
import electrosphere.renderer.ui.elements.Label;
import electrosphere.renderer.ui.elements.TextInput;
import electrosphere.renderer.ui.elements.VirtualScrollable;
import electrosphere.renderer.ui.elements.Window;
import electrosphere.renderer.ui.elementtypes.ClickableElement.ClickEventCallback;
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaAlignment;
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaFlexDirection;
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaJustification;
import electrosphere.renderer.ui.elementtypes.KeyEventElement.KeyboardEventCallback;
import electrosphere.renderer.ui.elementtypes.NavigableElement.NavigationEventCallback;
import electrosphere.renderer.ui.events.ClickEvent;
import electrosphere.renderer.ui.events.KeyboardEvent;
import electrosphere.renderer.ui.events.NavigationEvent;

/**
 * Menu generators for terrain editing controls
 */
public class MenuGeneratorsTerrainEditing {
    
    static Window rVal;

    //text input
    static final int TEXT_INPUT_HEIGHT = 50;
    static final int TEXT_INPUT_WIDTH = 200;

    //single voxel button
    static final int VOXEL_BUTTON_WIDTH = 90;
    static final int VOXEL_BUTTON_HEIGHT = 90;
    static final int VOXEL_BUTTON_TEXTURE_DIM = 70;
    static final int MARGIN_EACH_SIDE = 5;

    //voxel selection
    static final int VOXEL_SCROLLABLE_WIDTH = VOXEL_BUTTON_WIDTH * 5;
    static final int VOXEL_SCROLLABLE_HEIGHT = VOXEL_BUTTON_HEIGHT * 5;

    //width of the side panel
    static final int WINDOW_WIDTH = VOXEL_SCROLLABLE_WIDTH;
    static final int WINDOW_HEIGHT = VOXEL_SCROLLABLE_HEIGHT + TEXT_INPUT_HEIGHT;


    /**
     * Creates the level editor side panel top view
     * @return
     */
    public static Window createVoxelTypeSelectionPanel(){
        //setup window
        rVal = new Window(Globals.renderingEngine.getOpenGLState(),0,0,WINDOW_WIDTH,WINDOW_HEIGHT,true);
        rVal.setParentAlignContent(YogaAlignment.Center);
        rVal.setParentJustifyContent(YogaJustification.Center);
        rVal.setParentAlignItem(YogaAlignment.Center);
        rVal.setAlignContent(YogaAlignment.Center);
        rVal.setAlignItems(YogaAlignment.Center);
        rVal.setJustifyContent(YogaJustification.Center);
        rVal.setFlexDirection(YogaFlexDirection.Column);

        //scrollable that contains all the voxel types
        VirtualScrollable scrollable = new VirtualScrollable(VOXEL_SCROLLABLE_WIDTH, VOXEL_SCROLLABLE_HEIGHT);
        scrollable.setFlexDirection(YogaFlexDirection.Row);
        scrollable.setAlignItems(YogaAlignment.Start);
        rVal.setOnNavigationCallback(new NavigationEventCallback() {public boolean execute(NavigationEvent event){
            WindowUtils.closeWindow(WindowStrings.LEVEL_EDTIOR_SIDE_PANEL);
            return false;
        }});

        //search input
        TextInput searchInput = TextInput.createTextInput();
        searchInput.setWidth(TEXT_INPUT_WIDTH);
        searchInput.setMinWidth(TEXT_INPUT_WIDTH);
        searchInput.setMinHeight(20);
        searchInput.setOnPress(new KeyboardEventCallback() {public boolean execute(KeyboardEvent event){
            boolean rVal = searchInput.defaultKeyHandling(event);
            fillInVoxelSelectors(scrollable, searchInput.getText());
            return rVal;
        }});
        rVal.addChild(searchInput);


        //attach scrollable after search input for organzation purposes
        rVal.addChild(scrollable);

        //final step
        fillInVoxelSelectors(scrollable, searchInput.getText());
        

        rVal.applyYoga(0,0);

        return rVal;
    }

    /**
     * Fills in the voxels to display based on the contents of the search string
     * @param scrollable the scrollable to drop selection buttons in to
     * @param searchString the string to search based on
     */
    static void fillInVoxelSelectors(VirtualScrollable scrollable, String searchString){
        scrollable.clearChildren();
        VoxelData voxelData = Globals.gameConfigCurrent.getVoxelData();
        List<VoxelType> matchingVoxels = voxelData.getTypes().stream().filter((type)->type.getName().toLowerCase().contains(searchString.toLowerCase())).toList();
        //generate voxel buttons
        for(VoxelType type : matchingVoxels){
            Button newButton = new Button();
            newButton.setAlignItems(YogaAlignment.Center);
            //dimensions
            newButton.setWidth(VOXEL_BUTTON_WIDTH);
            newButton.setMinWidth(VOXEL_BUTTON_WIDTH);
            newButton.setHeight(VOXEL_BUTTON_HEIGHT);
            newButton.setMinHeight(VOXEL_BUTTON_HEIGHT);
            //margin
            newButton.setMarginBottom(MARGIN_EACH_SIDE);
            newButton.setMarginLeft(MARGIN_EACH_SIDE);
            newButton.setMarginRight(MARGIN_EACH_SIDE);
            newButton.setMarginTop(MARGIN_EACH_SIDE);
            //label
            Label voxelLabel = new Label(1.0f);
            voxelLabel.setText(type.getName());
            //icon/model
            ImagePanel texturePanel = ImagePanel.createImagePanel(type.getTexture());
            if(type.getTexture() != null){
                Globals.assetManager.addTexturePathtoQueue(type.getTexture());
            }
            texturePanel.setWidth(VOXEL_BUTTON_TEXTURE_DIM);
            texturePanel.setHeight(VOXEL_BUTTON_TEXTURE_DIM);
            newButton.addChild(texturePanel);
            //button handling
            newButton.addChild(voxelLabel);
            newButton.setOnClick(new ClickEventCallback() {public boolean execute(ClickEvent event){
                //set voxel type to this type
                Globals.clientSelectedVoxelType = type;
                return false;
            }});
            scrollable.addChild(newButton);
        }

        rVal.applyYoga(0,0);
    }

}
