package electrosphere.menu.debug;

import org.ode4j.ode.DBody;

import electrosphere.collision.PhysicsEntityUtils;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.attack.ClientAttackTree;
import electrosphere.entity.state.server.ServerPlayerViewDirTree;
import electrosphere.entity.types.camera.CameraEntityUtils;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.renderer.ui.imgui.ImGuiWindow;
import electrosphere.renderer.ui.imgui.ImGuiWindow.ImGuiWindowCallback;
import electrosphere.server.datacell.utils.EntityLookupUtils;
import imgui.ImGui;

/**
 * Menus for player entity in particular
 */
public class ImGuiPlayerEntity {

    //player entity details
    public static ImGuiWindow playerEntityWindow;
    
    /**
     * Create player entity debug menu
     */
    public static void createPlayerEntityDebugWindow(){
        playerEntityWindow = new ImGuiWindow("Player Entity");
        playerEntityWindow.setCallback(new ImGuiWindowCallback() {
            @Override
            public void exec() {
                //player entity details
                ImGui.text("Player Entity Details");

                //data about player entity
                if(Globals.playerEntity != null){
                    ImGui.text("Position: " + EntityUtils.getPosition(Globals.playerEntity));
                    ImGui.text("Rotation: " + EntityUtils.getRotation(Globals.playerEntity));
                    
                    //physics on client
                    if(ImGui.collapsingHeader("Physics Data")){
                        drawPhysicsData();
                    }

                    //sync data
                    if(ImGui.collapsingHeader("Synchronization Data")){
                        drawSynchronizationData();
                    }

                    //camera details
                    if(ImGui.collapsingHeader("Camera Data")){
                        drawCameraData();
                    }

                }

                //
                //Camera controls
                if(ImGui.button("Toggle Player Camera Lock")){
                    Globals.cameraHandler.setTrackPlayerEntity(!Globals.cameraHandler.getTrackPlayerEntity());
                }
                if(ImGui.button("Toggle 1st/3rd Person")){
                    Globals.controlHandler.setIsThirdPerson(!Globals.controlHandler.cameraIsThirdPerson());
                }

                //
                //quick launch entity details
                if(ImGui.button("Client Details")){
                    ImGuiEntityMacros.showEntity(Globals.playerEntity);
                }
                ImGui.sameLine();
                if(ImGui.button("1st Person Details")){
                    ImGuiEntityMacros.showEntity(Globals.firstPersonEntity);
                }
                ImGui.sameLine();
                if(ImGui.button("Server Details")){
                    int serverIdForClientEntity = Globals.clientSceneWrapper.mapClientToServerId(Globals.playerEntity.getId());
                    Entity serverPlayerEntity = EntityLookupUtils.getEntityById(serverIdForClientEntity);
                    ImGuiEntityMacros.showEntity(serverPlayerEntity);
                }


            }
        });
        playerEntityWindow.setOpen(false);
        Globals.renderingEngine.getImGuiPipeline().addImGuiWindow(playerEntityWindow);
    }

    /**
     * Draws data about physics for client entity
     */
    private static void drawPhysicsData(){
        //client-side tree stuff
        DBody body = PhysicsEntityUtils.getDBody(Globals.playerEntity);
        ClientAttackTree attackTree = ClientAttackTree.getClientAttackTree(Globals.playerEntity);
        if(body != null){
            ImGui.text("Velocity: " + body.getLinearVel());
            ImGui.text("Force: " + body.getForce());
            ImGui.text("Angular Velocity: " + body.getAngularVel());
            ImGui.text("Torque: " + body.getTorque());
            ImGui.text("Move Vector: " + CreatureUtils.getFacingVector(Globals.playerEntity));
            if(attackTree != null){
                ImGui.text("Attack Tree State: " + attackTree.getState());
            }
        }
    }

    /**
     * Draws data on server side for synchronization comparison
     */
    private static void drawSynchronizationData(){
        //server pos
        int serverIdForClientEntity = Globals.clientSceneWrapper.mapClientToServerId(Globals.playerEntity.getId());
        Entity serverPlayerEntity = EntityLookupUtils.getEntityById(serverIdForClientEntity);
        ImGui.text("Position (Server): " + EntityUtils.getPosition(serverPlayerEntity));
        ImGui.text("Rotation (Server): " + EntityUtils.getRotation(serverPlayerEntity));

        //server-side physics stuff
        DBody serverBody = PhysicsEntityUtils.getDBody(serverPlayerEntity);
        if(serverBody != null){
            ImGui.text("Velocity (Server): " + serverBody.getLinearVel());
            ImGui.text("Force (Server): " + serverBody.getForce());
            ImGui.text("Move Vector (Server): " + CreatureUtils.getFacingVector(serverPlayerEntity));
            ImGui.text("Velocity (Server): " + CreatureUtils.getVelocity(serverPlayerEntity));
        }
        ImGui.text("View yaw (Server): " + ServerPlayerViewDirTree.getTree(serverPlayerEntity).getYaw());
        ImGui.text("View pitch (Server): " + ServerPlayerViewDirTree.getTree(serverPlayerEntity).getPitch());
    }

    /**
     * Draws camera data
     */
    private static void drawCameraData(){
        ImGui.text("Yaw: " + CameraEntityUtils.getCameraYaw(Globals.playerCamera));
        ImGui.text("Pitch: " + CameraEntityUtils.getCameraPitch(Globals.playerCamera));
    }

}
