#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mat_util.h"
#include "ppm.h"
#include <assert.h>

// program gets passed ppm image filename  and blur amount
void usage();
void blurfunc( Var *Image, int blur);

int main(int argc, char *argv[]) {
  char imagename[100];
  unsigned char *tmpptr;
  int blur;
  Var myImage;

  if (argc != 3) {
	usage();
        exit(0);
  }
 
// first character of string only
//(subtract ascii value of zero) ...  blur = *argv[2] - '0';
  blur = atoi(argv[2]);
  sprintf(imagename, "%s", argv[1]);  

  fprintf(stderr,"%s: imagename = %s, blur = %d; ... ",argv[0],imagename,blur);

  // if blur is not odd
  if ((blur % 2) == 0) {
	usage();
	exit(0);
  }
  // load ppm file into Image
  tmpptr =  (unsigned char *)load_pnm_file(imagename, &myImage); 
  myImage.image = tmpptr;

  switch( myImage.image_type ) {
   case GREY_SCALE: fprintf(stderr,"%s is a pgm\n", imagename); break;
   case RGB24     : fprintf(stderr,"%s is a ppm\n", imagename); break;
   case GREY_PDM  : fprintf(stderr,"%s is a grayscale pdm\n", imagename); break;
   case RGB_PDM   : fprintf(stderr,"%s is a color pdm\n", imagename); break;
   case GREY_PLM  : fprintf(stderr,"%s is a greyscale plm\n", imagename); break;
   case RGB_PLM   : fprintf(stderr,"%s is a color plm\n", imagename); break;
   default        : fprintf(stderr,"blur couldn't determine type of input\n");
                      return -1;
  }

  // blur it 
  blurfunc(&myImage, blur );
 
  // write image back to disk
  save_pgm_file(&myImage, imagename);  

  return(1);
}

void blurfunc( Var *Image, int blur)
{
  Var *ANS, *ANS2;
  int i,j,k;
  int tmp;
  ANS = (Var *)calloc(1, sizeof(Var));
  ANS2 = (Var *)calloc(1, sizeof(Var));
  init_var(ANS, Image->name, Image->M, Image->N,
           IMAGE, GREY_SCALE);
  init_var(ANS2, Image->name, Image->M, Image->N,
           IMAGE, GREY_SCALE);

  for( i=0 ; i<Image->M ; i++ )
  {
    for( j=0 ; j<Image->N ; j++ )
    {

      tmp = 0;
      if( j<blur/2 )
      {
         for( k=-j; k<=blur/2; k++ )
         {
//printf("i=%d, j=%d, k=%d val=%d\n",i,j,k,Image->image[i*Image->N + j + k]);
           tmp+=Image->image[i*Image->N +j +k];
         }
         ANS->image[i*Image->N + j] = (unsigned char)(tmp/(j+1+blur/2));
//printf("div by %d\n", (unsigned char)(j+1+blur/2) );
      }
      else if( j>=Image->N-blur/2 ) 
      {
         for( k=-blur/2 ; k<Image->N-j ; k++ )
         {
//printf("i=%d, j=%d, k=%d val=%d\n",i,j,k,Image->image[i*Image->N + j + k]);
           tmp+=Image->image[i*Image->N +j +k];
         }
         ANS->image[i*Image->N + j] = (unsigned char)(tmp/(Image->N-j+blur/2));
//printf("div by %d\n", (unsigned char)(Image->N-j+blur/2) );
      }
      else  
      {  
         for( k=-blur/2 ; k<=blur/2 ; k++ )
         {
           tmp += Image->image[i*Image->N + j + k];
//   printf("i=%d, j=%d, k=%d val=%d\n",i,j,k,Image->image[i*Image->N + j + k]);
         }
         ANS->image[i*Image->N + j] = (unsigned char)(tmp/blur);
  //    printf(" result = %d\n", ANS->image[i*Image->N + j]);
         assert(ANS->image[i*Image->N+j] < 256 );
         
      }
    }
  }

  for( i=0 ; i<Image->N ; i++ )
  {
    for( j=0 ; j<Image->M ; j++ )
    {
      if( j<=blur/2 || j>Image->M-blur/2 ) 
      { }
      else  
      {
         tmp = 0;
         for( k=-blur/2 ; k<=blur/2 ; k++ )
         {
           tmp += ANS->image[j*Image->M + i + k];
//      printf("2: i=%d, j=%d, k=%d\n",i,j,k);

         }
         ANS2->image[j*Image->N + i] = (unsigned char)(tmp/blur);
      }
    }
   
  }   

  /* - - Copy answer to original image - - */
  copy_image(ANS, Image);
  
  /* - - Free OLD image - - */
  free(ANS2->image);
  free(ANS->image);
  
}

void usage() {
  fprintf(stderr, "Usage:  blur [image] [blur amount]\n");
  fprintf(stderr, "[image] - the name of the ppm image to be blurred\n");
  fprintf(stderr, "[blur amount] - an odd valued blur radius\n");
}

