#include "RHI/RHI.h"

#include "Core/Core.h"
#include "Core/SpinLock.h"
#include "OpenGLDrv/GLDrvAPI.h"

#include "RHI/RHICommondList.h"

RHI* Singleton<RHI>::instance_ = nullptr;


RHI::RHI() noexcept {
}

RHI::~RHI() {
            
}

bool RHI::Initialize() {
    rhiAPI_ = std::make_unique<GLDrvAPI>();
    if (!rhiAPI_->InitEnv(driverSettings_)) {
        ERRORLOG("RHI init evn failed");
        return false;
    }

    rhiCommonList_ = RHICommonList::Create();
   
    return true;
}

void RHI::Uninitialize() {
    if (rhiCommonList_) {
        rhiCommonList_.reset();
    }

    if (!rhiAPI_) {
        ERRORLOG("RHI is not initialized");
        return;
    }
    rhiAPI_->UninitEnv();
}

bool RHI::StartRender() {
    if (nullptr == rhiCommonList_ || !rhiCommonList_->Start()) {
        ERRORLOG("StartRenderThread start failed");
        return false;
    }
    return true;
}


bool RHI::StopRender() {
    if (nullptr == rhiCommonList_) {
        ERRORLOG("StartRenderThread stop failed");
        return false;
    }
    rhiCommonList_->Stop();
    return true;
}

bool RHI::InitRenderEnv() {
    const DriverSettings& setting = RHI::Get()->GetDriverSettings();
    if (nullptr == rhiAPI_ || !rhiAPI_->InitRenderEnv(setting)) {
        ERRORLOG("RHICommonList start failed");
        return false;
    }
    return true;

}

void RHI::UpdaeRenderSize() {
    rhiAPI_->UpdateRenderSize(driverSettings_);
}

void RHI::UpdateScreenSize() {
     SharedPtr<RHICommond> task = UpdateRenderSizeCommand::Create();
    rhiCommonList_->Push(task);
    task->Wait();
}


void RHI::BeginFrame() {
     SharedPtr<RHICommond> task = rhiAPI_->CreateStartCommand();
    rhiCommonList_->Push(task);
}

void RHI::EndFrame() {
    SharedPtr<RHICommond> task = rhiAPI_->CreateEndCommand();
    rhiCommonList_->Push(task);
    task->Wait();
}

void RHI::PollEvents() {
    rhiAPI_->PollEvents();
}

void RHI::Push(class RHICommond* commond) {
    rhiCommonList_->Push(commond);
}
