/********************************************************************\
 * image2html -- Converts an image file to a html file.             *
 ********************************************************************
 * Feel free to do whatever with this util && it's source as long   *
 * as you find it fun ;). If you have any questions, ideas,         *
 * bug-reports or whatever feel free to email at aquila@dasfisk.dk  *
 *                                                                  *
 *          Have fun...                                             *
 \*******************************************************************/

#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <SDL.h>

#include "args.c"

void surface_to_html (SDL_Surface* src, int fp, int tfile);
void get_color_code (int r, int g, int b, char* colorcode);
void dec2hex (int dec, char* hex);
int is_illegal (char ch);
void makeheader (char* header);

int main (int argc, char* argv[])
{
  SDL_Surface*  bitmap;
  char* tfile_buffer;
  char srcfile[255];
  char tfile[255];
  char target[255];
  int tfile_fd, target_fd;

  /* Parse commandline arguments */
  if ( !parse_cmdline  (argc, argv, srcfile, target, tfile) ) {
    exit(-1);
  }

  /* Load the bitmap */
  bitmap = SDL_LoadBMP (srcfile);

  if (!bitmap) {
    printf("Error! Couldn't load bitmap file: %s\n\n", srcfile);
    printf("exiting...\n");
    exit(-1);
  }

  /* open the input file */
  if (inputfile_type != 0) {
    tfile_fd = open (tfile, O_RDONLY);

    if (tfile_fd == 0) {
      printf ("open: Couldnt open file %s", tfile);
      exit(1);
    }
  }

  /* open the output file */

  if (outputfile != 0) {
    target_fd = open ( target, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR);
    if (target_fd == 0) {
      printf ("open: Couldnt open file %s\n", target);
      exit (1);
    }
  } else {
    target_fd = 1; /* use stdout */
  }
 
  surface_to_html (bitmap, target_fd, tfile_fd);

  /* clean up */
  SDL_FreeSurface (bitmap);
  close (target_fd);
  close (tfile_fd);
  
  free (font);
  
}

void surface_to_html (SDL_Surface* src, int fp, int tfile)
{
  char htmlcolor[8];
  char header [512];
  char* footer = "</BODY></HTML>";
  char* html1 = "<FONT COLOR=";
  char* html2 = ">";
  char* html3 = "</FONT>";

  
  char ch;
   Uint8 r, g, b;
   int bpp;
   Uint8* offset;
   Uint32 pixel;
   int xmax, ymax, x, y;

   xmax = src->w;
   ymax = src->h;
   bpp = src->format->BytesPerPixel;

   /* Make the header */
   makeheader (header);
  
   /* write header */
   write (fp, header, get_string_size (header) );

   /* Parse the each pixel in the bitmap */
   for (y = 0; y < ymax; y++) {
     for (x = 0; x < xmax; x++) {
       offset = ((Uint8 *)src->pixels)+y*src->pitch+x*bpp;
       switch (bpp) 
       {
       case 1:
	 pixel = *((Uint8 *)(offset));
         SDL_GetRGB (pixel, src->format, &r, &g, &b);
         break;
       case 2:
         pixel = *((Uint16 *)(offset));
         SDL_GetRGB (pixel, src->format, &r, &g, &b);
	 break;
       case 3:
         r = *((offset)+src->format->Rshift/8);
         g = *((offset)+src->format->Gshift/8);
         b = *((offset)+src->format->Bshift/8);
	 break;
       case 4:
         pixel = *((Uint32 *)(offset));
	 SDL_GetRGB (pixel, src->format, &r, &g, &b);
         break;
       default:
	 printf("Error: Couldn't understand this  image format, does it ");
         printf("have a weird colordepth or something?\n\n");
	 exit(-1);
	 break;
       }

       get_color_code (r, g, b, htmlcolor);

       switch (inputfile_type) {
       case TEXT: 
	 if ( read (tfile, &ch, 1) == 1 ) {
	   /* Skip illegal chars */
	   if ( is_illegal(ch) ) { 
	     while ( is_illegal(ch) ) {
	       if (read (tfile, &ch, 1) != 1) lseek (tfile, 0, SEEK_SET);
	     }
	   } 
	   if (ch != '\n') {
	     write (fp, html1, get_string_size(html1) );
	     write (fp, htmlcolor, get_string_size(htmlcolor) );
	     write (fp, html2, get_string_size (html2) );
	     write(fp, (char*)&ch, 1);
	     write (fp, html3, get_string_size (html3) );
	   }
	 } else { /* The text file is at eof, begin all over... */
	   lseek (tfile, 0, SEEK_SET);
	   if ( read (tfile, &ch, 1) == 1) {
	     /* Skipping illegal chars... */
	     if ( is_illegal (ch) ) {
	       while ( is_illegal(ch) ) {
		 if (read (tfile, &ch, 1) != 1) lseek (tfile, 0, SEEK_SET);
	       }
	   }
	     if (ch != '\n') {
	       write (fp, html1, get_string_size(html1) );
	       write (fp, htmlcolor, get_string_size(htmlcolor) );
	       write (fp, html2, get_string_size (html2) );
	       write(fp, (char*)&ch, 1);
	       write (fp, html3, get_string_size (html3) );
	     }
	   }
	 }
	 break;
       case HTML:
	 if ( read (tfile, &ch, 1) == 1 ) {
	   /* check if it is a html tag */
	   if (ch == '<') {
	       write (fp, (char*)&ch, 1);
	     do {
	       if (read (tfile, &ch, 1) != 1) lseek (tfile, 0, SEEK_SET);
	       write (fp, (char*)&ch, 1);
	     } while (ch != '>');
	   }
	   /* Skip illegal chars */
	   if ( is_illegal(ch) ) { 
	     while ( is_illegal(ch) ) {
	       if (read (tfile, &ch, 1) != 1) lseek (tfile, 0, SEEK_SET);
	     }
	   } 
	   if (ch != '\n') {
	     write (fp, html1, get_string_size(html1) );
	     write (fp, htmlcolor, get_string_size(htmlcolor) );
	     write (fp, html2, get_string_size (html2) );
	     write(fp, (char*)&ch, 1);
	     write (fp, html3, get_string_size (html3) );
	   }
	 } else { /* The text file is at eof, begin all over... */
	   lseek (tfile, 0, SEEK_SET);
	   if ( read (tfile, &ch, 1) == 1) {
	     /* check for tags */
	     if (ch == '<') {
	       write (fp, (char*)&ch, 1);
	       do {
		 if (read (tfile, &ch, 1) != 1) lseek (tfile, 0, SEEK_SET);
		 write (fp, (char*)&ch, 1);
	       } while (ch != '>');
	     }
	     /* Skipping illegal chars... */
	     if ( is_illegal (ch) ) {
	       while ( is_illegal(ch) ) {
		 if (read (tfile, &ch, 1) != 1) lseek (tfile, 0, SEEK_SET);
	       }
	     }
	     if (ch != '\n') {
	       write (fp, html1, get_string_size(html1) );
	       write (fp, htmlcolor, get_string_size(htmlcolor) );
	       write (fp, html2, get_string_size (html2) );
	       write(fp, (char*)&ch, 1);
	       write (fp, html3, get_string_size (html3) );
	     }
	   }
	 }
	 
	 break;
     default:
       /* Generate a ramdom char */
       ch = 65 + rand()%60;
       // get_color_code (r, g, b, htmlcolor);
       /* Write a font info  */
       write (fp, html1, get_string_size(html1) );
       write (fp, htmlcolor, get_string_size(htmlcolor) );
       write (fp, html2, get_string_size (html2) );
       write (fp, (char*)&ch, 1);
       
       break;
     }
   }
   write (fp, "<BR>\n", 4);
   }
   /* write footer */
   write (fp, footer, get_string_size (footer) );
}
    
void get_color_code (int r, int g, int b, char* colorcode)
{
  char hex[2];


  colorcode[0] = '#';

  /* red */
  dec2hex (r, (char*)&hex);
  colorcode[1] = hex[0];
  colorcode[2] = hex[1];
  /* green */
  dec2hex (g, (char*)&hex);
  colorcode[3] = hex[0];
  colorcode[4] = hex[1];
  /* blue */
  dec2hex (b, (char*)&hex);
  colorcode[5] = hex[0];
  colorcode[6] = hex[1];
  
  colorcode[7] = '\0';

}


void dec2hex (int dec, char* hex)
{
  int dec1, dec2;

  dec1 = dec/16;
  dec2 = dec%16;
  
  switch (dec1) {
  case 0:
    hex[0] = '0';
    break;
  case 1:
    hex[0] = '1';
    break;
  case 2:
    hex[0] = '2';
    break;
  case 3:
    hex[0] = '3';
    break;
  case 4:
    hex[0] = '4';
    break;
  case 5:
    hex[0] = '5';
    break;
  case 6:
    hex[0] = '6';
    break;
  case 7:
    hex[0] = '7';
    break;
  case 8:
    hex[0] = '8';
    break;
  case 9:
    hex[0] = '9';
    break;
  case 10:
    hex[0] = 'A';
    break;
  case 11:
    hex[0] = 'B';
    break;
  case 12:
    hex[0] = 'C';
    break;
  case 13:
    hex[0] = 'D';
    break;
  case 14:
    hex[0] = 'E';
    break;
  case 15:
    hex[0] = 'F';
    break;
  }


  switch (dec2) {
  case 0:
    hex[1] = '0';
    break;
  case 1:
    hex[1] = '1';
    break;
  case 2:
    hex[1] = '2';
    break;
  case 3:
    hex[1] = '3';
    break;
  case 4:
    hex[1] = '4';
    break;
  case 5:
    hex[1] = '5';
    break;
  case 6:
    hex[1] = '6';
    break;
  case 7:
    hex[1] = '7';
    break;
  case 8:
    hex[1] = '8';
    break;
  case 9:
    hex[1] = '9';
    break;
  case 10:
    hex[1] = 'A';
    break;
  case 11:
    hex[1] = 'B';
    break;
  case 12:
    hex[1] = 'C';
    break;
  case 13:
    hex[1] = 'D';
    break;
  case 14:
    hex[1] = 'E';
    break;
  case 15:
    hex[1] = 'F';
    break;
  }
  
}

int is_illegal (char ch)
{
  if (ch <= 65) return 1;
  if (ch >= 125) return 1;
  if (ch == ' ') return 1;
  if (ch == '<') return 1;
  if (ch == '>') return 1;

  return 0;
}

void makeheader (char* header)
{
  strcpy (header, "<HTML><HEAD><TITLE>");
  if (title) {
    strncat (header, title, get_string_size (title));
  } else {
    strcat (header, "-= Generated by Aquila's image to html converter =-");
  }
  
  strcat (header, "</TITLE><BODY BGCOLOR=");
  
  if (bgcolor) {
    strncat (header, bgcolor, get_string_size (bgcolor));
  } else {
    strcat (header, "#000000");
  }
  strcat (header, "><FONT FACE=");

  if (font) {
    strncat (header, font, get_string_size (font));
  } else {
    strcat (header, "courier");
  }
  
  strcat (header, " SIZE=");
  
  if (fontsize) {
    strncat (header, fontsize, get_string_size (fontsize));
  } else {
    strcat (header, "-6");
  }
  
  strcat (header, ">");

}
    




