/**
 * Copyright (c) 2021 Dominic Masters
 * 
 * This software is released under the MIT License.
 * https://opensource.org/licenses/MIT
 */

#include "renderlist.h"

void renderListInit(renderlist_t *list,int32_t width, int32_t height) {
  frameBufferInit(&list->frame, width, height);
  quadInit(&list->quad, 0, 0,0,0,0, 1,1,1,1);
  list->passCount = 0;
}

renderpass_t * renderListGetPass(renderlist_t *list, int32_t pass) {
  return list->passes + pass;
}

int32_t renderPassAdd(renderlist_t *list) {
  int32_t i = list->passCount++;
  renderpass_t *pass = renderListGetPass(list, i);
  frameBufferInit(&pass->frame,
    list->frame.texture.width, list->frame.texture.height
  );
  return i;
}

void renderListRenderPass(
  renderlist_t *list, engine_t *engine,
  camera_t *camera, int32_t pass, renderitem_t *items, int32_t itemCount
) {
  int32_t i;
  renderpass_t *renderPass;
  renderitem_t *item;

  renderPass = renderListGetPass(list, pass);

  // Bind the shader.
  frameBufferUse(&renderPass->frame, true);
  shaderUse(renderPass->shader);

  // "Uniforms"
  shaderUseCamera(renderPass->shader, camera);

  // Render list
  for(i = 0; i < itemCount; i++) {
    item = items + i;
    item->onRender(list, renderPass, engine, i);
  }
}

void renderListRender(renderlist_t *list, shader_t *shader) {
  camera_t camera;
  int32_t i;
  renderpass_t *pass;

  // Setup the camera
  cameraLookAt(&camera, 0,0,1, 0,0,0);
  cameraOrtho(&camera, 0,1, 0,1, 0.5f, 1.5f);

  // Bind the framebuffer
  frameBufferUse(&list->frame, true);

  // Set the shader
  shaderUse(shader);
  shaderUsePosition(shader, 0,0,0, 0,0,0);
  shaderUseCamera(shader, &camera);

  // Render each pass.
  for(i = 0; i < list->passCount; i++) {
    pass = renderListGetPass(list, i);
    shaderUseTexture(shader, &pass->frame.texture);
    primitiveDraw(&list->quad, 0, -1);
  }
}

void renderListAsBackbuffer(
  renderlist_t *list, engine_t *engine, shader_t *shader
) {
  camera_t camera;

  // Reset to backbuffer
  renderResetFramebuffer(&engine->render);

  // Setup camera to look right at teh quad.
  cameraLookAt(&camera, 0,0,1, 0,0,0);
  cameraOrtho(&camera, 0,1, 0,1, 0.5f, 1.5f);

  // Set up the shader.
  shaderUse(shader); 
  shaderUseTexture(shader, &list->frame.texture);
  shaderUseCamera(shader, &camera);
  shaderUsePosition(shader, 0,0,0, 0,0,0);

  // Render the quad to the back buffer.
  primitiveDraw(&list->quad, 0, -1);
}