Documento de especificaciones de ViBe3 Physics

# Codigo
* Se preferira el uso de #pragma once a #ifndef
* Se preferira el uso de C++ frente a C
* Se preferirá el uso de verisiones mas moderdas de C++ frente a las mas viejas, es decir, C++20 frente a C++17, por ejemplo
* Se preferirá el uso de smart pointers frente a new/delete y sobretodo antes que malloc/free
* Los archivos de cabecera que definan clases, colocaran primero la parte publica y luego la privada. Agruparan los metodos por categorias. Todas las variables, constantes, estructuras, enumeraciones, metodos, llevaran el comentario a la derecha
* Se respetarán las reglas definidas en los ficheros .clang-tidy y .clang-format que hay en la raíz o en las subcarpetas

# Funcionamiento
* El programa tiene modos de funcionamiento (AppMode). El funcionamiento de cada uno de ellos se describirá mas adelante. Son estados exclusivos que van automatizando cambios en el SimulationMode, Theme y Scene y serian:
    * SANDBOX
    * DEMO
    * DEMO LITE
    * LOGO
    * LOGO LITE
* El progama tiene otros modos de funcionamiento (SimulationMode). El funcionamiento de cada uno de ellos se describirá mas adelante. Son estados exclusivos:
    * PHYISICS
    * FIGURE
    * BOIDS
* El programa tiene un gestor de temas (Theme) que cambia los colores de lo que se ve en pantalla. Hay temas estáticos y dinamicos. El cambio de tema se realiza mediante LERP y no afecta en nada ni al AppMode ni al SimulationMode, es decir, no modifica sus estados.
* El programa tiene escenarios (Scene). Cada escena tiene un numero de pelotas. Cuando se cambia el escenario, se elimina el vector de pelotas y se crea uno nuevo. En funcion del SimulationMode actual se inicializan las pelotas de manera distinta:
    * PHYSICS: Se crean todas las pelotas cerca de la parte superior de la pantalla distribuidas en el 75% central del eje X (es como está ahora)
    * FIGURE: Se crean todas las pelotas en el punto central de la pantalla
    * BOIDS: Se crean todas las pelotas en posiciones al azar de la pantalla con velocidades y direcciones aleatorias
* El cambio de SimulationMode ha de preservar la inercia (velocidad, aceleracion, direccion) de cada pelota. El cambio se produce tanto de forma manual (pulsacion de una tecla por el usuario) como de manera automatica (cualquier AppMode que no sea SANDBOX)
    * PHYSICS a FIGURE:
        * Pulsando la tecla de la figura correspondiente
        * Pulsando la tecla F (ultima figura seleccionada)
    * PHYSICS a BOIDS:
        * Pulsando la tecla B
    * FIGURE a PHYSICS:
        * Pulsando los cursores: Gravedad ON en la direccion del cursor
        * Pulsando la tecla G: Gravedad OFF
        * Pulsando la tecla F: Ultima gravedad seleccionada (direccion o OFF)
    * FIGURE a BOIDS:
        * Pulsando la tecla B
    * BOIDS a PHYSICS:
        * Pulsando la tecla G: Gravedad OFF
        * Pulsando los cursores: Gravedad ON en la direccion del cursor
    * BOIDS a FIGURE:
        * Pulsando la tecla de la figura
        * Pulsando la tecla F (ultima figura)

# AppMode
* SANDBOX
    * No hay ningun automatismo. El usuario va pulsando teclas para ejecutar acciones.
    * Si pulsa una de estas teclas, cambia de modo:
        * D: DEMO
        * L: DEMO LITE
        * K: LOGO
* DEMO
    * En el modo DEMO el programa va cambiando el SimulationMode de manera automatica (como está ahora es correcto)
    * Se inicializa con un Theme al azar, Scene al azar, SimulationMode al azar. Restringido FIGURE->PNG_SHAPE
    * Va cambiando de Theme
    * Va cambiando de Scene
    * Cambia la escala de la Figure
    * Cambia el Sprite de las pelotas
    * NO PUEDE cambiar a la figura PNG_SHAPE
    * Eventualmente puede cambiar de manera automatica a LOGO LITE, sin restricciones
    * El usuario puede cambiar el SimulationMode, el Theme o el Scene. Esto no hace que se salga del modo DEMO
    * El usuario puede cambiar de AppMode pulsando:
        * D: SANDBOX 
        * L: DEMO LITE
        * K: LOGO
* DEMO LITE
    * En el modo DEMO el programa va cambiando el SimulationMode de manera automatica (como está ahora es correcto)
    * Se inicializa con un Theme al azar, Scene al azar, SimulationMode al azar. Restringido FIGURE->PNG_SHAPE
    * Este modo es exactamente igual a DEMO pero NO PUEDE:
        * Cambiar de Scene
        * Cambiar de Theme
        * Cambiar el Sprite de las pelotas
    * Eventualmente puede cambiar de manera automatica a LOGO LITE, sin restricciones
    * NO PUEDE cambiar a la figura PNG_SHAPE
    * El usuario puede cambiar el SimulationMode, el Theme o el Scene. Esto no hace que se salga del modo DEMO LITE
    * El usuario puede cambiar de AppMode pulsando:
        * D: DEMO 
        * L: SANDBOX
        * K: LOGO
* LOGO
    * Se inicializa con la Scene de 5.000 pelotas, con el tamaño de Sprite->Small, con SimulationMode en FIGURE->PNG_SHAPE, con un tema al azar de los permitidos
    * No cambia de Scene
    * No cambia el tamaño de Sprite
    * No cambia la escala de FIGURE
    * Los temas permitidos son MONOCROMO, LAVANDA, CARMESI, ESMERALDA o cualquiera de los temas dinamicos
    * En este modo SOLO aparece la figura PNG_SHAPE
    * Solo cambiara a los temas permitidos
    * Cambia el SimulationMode de PHYSICS a FIGURE (como hace ahora) pero no a BOIDS. BOIDS prohibido
    * El usuario puede cambiar el SimulationMode, el Theme o el Scene. Esto no hace que se salga del modo LOGO. Incluso puede poner un Theme no permitido o otro Scene.
    * El automatismo no cambia nunca de Theme así que se mantiene el del usuario.
    * El automatismo no cambia nunca de Scene asi que se mantiene el del usuario.
    * El usuario puede cambiar de AppMode pulsando:
        * D: DEMO 
        * L: DEMO LITE
        * K: SANDBOX
        * B: SANDBOX->BOIDS
* LOGO LITE
    * Este modo es exactamente igual al modo LOGO pero con unas pequeñas diferencias:
        * Solo se accede a el de manera automatica, el usuario no puede invocarlo. No hay tecla
        * Como se accede de manera automatica solo se puede llegar a él desde DEMO o DEMO LITE. Hay que guardar el estado en el que se encontraba AppMode, EngindeMode, Scene, Theme, Sprite, Scale... etc
        * Este modo tiene una muy alta probabilidad de terminar, volviendo al estado anterior desde donde se invocó.
    * El usuario puede cambiar de AppMode pulsando:
        * D: Si el modo anterior era DEMO -> SANDBOX, else -> DEMO)
        * L: Si el modo anterior era DEMO LITE -> SANDBOX, else -> DEMO LITE)
        * K: LOGO
        * B: SANDBOX->BOIDS


# Debug Hud
* En el debug hud hay que añadir que se vea SIEMPRE el AppMode (actualmente aparece centrado, hay que ponerlo a la izquierda) y no solo cietos AppModes
* Tiene que aparecer tambien el SimulationMode
* El modo de Vsync
* El modo de escalado entero, stretched, ventana
* la resolucion fisica
* la resolucion logica
* el refresco del panel
* El resto de cosas que salen

# Ventana de ayuda
* La ventana de ayuda actualmente es cuadrada
* Esa es la anchura minima que ha de tener
* Hay que ver cual es la linea mas larga, multiplicarla por el numero de columnas, añadirle los paddings y que ese sea el nuevo ancho
* Actualmente se renderiza a cada frame. El rendimiento cae de los 1200 frames por segundo a 200 frames por segundo. Habria que renderizarla a una textura o algo. El problema es que el cambio de Theme con LERP afecta a los colores de la ventana. Hay que investigar qué se puede hacer.

# Bugs actuales
* En el modo LOGO, si se pulsa un cursor, se activa la gravedad y deja de funcionar los automatismos. Incluso he llegado a ver como sale solo del modo LOGO sin pulsar nada
* En el modo BOIDS, pulsar la G activa la gravedad. La G deberia pasar al modo PHYSICS con la gravedad en OFF y que las pelotas mantuvieran el momento/inercia