/*
   Ludovic Jacomme <Ludovic.Jacomme@gmail.com>
*/

#include <pspkernel.h>
#include <pspdebug.h>
#include <pspsdk.h>
#include <pspctrl.h>
#include <pspthreadman.h>
#include <stdlib.h>
#include <stdio.h>

#include <zlib.h>
#include <string>
#include <psppower.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>

#include "global.h"
#include "psp_fmgr.h"
#include "psp_kbd.h"
#include "psp_danzeff.h"
#include "psp_sdl.h"

#include "Cartridge.h"
#include "ProSystem.h"

extern "C" {

static word display_palette16[256] = {0};

void
psp_atari_reset()
{
  prosystem_Reset();
}

int
psp_atari_load_state(char *filename)
{
  int error;

  std::string std_filename(filename);
  error = prosystem_Load(filename) ? 0 : 1;

  return error;
}

int
psp_atari_save_state(char *filename)
{
  int error;

  std::string std_filename(filename);
  error = prosystem_Save(filename, true) ? 0 : 1;

  return error;
}

int 
psp_atari_load_rom(char *filename) 
{
  std::string std_filename(filename);
  if(! cartridge_Load(std_filename)) return 1;

# if 0
    sound_Stop( );
    display_Clear( );
    database_Load(cartridge_digest);
# endif

  prosystem_Reset();

# if 0
    std::string title = std::string(CONSOLE_TITLE) + " - " + common_Trim(cartridge_title);
    SetWindowText(console_hWnd, title.c_str( ));
    console_AddRecent(filename);
    display_ResetPalette( );
    console_SetZoom(display_zoom);
    sound_Play( );
# endif
  return 0;
}

/* LUDO: */
void
atari_synchronize(void)
{
	static u32 nextclock = 1;

	if (nextclock) {
		u32 curclock;
		do {
			curclock = clock();
		} while (curclock < nextclock);

		nextclock = curclock + (CLK_TCK / 60);
	}
}

void
psp_atari_init_palette16()
{
  uint rsize  =  6;
  uint gsize  =  5;
  uint bsize  =  6;
      
  for(uint index = 0; index < 256; index++) {
    word r = palette_data[(index * 3) + 0];
    word g = palette_data[(index * 3) + 1];
    word b = palette_data[(index * 3) + 2];
    display_palette16[index] = psp_sdl_rgb(r, g, b);
  }
}

void
psp_atari_put_image_normal()
{
  uint height = maria_visibleArea.GetHeight( );
  uint length = maria_visibleArea.GetLength( );

  const byte* buffer = maria_surface + ((maria_visibleArea.top - maria_displayArea.top) * maria_visibleArea.GetLength( ));

  word* surface = (word*)psp_sdl_get_vram_addr(80, 25);
  uint pitch = PSP_LINE_SIZE;

  for(uint indexY = 0; indexY < height; indexY++) {
    for(uint indexX = 0; indexX < length; indexX += 4) {
      surface[indexX + 0] = display_palette16[buffer[indexX + 0]];
      surface[indexX + 1] = display_palette16[buffer[indexX + 1]];
      surface[indexX + 2] = display_palette16[buffer[indexX + 2]];
      surface[indexX + 3] = display_palette16[buffer[indexX + 3]];
    }
    surface += pitch;
    buffer += length;
  }
}

void
psp_atari_refresh_screen()
{
  if (ATARI.atari_render_mode == ATARI_RENDER_NORMAL) psp_atari_put_image_normal(); 
# if 0
  else
  if (ATARI.atari_render_mode == ATARI_RENDER_FIT   ) PutImage_fit(); 
  else
  if (ATARI.atari_render_mode == ATARI_RENDER_X13   ) PutImage_x13(); 
# endif
  if (psp_kbd_is_danzeff_mode()) {
    danzeff_moveTo(-165, -50);
    danzeff_render();
  }

  psp_sdl_flip();
  
  if (psp_screenshot_mode) {
    psp_screenshot_mode--;
    if (psp_screenshot_mode <= 0) {
      psp_sdl_save_screenshot();
      psp_screenshot_mode = 0;
    }
  }
}

void
psp_atari_main_loop()
{
  /* Open default rom */
  if (psp_atari_load_rom("./default.a78")) {
    psp_sdl_exit(1);
  }

  psp_atari_init_palette16();

  while (1) {
    psp_update_keys();

    if(prosystem_active && !prosystem_paused) {
      {
        prosystem_ExecuteFrame(ATARI.keyboard_data);

        if (ATARI.atari_speed_limiter) {
          atari_synchronize();
        }
        psp_atari_refresh_screen();
      }
    }
  }  
}

};
