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

#pragma once
#include "../libs.h"
#include "../display/texture.h"
#include "../display/tileset.h"
#include "../display/primitive.h"
#include "../display/shader.h"
#include "../display/primitives/quad.h"
#include "../display/animation/animation.h"
#include "../engine/engine.h"
#include "../display/animation/easing.h"

#define VN_CHARACTER_BLINK_TIME_RANGE_MAX 6
#define VN_CHARACTER_SIZE 0.5

/** How many quads the VN Character has. Base, Eyes, Mouth and Eyebrows */
#define VN_CHARACTER_QUAD_COUNT 4

/** The Quads */
#define VN_CHARACTER_QUAD_BASE 0
#define VN_CHARACTER_QUAD_EYEBROWS 1
#define VN_CHARACTER_QUAD_EYES 2
#define VN_CHARACTER_QUAD_MOUTH 3

/** How many frames does each mouth set have */
#define VN_CHARACTER_TALKING_FRAME_COUNT 3

#define VN_CHARACTER_EMOTION_BORED 0x00
#define VN_CHARACTER_EMOTION_BORED_SMILING 0x01
#define VN_CHARACTER_EMOTION_BORED_DISAGREE 0x02
#define VN_CHARACTER_EMOTION_BORED_AGREE 0x03
#define VN_CHARACTER_EMOTION_SHORT 0x04
#define VN_CHARACTER_EMOTION_SMUG_SLIGHT 0x05
#define VN_CHARACTER_EMOTION_BORED_ANNOYED 0x06
#define VN_CHARACTER_EMOTION_BORED_PROUD 0x07
#define VN_CHARACTER_EMOTION_BORED_THINKING 0x08
#define VN_CHARACTER_EMOTION_HAPPY_THINKING 0x09
#define VN_CHARACTER_EMOTION_SERIOUS_THINKING 0x0A
#define VN_CHARACTER_EMOTION_SMUG_THINKING_SLIGHT 0x0B
#define VN_CHARACTER_EMOTION_XXXX_THINKING 0x0C// "concerned thinking"
#define VN_CHARACTER_EMOTION_HAPPY_FAKE_THINKING 0x0D
#define VN_CHARACTER_EMOTION_XXXX_THINKING2 0x0E// "serious concerned thinking"
#define VN_CHARACTER_EMOTION_XXXX_THINKING3 0x0F // "Happy pleased thinking"
#define VN_CHARACTER_EMOTION_BORED_LISTENING 0x10
#define VN_CHARACTER_EMOTION_HUMBLED 0x11
#define VN_CHARACTER_EMOTION_CONCERNED_1 0x12
#define VN_CHARACTER_EMOTION_PROUD 0x13
#define VN_CHARACTER_EMOTION_DEADPAN 0x14
#define VN_CHARACTER_EMOTION_SMIRK 0x15
#define VN_CHARACTER_EMOTION_CONCERNED_2 0x16
#define VN_CHARACTER_EMOTION_TEASING 0x17
#define VN_CHARACTER_EMOTION_XXXX_THINKING4 0x18// "concerned thinking lightly"
#define VN_CHARACTER_EMOTION_XXXX_THINKING5 0x19// "daydreaming"
#define VN_CHARACTER_EMOTION_XXXX_THINKING6 0x1A// "concerned thinking heavy"
#define VN_CHARACTER_EMOTION_XXXX_THINKING7 0x1B// "pleasant daydreaming"
#define VN_CHARACTER_EMOTION_XXXX_THINKING8 0x1C// not really sure
#define VN_CHARACTER_EMOTION_ANIME_MOM 0x1D
#define VN_CHARACTER_EMOTION_XXXX_THINKING9 0x1E// not really sure
#define VN_CHARACTER_EMOTION_ANIME_MOM_SMUG 0x1F
#define VN_CHARACTER_EMOTION_CURIOUS 0x20
#define VN_CHARACTER_EMOTION_HAPPY 0x21
#define VN_CHARACTER_EMOTION_CONCERNED_WORRIED 0x22
#define VN_CHARACTER_EMOTION_HAPPY_PROUD_SLIGHT 0x23
#define VN_CHARACTER_EMOTION_NOT_BELIEVING 0x24//"Mhm, suuure"
#define VN_CHARACTER_EMOTION_HAPPY_TIRED 0x25
#define VN_CHARACTER_EMOTION_CONCERNED_SLIGHT 0x26
#define VN_CHARACTER_EMOTION_HAPPY_PROUD 0x27
#define VN_CHARACTER_EMOTION_XXXX_THINKING10 0x28// sort of tsundere
#define VN_CHARACTER_EMOTION_XXXX_THINKING11 0x29// "thinking of something nice"
#define VN_CHARACTER_EMOTION_XXXX_THINKING12 0x2A// big sister vibes
#define VN_CHARACTER_EMOTION_XXXX_THINKING13 0x2B// "vibin"
#define VN_CHARACTER_EMOTION_XXXX_THINKING14 0x2C// not really sure
#define VN_CHARACTER_EMOTION_XXXX_THINKING15 0x2D// not really sure
#define VN_CHARACTER_EMOTION_XXXX_THINKING16 0x2E// not really sure
#define VN_CHARACTER_EMOTION_XXXX_THINKING17 0x2F// not really sure
#define VN_CHARACTER_EMOTION_CONCERNED 0x30
#define VN_CHARACTER_EMOTION_RELIEVED 0x31
#define VN_CHARACTER_EMOTION_CONCERNED_VERY 0x32
#define VN_CHARACTER_EMOTION_RELIEVED_SMUG 0x33//"slightly smug"
#define VN_CHARACTER_EMOTION_CONCERNED_3 0x34// "slightly worried"
#define VN_CHARACTER_EMOTION_CONCERNED_4 0x35// "slightly smug"
#define VN_CHARACTER_DISAPPOINTED 0x36// "slightly worried"
#define VN_CHARACTER_EMOTION_CONCERNED_5 0x37// "slightly smugger"
#define VN_CHARACTER_EMOTION_CONCERNED_THINKING 0x38
#define VN_CHARACTER_EMOTION_SMUG_1 0x39
#define VN_CHARACTER_EMOTION_CONCERNED_THINKING_DEEP 0x3A
#define VN_CHARACTER_EMOTION_SMUG_2 0x3B
#define VN_CHARACTER_EMOTION_XXXX_THINKING18 0x3C// not really sure
#define VN_CHARACTER_EMOTION_XXXX_THINKING19 0x3D// not really sure
#define VN_CHARACTER_EMOTION_XXXX_THINKING20 0x3E// not really sure
#define VN_CHARACTER_EMOTION_XXXX_THINKING21 0x3F// not really sure
#define VN_CHARACTER_EMOTION_SERIOUS 0x40
#define VN_CHARACTER_EMOTION_READY 0x41
#define VN_CHARACTER_EMOTION_SERIOUS_ANGRY 0x42
#define VN_CHARACTER_EMOTION_SMUG 0x43
#define VN_CHARACTER_EMOTION_ANGRY 0x44
#define VN_CHARACTER_EMOTION_ANGRY_PROUD 0x45
#define VN_CHARACTER_EMOTION_ANGRY_VERY 0x46
#define VN_CHARACTER_EMOTION_SMUG_VERY 0x47
#define VN_CHARACTER_EMOTION_SERIOUS_THINKING_VERY 0x48
#define VN_CHARACTER_EMOTION_SMUG_THINKING 0x49
#define VN_CHARACTER_EMOTION_ANGRY_THINKING 0x4A
#define VN_CHARACTER_EMOTION_SMUG_THINKING_VERY 0x4B
#define VN_CHARACTER_EMOTION_XXXX_THINKING22 0x4C// not really sure
#define VN_CHARACTER_EMOTION_HAPPY_FAKE_THINKING_ANGRY 0x4D
#define VN_CHARACTER_EMOTION_XXXX_THINKING23 0x4E// not really sure
#define VN_CHARACTER_EMOTION_BOASTFUL 0x4F

typedef struct {
  float x, y, z;
  float yaw, pitch, roll;
  float scaleX, scaleY;

  bool talking;
  float blinkStart;

  uint8_t emotion;

  primitive_t primitive;
  texture_t *texture;

  int32_t baseWidth, baseHeight;
  int32_t faceX, faceY;
  int32_t faceWidth, faceHeight;
} vncharacter_t; 

/**
 * Initialize a VN Character.
 * 
 * @param character Character to initialize.
 * @param texture The characters' texture.
 * @param baseWidth The width of the base character within the texture.
 * @param baseHeight The height of the base character within the texture.
 * @param faceX The X position on the face that the faces are cropped.
 * @param faceY The Y position on the face that the faces are cropped.
 * @param faceWidth The width of the cropped face.
 * @param faceHeight The height of the cropped face.
 */
void vnCharacterInit(
  vncharacter_t *character, texture_t *texture,
  int32_t baseWidth, int32_t baseHeight,
  int32_t faceX, int32_t faceY,
  int32_t faceWidth, int32_t faceHeight
);

/**
 * Buffer part of a VN Character texture onto the primitive. All the below units
 * are believed to be in pixels, the relatives will be recalculated on the fly.
 * 
 * @param character Character to buffer to.
 * @param x Local X position of the VN Character to buffer to.
 * @param y Local Y positon of the VN character to buffer to.
 * @param width Width of the subarea.
 * @param height Height of the subarea.
 * @param tx Texture X position.
 * @param ty Texture Y position.
 * @param i Quad index to buffer to.
 */
void _vnCharacterBuffer(vncharacter_t *character,
  int32_t x, int32_t y, int32_t width, int32_t height, int32_t tx, int32_t ty,
  int32_t i
);

/**
 * Buffer the face of a VN Character to the primitive.
 * 
 * @param character Character to buffer to.
 * @param col Face Column.
 * @param i Quad index to buffer to.
 */
void _vnCharacterFaceBuffer(vncharacter_t *character, int32_t col, int32_t i);

void vnCharacterUpdate(vncharacter_t *character, engine_t *engine);
void vnCharacterRender(vncharacter_t *character, shader_t *shader);

void vnCharacterDispose(vncharacter_t *character);