#include "bitmap.h"

//please fix it properly to do RLE.
void bmp_read_header(FILE *fp,bmpheader *bmph)
{
  unsigned char buffer[54];
  fread(buffer,1,54,fp);

#ifdef BMP_DEBUG
  printf("First 2 letter %c%c\n",buffer[0],buffer[1]);
#endif
  
  bmph->BMP[0]=buffer[0];
  bmph->BMP[1]=buffer[1];

  bmph->filesize=buffer[2]+(buffer[3]<<8);
  bmph->filesize+=(buffer[4]<<16)+(buffer[5]<<24);

#ifdef BMP_DEBUG
  printf("File size=%d\n",bmph->filesize);
#endif

  bmph->width=buffer[18]+(buffer[19]<<8)+(buffer[20]<<16)+(buffer[21]<<24);

#ifdef BMP_DEBUG
  printf("Width of picture was %d\n",bmph->width);
#endif
  
  bmph->height=buffer[22]+(buffer[23]<<8)+(buffer[24]<<16)+(buffer[25]<<24);

#ifdef BMP_DEBUG
  printf("Height of picture was %d\n",bmph->height);
#endif

  bmph->bitplanes=buffer[26]+(buffer[27]<<8);
  bmph->colordepth=buffer[28]+(buffer[29]<<8);

#ifdef BMP_DEBUG
  printf("picture has Colordepth=%d and bitplanes=%d\n",bmph->colordepth,bmph->bitplanes);
#endif

  bmph->pixelsize=buffer[34]+(buffer[35]<<8)+(buffer[36]<<16)+(buffer[37]<<24);

#ifdef BMP_DEBUG
  printf("Pixelsize=%d\n",bmph->pixelsize);
#endif

}

void bmp_info_header(bmpheader bmph)
{
    printf("BMP=%c%c\n",bmph.BMP[0],bmph.BMP[1]);
    printf("filesize=%d\n",bmph.filesize);
    printf("width=%d\n",bmph.width);
    printf("height=%d\n",bmph.height);
}

void  bmp_info_pixel(pixel sample)
{
  printf("RED=%d GREEN=%d BLUE=%d\n",sample.red,sample.green,sample.blue);
}

int message_size(char *message)
{ 
  return (strlen(message)*8+16);//See message.h for details
}

/*
  File Copying mechanism
*/
int file_copy(FILE *fdest,FILE *fsrc)
{
  unsigned char pixelletter;
  int count=0;
  while(!feof(fsrc))
    {
      count++;
      fread(&pixelletter,1,1,fsrc);
      fwrite(&pixelletter,1,1,fdest);
    }    
  return count;
}



/*
  Do Encoding for each of the letters.
*/
int encode_message_to_file(FILE *fdest, FILE *fsrc,char *message)
{
  int count=0;
  int length=0;
  int index=0;

  unsigned char letter=0;
  unsigned char insert_letter=0;
  unsigned char pixelletter=0;
  
  char *buffer=NULL;
  
  length=strlen(message);

  if(length >= 0)
    {
      buffer=(char *)calloc(2+length,sizeof(char));      
      memcpy(buffer+2,message,length);

      //protocol for length
      buffer[0]=length&0xff;
      buffer[1]=(length&0xff00)>>8;

#ifdef DEBUG_BMP
      printf("|_ \n");
      write(1,buffer,length+2);
      printf(" _|\n");      
#endif
      length=length+1;//fixed the junk endings problem.
    }
  else
    buffer=message;
  
  for(count=0;count<length;count++)
    {
      //Enter This Region only when we need to ENCODE the Message.
      letter=buffer[count];      
      for(index=0;index<8;index++)
	{
	  if ((letter&(1<<(index)))==(1<<(index)))
	    {
	      insert_letter=1;
#ifdef DEBUG_BMP
	      printf("1");
#endif
	    }
	  else
	    {
	      insert_letter=0;
#ifdef DEBUG_BMP
	      printf("0");
#endif
	    }
	  fread(&pixelletter,1,1,fsrc);
	  pixelletter=pixelletter&0xfe;//cut off the last bit

	  if (insert_letter==1)
	    pixelletter=pixelletter|0x01;

	  fwrite(&pixelletter,1,1,fdest);
	}

#ifdef DEBUG_BMP
      printf("\n");
#endif
    }
  if(length != 2)
    free(buffer);
  return length*8;
}

/*
  Do Decoding for each of the letters.
*/
int decode_message_to_file(FILE *fdest, FILE *fsrc,char *message,int length)
{
  int tempval=-1;
  int count=0;
  int value=0;
  unsigned char letter=0;
  
  if(length!=2)
    {
      //get the length. fsrc is automatically moved in the stream as desired.
      //so we dont need to keep track of this pointer.
      decode_message_to_file(stdout,fsrc,message,2);

      //little endian
      length=message[0]+(message[1]<<8);
      length=length-1;

#ifdef DEBUG_BMP
      printf("Length=>%d\n",length);
#endif
    }

  tempval=0;
  while(tempval < length)
    {
      value=0;
      for(count=0;count<8;count++)
	{
	  fread(&letter,1,1,fsrc);
	  if ((letter&0x01)==1)
	    {
#ifdef DEBUG_BMP
	      printf("1");
#endif
	      value=value|(1<<count);
	    }
	  else
	    {
	      value=value|(0<<count);
#ifdef DEBUG_BMP
	      printf("0");
#endif
	    }
	}
#ifdef DEBUG_BMP
      printf("\t %3d %c\n",value,value);
      if(length!=2)
	fprintf(fdest,"|_ %c _|\n",value);
#endif

      message[tempval]=value;
      tempval++;
    }

#ifdef DEBUG_BMP
  printf("%d\n",tempval);
#endif

  return tempval;
}
