/* 
    This file is just a wrapper for sdl, it also handles texture caching

    Copyright, 2003 Caleb Moore
    
    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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

*/


#include "graphics.h"
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <vector>
#include "arch.h"
using namespace std;

static SDL_Surface * screen;

static SDL_Surface * background;

static SDL_Surface * backimage;

static vector<SDL_Surface *> textures;

extern int fullscreen;

//just gets everthing loaded before any graphic work is done

void graphics_initialize()
{

  if( SDL_Init(SDL_INIT_VIDEO) < 0 ) 
    {
      fprintf(stderr,
	      "Error initializing SDL: %s\n", SDL_GetError());
      exit(1);
    }

  atexit(SDL_Quit);

    screen = SDL_SetVideoMode(800, 600, 16, SDL_HWSURFACE | SDL_FULLSCREEN *
			      fullscreen);
  if ( screen == NULL ) 
    {
      fprintf(stderr, "Couldn't set video mode: %s\n",
	      SDL_GetError());
      exit(1);
    }
  
}

void graphics_changemode()
{
  SDL_FreeSurface(screen);
  screen = SDL_SetVideoMode(800, 600, 16, SDL_HWSURFACE | SDL_FULLSCREEN *
			    fullscreen);
  if ( screen == NULL ) 
    {
      fprintf(stderr, "Couldn't set video mode: %s\n",
	      SDL_GetError());
      exit(1);
    }
}

//loads up a new texture

SDL_Surface * prepare_bmp(char * filename)
{
  if (screen == NULL)
    graphics_initialize();
  
  char absfile[200];
  char absfilea[200];

  snprintf(absfilea, 200, "graphics/%s", filename);
  absolutepath(absfilea, absfile);

  SDL_Surface * image = IMG_Load(absfile);
  if (image == NULL) 
    {
      fprintf(stderr, "Couldn't load %s: %s\n",
	      filename, SDL_GetError());
      return NULL;
    }
  
  SDL_Surface * convertedimage;
  convertedimage = SDL_ConvertSurface(image, screen->format, 0);

    if (convertedimage == NULL) 
    {
      fprintf(stderr, "Couldn't convert %s: %s\n",
	      filename, SDL_GetError());
      return NULL;
    }
  

    SDL_SetColorKey(convertedimage, SDL_SRCCOLORKEY,
		    SDL_MapRGB(convertedimage->format,0,0,0));


  SDL_FreeSurface(image);
  return convertedimage;
}

int load_bmp(char * filename)
{
  SDL_Surface * temp = prepare_bmp(filename);
  if (temp == NULL)
    return -1;
  textures.push_back(temp);
  return textures.size() - 1;
}

int load_bmps(char * filename, int start, int number)
{
  int ref = textures.size();

  char curname[200];
  SDL_Surface * temp;

  for (int i = start; i <= number; i++)
    {
      snprintf(curname, 200, "%s%i.bmp", filename, i);
      temp = prepare_bmp(curname);
      textures.push_back(temp);
    }
  return ref;
}

int load_bmpstrip(char * filename, int number)
{
  int ref = textures.size();

  SDL_Surface * strip;
  SDL_Surface * frame;

  strip = prepare_bmp(filename);
  int framewidth = strip->w / number;

  SDL_Rect dstrect;
  dstrect.x = 0;
  dstrect.y = 0;
  SDL_Rect srcrect;
  srcrect.y = 0;
  srcrect.h = strip->h;
  srcrect.w = framewidth;


  for (int i = 0; i <= number; i++)
    {
      frame = SDL_CreateRGBSurface(0, framewidth, strip->h,
				   strip->format->BitsPerPixel, 
				   strip->format->Rmask, 
				   strip->format->Gmask,
				   strip->format->Bmask, 
				   strip->format->Amask);
      srcrect.x = framewidth * i;
      SDL_BlitSurface(strip, &srcrect, frame, &dstrect);
      SDL_SetColorKey(frame, SDL_SRCCOLORKEY,
		      SDL_MapRGB(frame->format,0,0,0));
      textures.push_back(frame);
    }
  return ref;
}

//throwes the buffer onto the screen

void refresh_screen()
{
  SDL_UpdateRect(screen, 0, 0, screen->w, screen->h);
}

//draws a cached bitmap

void display_bmp(unsigned int index, unsigned int x, unsigned int y)
{
  SDL_Rect dstrect;
  dstrect.x = x;
  dstrect.y = y;
  SDL_Rect srcrect;
  srcrect.x = 0;
  srcrect.y = 0;
  srcrect.w = textures[index]->w;
  srcrect.h = textures[index]->h;

  SDL_BlitSurface(textures[index], &srcrect, screen, &dstrect);
}

//returns the size of a given bitmap

point bmp_size(unsigned int index)
{
  point output;
  output.x = textures[index]->w;
  output.y = textures[index]->h;
  return output;
}

//flushes out the cache

void free_bmps()
{
  vector<SDL_Surface *>::iterator i;
  for (i = textures.begin(); i < textures.end(); i++)
    SDL_FreeSurface(*i);
}

//sets a background image, this will undo any chopping

void set_bg(char * filename)
{
  background = prepare_bmp(filename);
  SDL_SetColorKey(background, 0,0);
}

//sets the image behind the background that gets exposed

void set_backimage(char * filename)
{
  backimage = prepare_bmp(filename);
  SDL_SetColorKey(backimage, 0,0);
}

//carves a hole in the background image

void chop_bg(point tl, point br)
{
  SDL_Rect dstrect;
  dstrect.x = tl.x;
  dstrect.y = tl.y;
  SDL_Rect srcrect;
  srcrect.x = tl.x;
  srcrect.y = tl.y;
  srcrect.w = br.x - tl.x;
  srcrect.h = br.y - tl.y;

  SDL_BlitSurface(backimage, &srcrect, background, &dstrect);
}

//draws the background image

void display_bg()
{
  SDL_Rect srcrect;
  srcrect.x = 0;
  srcrect.y = 0;
  srcrect.w = background->w;
  srcrect.h = background->h;

  SDL_BlitSurface(background, &srcrect, screen, &srcrect);
}
