#include <cpctelera.h>
#include <stdio.h>
#include <string.h>
#include "main.h"
#include "render.h"

u8 abs (i8 valor){
   return (valor > 0 ? valor : -valor);
}

u8 maximo (u8 punto1, u8 punto2) {
  return (punto1 > punto2 ? punto1 : punto2);
}

u8 numToCharacter(u8 value) {
  return 48 + value; //48 es el carácter para 0
}

void pausa(u16 ciclos) {
  u16 i;

  for (i = 0; i < ciclos; i++)
      ;
}

void pausaTecladoLibre(){
	while (cpct_isAnyKeyPressed_f ()) { //Asegurarnos que se ha dejado de pulsar la tecla anterior 
   		//cpct_scanKeyboard_f()
    ;
   	}
}

void pausaTeclado(){
  pausaTecladoLibre();
  while (!cpct_isAnyKeyPressed_f())
      ;
}


u8 pressedUp() {
  return (cpct_isKeyPressed(Key_Q) || cpct_isKeyPressed(Key_CursorUp) 
    || ((!using2ndbtn && cpct_isKeyPressed(Joy0_Up)) || (using2ndbtn && cpct_isKeyPressed(Joy0_Fire2))));
}

/*u8 pressedDown() {
  return (cpct_isKeyPressed(Key_A) || cpct_isKeyPressed(Key_CursorDown) || cpct_isKeyPressed(Joy0_Down));
}*/

u8 pressedLeft() {
  return (cpct_isKeyPressed(Key_O) || cpct_isKeyPressed(Key_CursorLeft) || cpct_isKeyPressed(Joy0_Left));
}

u8 pressedRight() {
  return (cpct_isKeyPressed(Key_P) || cpct_isKeyPressed(Key_CursorRight) || cpct_isKeyPressed(Joy0_Right));
}

u8 pressedFire() {
  return (cpct_isKeyPressed(Key_Space) || cpct_isKeyPressed(Joy0_Fire1));
}


u8 sizeString(u8* string){
  u8 i;

  i=1;
  while (*(string) != 0) {
    string++;
    i++;
  }

  return i;
}

u16 tileCell(u8 x, u8 y) {
  return (34*(y/4)) + (x/2);
}

u8 tileValue(u8 x, u8 y){
  return (current_map[tileCell(x, y)]);
}

u8 typeOfTile(u8 tile){
  
  if (tile <= MAX_TILES_PLATFORMS)
    return 1;
  else if (tile <= MAX_TILES_SOLID)
    return 2;
  else
    return 0;
}

void clearScreens(){
  cpct_memset ((u8*) 0xC000, 0x00, 0x4000);
}

void updatePalette(){
  cpct_memcpy (&current_palette[0],&paletteM0,16);
  cpct_setPalette(current_palette,16);
}


void updateEnergy (i8 new){
  i16 test;

  test = energy + new;

  if (test <0)
    energy = 0;
  else if (test > 255) 
    energy = 255;
  else
    energy = test;


  if (new < 0)
    renderFace(1);
  else
    renderFace(2);
  
  reset_face = 20;


  renderEnergy();
}

void fade(){
  u8 i,j;
  
  // Efecto Fade
  for (i=26;i>0;i--){
    for (j=1;j<16;j++){
      current_palette[j]=cpct_getHWColour (i);
    }
    cpct_setPalette(current_palette,16);
    pausa(SECOND/32);
  }

  clearScreens();
  updatePalette();
}


void swipeScreen (u8 V, u8 H) {
//  H: 0/1 borrado a la izquierda
//  H: 2/3 borrado a la derecha
//  V: 0/1 borrado arriba-abajo
//  V: 2/3 borrado abajo-arriba
// par: primer paso (efecto); impar: segundo paso (restaurar)

  u8 i,j;
  u16 k;

  i = 40;  //H es par
  j = 25;  //V es par
  if (H & 0x01) 
    i = 0;  //H es impar
  if (V & 0x01) 
    j = 0;  //V es impar

  do {
    if (H != 255) {
      cpct_setCRTCReg (1, i);   //Cambiar nº columnas por pantalla (1-40)
      if (H > 1)
        cpct_setCRTCReg (2, i+6);   //Cambiar columna de inicio (1-40)
    }

    if (V != 255) {
      cpct_setCRTCReg (6, j);   //Cambiar nº filas por pantalla (1-25)
      if (V > 1)
        cpct_setCRTCReg (7, j+5);   //Cambiar fila de inicio 
    }
    
    for (k = 0; k < 1024; k++)
      ;  //pausa

    if (H & 0x01)  {
      i++;
    } else {
      i--; 
    }

    if (V & 0x01)  {
      j++;
    } else {
      j--; 
    }
  } while ((H != 255 && i <= 40)
         ||(V != 255 && j <= 25));
}


void showMessage(u8 id) {
  textPrinted = 0;
  hintText = id; 
  hintTextTime = HINT_TIME_ON_SCREEN;  
}

void cutreZoomModo0 (void* sprite, u8 x, u8 y, u8 width, u8 height, u8 factor) {
// Tomando como base el sprite "*sprite" situado en x,y con dimensiones width,height,
// hace un escalado por el número indicado por factor tiendo como referencia el centro de la figura original
// Es decir para ver la misma figura con distintos factores de escalado, no se modifica x e y. Ya lo calcula la función
// NO SE HACEN COMPROBACIONES si se pintará fuera de pantalla
// No es ótpima, no es rápida, ¡PERO FUNCIONA!
  u8 xc,yc,x0,y0;
  u8 i,j,k,l,*ptr, pasos;
  u8 color1, color2, pixelFinal;
  

  // Calcular centro
  xc = x + (width/2);
  yc = y + (height/2);

  // Calcular x e y
  x0 = xc - ((width/2) * factor);
  y0 = yc - ((height/2) * factor);

  ptr = sprite;
  pasos = 0;

  //Recorreré cada pixel ancho por alto del sprite escalado e iré cogiendo el pixel del original
  for (i = 0; i < height; i++){
    for (j = 0; j < width; j++){
      for (k = 0; k < factor; k++){
        //obtenemos los valores codificados de los 2 colores del byte
        //Un byte contiene 2 pixeles, o sea dos colores que se codifican de la siguiente manera
        //Byte 94 correspondería a los colores 1 y 6 (en ese orden)
        //0x94 = 0b 1001 0100 
        //Si tomamos el orden como b0,b1,...b7 del byte. 
        //El primer color sale de coger los bits de los lugares 6,2,4,0 = 0001 => Color 1 de la paleta
        //El segundo color sale de coger los bits de los lugares 7,3,5,1 = 0110 => Color 6 de la paleta
        color1 = *ptr;
        color1 = color1 & 0b10101010;
        color2 = *ptr;
        color2 = color2 & 0b01010101;

        //Si el factor es par, la primera mitad será del color1; la segunda de color2
        //Para codificar un color consigo mismo, depende de si es el color1 o es el color2 hay que hacer un OR consigo mismo
        // desplazando a la derecha o la izquierda respectivamente.

        if (k < (factor/2)) { 
          pixelFinal = color1 | (color1 >> 1);
        } else if ((factor % 2) == 0 || (k > (factor/2))){
          pixelFinal = color2 | (color2 << 1);
        } else { //El centro de los factores impares es una mezcla de ambos colores
          pixelFinal = color1 | color2;
        }
        // *((u8*) 0xFFFF) = shift;       

        for (l=0;l<factor;l++) {
          //Pintar en Memoria de Vídeo el Byte Resultante
          *(cpct_getScreenPtr (CPCT_VMEM_START, x0+(j*factor)+k,y0+(i*factor)+l)) = pixelFinal;
        }
        //Cada X pasos avanzamos el puntero del sprite )donde X es el factor de escalado)
        pasos++;
        if (pasos % factor == 0)
          ptr++;
      }
    }
  } 
}