/*
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <SDL/SDL.h>
#include <SDL/SDL_mixer.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_ttf.h>
#include <pspctrl.h>
#include "psp_sdl.h"
#include "beebwinc.h"

//static ushort *sdl_vramtop=(ushort *)0x04000000;
  extern SDL_Surface *back2_surface;

uint
psp_sdl_rgb(uchar R, uchar G, uchar B)
{
  return SDL_MapRGB(screen_ptr->format, R,G,B);
}

ushort *
psp_sdl_get_vram_addr(uint x, uint y)
{
  ushort *vram = (ushort *)screen_ptr->pixels;
  return vram + x + (y*LINESIZE);
}

void
loc_psp_debug(char *file, int line, char *message)
{
  static current_line = 0;
  static current_col  = 10;

  char buffer[128];
  current_line += 10;
  if (current_line > 250)
  {
    if (current_col == 200) {
      psp_sdl_clear_screen(psp_sdl_rgb(0, 0, 0xff));
      current_col = 10;
    } else {
      current_col = 200;
    }
    
    current_line = 10;
  }
  sprintf(buffer,"%s:%d %s", file, line, message);
  psp_sdl_print(current_col, current_line, buffer, psp_sdl_rgb(0xff,0xff,0xff) );
}

void 
psp_sdl_print(int x,int y, char *str, int color)
{
  int index;
  int x0 = x;

  for (index = 0; str[index] != '\0'; index++) {
    psp_sdl_put_char(x, y, color, 0, str[index], 1, 0);
    x += 8;
    if (x >= (PSP_SDL_SCREEN_WIDTH - 8)) {
      x = x0; y++;
    }
    if (y >= (PSP_SDL_SCREEN_HEIGHT - 8)) break;
  }
}

void
psp_sdl_clear_screen(int color)
{
  int x; int y;
  ushort *vram = psp_sdl_get_vram_addr(0,0);
  
  for (y = 0; y < PSP_SDL_SCREEN_HEIGHT; y++) {
    for (x = 0; x < PSP_SDL_SCREEN_WIDTH; x++) {
      vram[x + (y*LINESIZE)] = color;
    }
  }
  psp_sdl_flush();
}


void 
psp_sdl_draw_rectangle(int x, int y, int w, int h, int border, int mode) 
{
  ushort *vram = (ushort *)psp_sdl_get_vram_addr(x, y);
  int xo, yo;
  if (mode == PSP_SDL_XOR) {
    for (xo = 0; xo < w; xo++) {
      vram[xo] ^=  border;
      vram[xo + h * LINESIZE] ^=  border;
    }
    for (yo = 0; yo < h; yo++) {
      vram[yo * LINESIZE] ^=  border;
      vram[w + yo * LINESIZE] ^=  border;
    }
  } else {
    for (xo = 0; xo < w; xo++) {
      vram[xo] =  border;
      vram[xo + h * LINESIZE] =  border;
    }
    for (yo = 0; yo < h; yo++) {
      vram[yo * LINESIZE] =  border;
      vram[w + yo * LINESIZE] =  border;
    }
  }
}

void 
psp_sdl_fill_rectangle(int x, int y, int w, int h, int color, int mode)
{
  ushort *vram  = (ushort *)psp_sdl_get_vram_addr(x, y);
  int xo, yo;
  if (mode == PSP_SDL_XOR) {
    for (xo = 0; xo <= w; xo++) {
      for (yo = 0; yo <= h; yo++) {
        if ( ((xo == 0) && ((yo == 0) || (yo == h))) ||
             ((xo == w) && ((yo == 0) || (yo == h))) ) {
          /* Skip corner */
        } else {
          vram[xo + yo * LINESIZE] ^=  color;
        }
      }
    }
  } else {
    for (xo = 0; xo <= w; xo++) {
      for (yo = 0; yo <= h; yo++) {
        vram[xo + yo * LINESIZE] =  color;
      }
    }
  }
}

void 
psp_sdl_put_char(int x, int y, int color, int bgcolor, char c, int drawfg, int drawbg)
{
  int cx;
  int cy;
  int b;
  int index;

  ushort *vram = (ushort *)psp_sdl_get_vram_addr(x, y);
  index = ((ushort)c) * 8;

  for (cy=0; cy<8; cy++) {
    b=0x80;
    for (cx=0; cx<8; cx++) {
      if (psp_font[index] & b) {
        if (drawfg) vram[cx + cy * LINESIZE] = color;
      } else {
        if (drawbg) vram[cx + cy * LINESIZE] = bgcolor;
      }
      b = b >> 1;
    }
    index++;
  }
}

void 
psp_sdl_fill_print(int x,int y,const char *str, int color, int bgcolor)
{
  int index;
  int x0 = x;

  for (index = 0; str[index] != '\0'; index++) {
    psp_sdl_put_char(x, y, color, bgcolor, str[index], 1, 1);
    x += 8;
    if (x >= (PSP_SDL_SCREEN_WIDTH - 8)) {
      x = x0; y++;
    }
    if (y >= (PSP_SDL_SCREEN_HEIGHT - 8)) break;
  }
}

void
psp_sdl_wait_vn(uint count)
{
  for (; count>0; --count) {
    sceDisplayWaitVblankStart();
  }
}

void
psp_sdl_wait_vblank(void)
{
  sceDisplayWaitVblankStart();
}

void
psp_sdl_flush(void)
{
  sceKernelDcacheWritebackAll();
}

void
psp_sdl_lock(void)
{
  SDL_LockSurface(screen_ptr);
}

void
psp_sdl_unlock(void)
{
  SDL_UnlockSurface(screen_ptr);
}

void
psp_sdl_flip(void)
{
  SDL_Flip(screen_ptr);
}

void
psp_sdl_load_background()
{
  back2_surface = IMG_Load("./background.jpg");
}

void
psp_sdl_blit_background()
{
  static int first = 1;

  if (first && (back2_surface == NULL)) {
    psp_sdl_load_background();
    first = 0;
  }
  if (back2_surface != NULL) {
	  SDL_BlitSurface(back2_surface, NULL, screen_ptr, NULL);
  } else {
    psp_sdl_clear_screen(psp_sdl_rgb(0x00, 0x00, 0x00));
  }
}

void
psp_sdl_save_bmp(char *filename)
{
  SDL_SaveBMP(screen_ptr, filename);
}

#ifndef _MAX_PATH
#define _MAX_PATH 1024
#endif
void
psp_sdl_save_screenshot(void)
{
  char TmpFileName[_MAX_PATH];
  char TmpDirName[_MAX_PATH];
  int  screenshot_id = beeb_get_psp_screenshot_id();

  getcwd(TmpDirName, sizeof(TmpDirName));
  sprintf(TmpFileName,"%s/scr/screenshot_%d.bmp", TmpDirName, screenshot_id++);
  if (screenshot_id >= 10) screenshot_id = 0;
  beeb_set_psp_screenshot_id(screenshot_id);
  SDL_SaveBMP(screen_ptr, TmpFileName);
}
