/**
 * MBM_C64 covert an image to Multicolor bitmap mode
 *
 * The input file must be an not compressed TGA format
 * We use only one bacground color for all the image
 */

#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>

#define DIMX 160
#define DIMY 200
#define NCOL 16

typedef unsigned short int byte;

// the image array
byte image[DIMX][DIMY];
byte best;                   // best color
byte bank1[DIMX*DIMY/8];     // bank of memory with color 11 pixels
byte bank2[DIMX*DIMY/8];     // bank of memory with color 01 and 10 pixels
byte bank3[DIMX*DIMY/8];     // bank of memory with bits data
ofstream *fo1;                // file for bank 1 output
ofstream *fo2;                // file for bank 2 output
ofstream *fo3;                // file for bank 3 output
ofstream *fo4;                // file for backgroud color


/**
 * Read the TGA file image with the passed name
 *
 * @param name the name of the file
 */
void readImage(char *name) {
  int i,j;
  ifstream in(name, ios::in);
  in.seekg(0x42, ios::beg);

  for (int j=0; j<DIMY; j++) {
    for (int i=0; i<DIMX; i++) {
      //in >> image[i][j];
      image[i][j]=(in.get() & 15);
    }
  }
}

/**
 * Calculate the most used color for this image
 *
 * @return the nuber of the most used color for this image
 */
int getMostUsed() {
  int i,j;
  byte best;        // best color index
  int max;          // max conter
  int color[NCOL];  // counter of the colors

  // init color counter
  for (i=0; i<NCOL; i++) {
    color[i]=0;
  }

  // increment colors counter
  for (i=0; i<DIMX; i++) {
    for (j=0; j<DIMY; j++) {
      color[image[i][j]]++;
    }
  }

  //choose the max color
  cout << "Count how much a color is used:\n";
  max=0;
  best=0;
  for (i=0; i<NCOL; i++) {
    if (color[i]>max) {
      max=color[i];
      best=i;
    }
    cout << "Color " << i << " used " << color[i] << " times\n";
  }
  cout << "Best color for background is " << best << endl;
  return best;
}

/**
 * Codify a block 8x8 of the image
 *
 * @param x the x coord of the char block
 * @param y the y coord of the char block
 */
void codifyBlock(int x, int y) {
  int i,j;
  byte out;            // output byte
  int color[NCOL];
  byte col01;          // color for 01
  byte col10;          // color for 10
  byte col11;          // color for 11
  int colc[3]={0,0,0}; // color count
  byte coln[3]={0,0,0};// color number
  byte colnum;         // color number actual processing

  //count the color used in the block
  for (i=0; i<NCOL; i++) {
    color[i]=0;
  }
  for (j=0; j<8; j++) {    //row scan
    for (i=0; i<4; i++) {  //col (pixels) scan
      color[image[x*4+i][y*8+j]]++;
    }
  }

  cout << "in block " << x << ", " << y << endl;
  for (i=0; i<NCOL; i++) {
    if (color[i]!=0) {
      cout << "Color " << i << " used " << color[i] << " times\n";
      if (i!=best) {
        if (color[i]>=colc[0]) {
          colc[2]=colc[1];
          colc[1]=colc[0];
          colc[0]=color[i];
          coln[2]=coln[1];
          coln[1]=coln[0];
          coln[0]=i;
        } else {
            if (color[i]>=colc[1]) {
              colc[2]=colc[1];
              colc[1]=color[i];
              coln[2]=coln[1];
              coln[1]=i;
            } else {
                if (color[i]>=colc[2]) {
                  colc[2]=color[i];
                  coln[2]=i;
                }
              }
          }
      }
    }
  }
  cout << "use color: " << coln[0] << " " << coln[1] << " " << coln[2] << endl << endl;
  col11=coln[0];
  col10=coln[1];
  col01=coln[2];

  //write info to output files
  fo1->put(col11);
  fo2->put((col01<<4)+col10);
  cout <<((col01<<4)+col10) << endl;

  for (j=0; j<8; j++) {    //row scan
    out=0;
    for (i=0; i<4; i++) {  //col (pixels) scan
      colnum=image[x*4+i][y*8+j];
      out<<=2;
      if (colnum==best) {
        //out+=0x00;
      } else
      if (colnum==col11){
        out+=0x03;
      } else
      if (colnum==col10) {
        out+=0x02;
      } else
      if (colnum==col01) {
        out+=0x01;
      } else {               // choose a color fot this case
          out+=1+(int)(3.0*rand()/(RAND_MAX+1.0));
        }
    }
    fo3->put(out);
  }
}

void codifyImage() {
  int x,y;

  for (y=0; y<DIMY/8; y++) {
    for (x=0; x<DIMX/4; x++) {
      codifyBlock(x,y);
    }
  }
}

int main(int argc, char **argv) {
  if (argc<1) return 1;

  cout << "MBM_C64 0.1: convert a TGA not compressed 160*200 image in C64 raw data\n";

  readImage(argv[1]);
  fo1=new ofstream("b1.raw", ios::out);
  fo2=new ofstream("b2.raw", ios::out);
  fo3=new ofstream("b3.raw", ios::out);
  fo4=new ofstream("b4.raw", ios::out);

  fo4->put(best=getMostUsed());


  codifyImage();

  delete fo1;
  delete fo2;
  delete fo3;
  delete fo4;
  getMostUsed();

  return 0;
}

