#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include "SDL/SDL.h"

SDL_Surface *screen;

bool rgba = true;

void render(char* data, int width, int offset)
{   
  if (SDL_MUSTLOCK(screen)) if (SDL_LockSurface(screen) < 0) return;

  if (rgba)
    {
      for (int y = 0; y < 768; ++y)
        for (int x = 0; x < width && x < 1024; ++x)
          {
            ((unsigned char*)screen->pixels)[4*(y * 1024 + x) + 0] = data[offset + 4*(y * width + x) + 0];
            ((unsigned char*)screen->pixels)[4*(y * 1024 + x) + 1] = data[offset + 4*(y * width + x) + 1];
            ((unsigned char*)screen->pixels)[4*(y * 1024 + x) + 2] = data[offset + 4*(y * width + x) + 2];
            ((unsigned char*)screen->pixels)[4*(y * 1024 + x) + 3] = data[offset + 4*(y * width + x) + 3];
          }
    }
  else
    {
      for (int y = 0; y < 768; ++y)
        for (int x = 0; x < width && x < 1024; ++x)
          {
            if (0)
              {
                ((unsigned char*)screen->pixels)[4*(y * 1024 + x) + 0] = data[offset + 3*(y * width + x) + 0];
                ((unsigned char*)screen->pixels)[4*(y * 1024 + x) + 1] = data[offset + 3*(y * width + x) + 1];
                ((unsigned char*)screen->pixels)[4*(y * 1024 + x) + 2] = data[offset + 3*(y * width + x) + 2];
                ((unsigned char*)screen->pixels)[4*(y * 1024 + x) + 3] = 0;
              }
            else if (0)
              {
                ((unsigned char*)screen->pixels)[4*(y * 1024 + x) + 0] = data[offset + (y * width + x)];
                ((unsigned char*)screen->pixels)[4*(y * 1024 + x) + 1] = data[offset + (y * width + x)];
                ((unsigned char*)screen->pixels)[4*(y * 1024 + x) + 2] = data[offset + (y * width + x)];
                ((unsigned char*)screen->pixels)[4*(y * 1024 + x) + 3] = 0;
              }
            else
              {
                unsigned int p = data[offset + 2*(y * width + x)] & (data[offset + 2*(y * width + x)+1] << 8);
                
                ((unsigned char*)screen->pixels)[4*(y * 1024 + x) + 0] = p & 0x1F;
                ((unsigned char*)screen->pixels)[4*(y * 1024 + x) + 1] = (p & 0x7E0) >> 5;
                ((unsigned char*)screen->pixels)[4*(y * 1024 + x) + 2] = ((p & 0x1F << 11) >> 11)d;
                ((unsigned char*)screen->pixels)[4*(y * 1024 + x) + 3] = 0;
              }
          }
    }

  if (SDL_MUSTLOCK(screen)) SDL_UnlockSurface(screen);

  SDL_UpdateRect(screen, 0, 0, 1024, 768); 
}


// Entry point
int main(int argc, char *argv[])
{
  if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) 
  {
    fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
      exit(1);
    }

  atexit(SDL_Quit);
    
  screen = SDL_SetVideoMode(1024, 768, 32, SDL_SWSURFACE);
  
  // If we fail, return error.
  if ( screen == NULL ) 
    {
      fprintf(stderr, "Unable to set 640x480 video: %s\n", SDL_GetError());
      exit(1);
    }

  int width = 512;
  int offset = 0;
  int filesize = 0;
  int blocksize = 4096;
  char* data = 0;
  
  std::cout << "OK" << std::endl;
  FILE* in = fopen(argv[1], "r");

  std::cout << "OK" << std::endl;
  
  int res;
  do {
    //std::cout << filesize << std::endl;
    data = (char*)realloc(data, filesize + blocksize);
    res = fread(data + filesize, 1, blocksize, in);
    filesize += res;
  } while (res > 0);

  std::cout << "Filesize: " << filesize << std::endl;
  fclose(in);

  // Main loop: loop forever.
  while (1)
    {
      render(data, width, offset);

      SDL_Event event;
      while (SDL_PollEvent(&event)) 
        {
          switch (event.type) 
            {
            case SDL_KEYDOWN:
              break;

            case SDL_KEYUP:
              switch(event.key.keysym.sym)
                {
                case SDLK_r:
                  rgba = !rgba;
                  std::cout << "RGBA: " << rgba << std::endl;
                  break;


                case SDLK_l:
                  std::cout << "New Width: " << std::flush;
                  std::cin >> width;
                  break;

                case SDLK_t:
                  width -= 1;
                  break;
                  
                case SDLK_n:
                  width += 1;
                  break;


                case SDLK_p:
                  width -= 32;
                  break;
                  
                case SDLK_y:
                  width += 32;
                  break;

                case SDLK_f:
                  offset -= width*768 * 3;
                  break;

                case SDLK_d:
                  offset += width*768 * 3;
                  break;
                  
                case SDLK_i:
                  offset += 512*512;
                  break;

                  

                case SDLK_u:
                  offset -= 512*512;
                  break;

                case SDLK_a:
                  offset -= 1;
                  break;
                case SDLK_o:
                  offset += 1;
                  break;

                default:
                  break;

                }
              std ::cout << "Width: " << width << " Offset: " << offset << std::endl;


              if (event.key.keysym.sym == SDLK_ESCAPE)
                return 0;
              break;

            case SDL_QUIT:
              return(0);
            }
        }
    }
  return 0;
}

/* EOF */
