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

#include "bitmapfont.h"

tilesetdiv_t * bitmapFontGetCharacterDivision(tileset_t *tileset, char character) {
  int32_t i = ((int32_t)character) - BITMAP_FONT_CHAR_START;
  return tileset->divisions + i;
}

bitmapfontmeasure_t bitmapFontMeasure(char *string, float charWidth, float charHeight) {
  int32_t i;
  float x, y;
  char c;
  bitmapfontmeasure_t measure = {
    .height = 0, .lines = 1, .width = 0
  };

  i = 0;
  y = 0;
  x = 0;

  while(true) {
    c = string[i];
    if(c == '\0') break;
    i++;
    
    if(c == '\n') {
      measure.width = mathMax(x, measure.width);
      x = 0;
      y += charHeight;
      measure.lines++;
      continue;
    } else if(c == ' ') {
      x += charWidth;
      continue;
    }

    x += charWidth;
  }

  measure.width = mathMax(x, measure.width);
  measure.height = y + charHeight;

  return measure;
}

bitmapfontmeasure_t bitmapFontSpriteBatchBuffer(
  spritebatch_t *batch, tileset_t *tileset,
  char *string, float x, float y, float z, float charWidth, float charHeight
) {
  int32_t i;
  char c;
  tilesetdiv_t *div;
  float cx, cy;
  bitmapfontmeasure_t measure;

  // Detect char dimensions
  if(charWidth == -1) charWidth = tileset->divX * (charHeight / tileset->divY);
  if(charHeight == -1) charHeight = tileset->divY * (charWidth / tileset->divX);

  // Position the text.
  if(x == BITMAP_FONT_CENTER_X ||
     y == BITMAP_FONT_CENTER_Y ||
     x == BITMAP_FONT_RIGHT_X
  ) {
    measure = bitmapFontMeasure(string, charWidth, charHeight);
    if(x == BITMAP_FONT_CENTER_X) {
      x = -(measure.width/2);
    } else if(x == BITMAP_FONT_RIGHT_X) {
      x = -measure.width;
    }
    if(y == BITMAP_FONT_CENTER_Y) y = -(measure.height/2);
  }

  // Begin buffering the sprite batch
  measure.width = 0;
  measure.height = 0;
  measure.lines = 1;
  i = 0;
  cx = x, cy = y;

  while(true) {
    c = string[i];
    if(c == '\0') break;
    i++;
    
    // Special chars
    if(c == '\n') {
      measure.width = mathMax(cx-x, measure.width);
      cx = x;
      cy += charHeight;
      measure.lines++;
      continue;
    } else if(c == ' ') {
      cx += charWidth;
      continue;
    }

    div = bitmapFontGetCharacterDivision(tileset, c);
    spriteBatchQuad(batch, -1,
      cx, cy, z, charWidth, charHeight,
      div->x0, div->y1, div->x1, div->y0
    );
    cx += charWidth;
  }

  measure.width = mathMax(cx-x, measure.width);
  measure.height = cy-y + charHeight;

  return measure;
}