package net.halbear.Terrain4J.EngineCore.Threads;

import net.halbear.Terrain4J.EngineCore.Display.Render;
import net.halbear.Terrain4J.EngineCore.Display.Window;
import net.halbear.Terrain4J.EngineCore.Logic.*;
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
import net.halbear.Terrain4J.EngineCore.Profiling.CPUMonitor;
import net.halbear.Terrain4J.EngineCore.Profiling.GPUProfiler;
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.SceneRender;
import org.tinylog.Logger;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class RenderThread extends EngineThread {
    private Render render;
    private Window window;
    private final InitData initData;

    public RenderThread(Window window, EngineInstance engineInstance, InitData initData, GameLogic appLogic) {
        //this.window = window;
        render = new Render(engineInstance);
        super(engineInstance,appLogic,"Render");
        this.initData = initData;
        render.Initialise(initData);
    }

    public Render GetRenderer(){return render;}

    @Override
    public void TickEvent(long nsTimeDiff){
    }
    @Override
    public void FrameEvent(long now, long InitialTime){
        gameLogic.RenderThreadInput(PrimaryRuntime.GetEngineInstance(), (now-InitialTime));
        render.render(PrimaryRuntime.GetEngineInstance());
    }
    @Override
    public void CycleEvent(){

    }


    @Override
    public void SecondEvent(){
        EngineConfig.LAST_AVERAGE_GPU_TIME = SceneRender.GetGPUTimeNS();
        List<String[]> Profiling =GPUProfiler.GetVramUsage(render.GetVulkanContext().GetPhysicalDevice().GetPhysicalDevice());
        EngineConfig.getInstance().SetMemoryProfiling(Profiling);
        EngineConfig.FrameRate_RENDERTHREAD = Frames;
        EngineConfig.TPS_RENDERTHREAD = TickFrames;
        if(render.GetCurrentAAMode() != EngineConfig.getInstance().RenderAAType()){
            render.cleanup();
            render = new Render(PrimaryRuntime.GetEngineInstance());
            render.Initialise(initData);
        }
    }


    @Override
    public void cleanup() {
        render.cleanup();
        PrimaryRuntime.ThreadsOpen--;
        Logger.debug("Closing Render Thread, Thread: [{}]",Thread.currentThread().toString());
        if (PrimaryRuntime.ThreadsOpen <= 0 && VulkanContext.VulkanLayersOpen < 0) PrimaryRuntime.CanClose = true;
    }
}
