#include <iostream.h>
#include <qimage.h>
#include <qstring.h>
#include <qcolor.h>
#include <stdio.h>

int main(int argc, char **argv) {
  
  // manual of the command
  if (argc == 1) {
  err:
    printf("-------------------------------------------------------\n"
	   "filmedian: Filter using method median\n\n"
	   "usage : filmedian [-w W] in out\n\n"
	   "\t-w W    : Size of filtering window, must be odd (1..19), default 3\n"
	   "\tin      : Input image\n"
	   "\tout     : Output image\n");
    return 0;
  }

  // main parameters
  int W = 3;
  QString input("");
  QString output("");

  // ----- Feed the parameter -----
  int count = 1;
  int ob_param = 0; // parametre obligatoire
  while (count < argc) {
    if (strcmp(argv[count], "-w") == 0) {
      if (count + 1 >= argc) goto err;
      W = atoi(argv[count + 1]);
      if (W < 1 || W > 19 || W % 2 == 0) goto err;
      count = count + 2;
    }
    else {
      switch (ob_param) {
      case 0: input = argv[count];
      case 1: output = argv[count];
      }
      ob_param++;
      count++;
    }
  }

  if (ob_param != 2) goto err;


  // ----- Algorithm -----
  QImage in, out;
  if (in.load(input) == false) {
    printf("Cannot load image\n");
    return 1;
  }

  int maxX = in.width();
  int maxY = in.height();

  out = QImage(maxX, maxY, 32);

  int i, j, k, x, y; 

  QRgb color;
  int gray;

  int list[400];

  for (x = 0; x < maxX; x++) 
    for (y = 0; y < maxY; y++) {
      
      // add the elements inside the window to the list
      k = 0;
      for (i = -W / 2; i <= W / 2; i++)
	if (x + i >= 0 && x + i < maxX)
	  for (j = -W / 2; j <= W / 2; j++)
	    if (y + j >= 0 && y + j < maxY) {
	      color = in.pixel(x + i, y + j);
	      gray = qGray(color);
	      list[k++] = gray;
	    }
		 
      // sort the list
      for (i = 0; i < k - 1; i++)
	for (j = i + 1; j < k; j++)
	  if (list[i] > list[j]) {
	    gray = list[i];
	    list[i] = list[j];
	    list[j] = gray;
	  }

      // change the current element to the median of the list
      gray = list[k / 2];
      out.setPixel(x, y, qRgb(gray, gray, gray));
    }

  out.save(output, "BMP", 100);
}

