/* 
   Copyright (C) 1999 E. H. Haley

   trog.c just averages them.

 */

#include <stdio.h>
#include <stdlib.h>
#include <jpeglib.h>
#include "lib/loadj.h"
#include <GL/glut.h>
#include <X11/Xlib.h>
#include "lib/tile.h"
#include <math.h>

int dw,dh;
tile *dcont; //display_contender
tfile tatch;
int nlayers;

void init(int aardc, char **aardv)
{
  int check, i,j,k,level, side, logw, w,h,c;
  FILE *matchfile;

  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  glReadBuffer(GL_FRONT);

  if (aardc<2) exit(0);
  if ((matchfile=fopen(*++aardv,"r"))==NULL)
    { fprintf(stderr, "can't open %s\n",*aardv); exit(1); }

  check=fread(&tatch,sizeof(tfile),1,matchfile);
  printf("%d\n",tatch.nnodes);
  side=dw=dh=tatch.side;

  dcont=(tile *)malloc(tatch.nnodes*sizeof(tile));
  check=fread(dcont,tatch.nnodes*sizeof(tile),1,matchfile);
  fclose(matchfile);


  logw = 0;
  while((side>>=1)>0) logw++;
  nlayers=logw-3;

}


void display(void)
{
  int p,w,h,c, x,y, l,i,j,k, check, zint,exp, level, temp;
  float zoom;
  JSAMPLE *arr, *blayer;
  float *norm, *total;

  blayer=(JSAMPLE *)malloc(3*dw*dh*sizeof(JSAMPLE));
  norm=(float *)calloc(3*dw*dh, sizeof(float));
  total=(float *)calloc(3*dw*dh, sizeof(float));
  
  p=-1;
  level= nlayers;
  for(l=1; l>0; l<<=1) //forever
    {
      level--;
      for(i=0; i<l; i++)
	for(j=0; j<l; j++)
	  {
	    if (++p>=tatch.nnodes)
	      {
		for(i=0; i<dw; i++)
		  for(j=0; j<dh; j++)
		    for(k=0; k<3; k++)
		      blayer[3*(dw*j+i)+k]
			= (JSAMPLE)(total[3*(dw*j+i)+k] / 
				    (norm[dw*j+i] + 0.01));
		glPixelZoom(1.0,1.0);
		glRasterPos2i(0,0);
		glDrawPixels(dw,dh, GL_RGB, GL_UNSIGNED_BYTE, blayer);
		glFlush();
		
		free(norm); free(total); free(blayer);
		return; 
	      }
	    
	    exp = dcont[p].exp;
	    zint = 1 << (exp>0 ? exp : -exp);
	    zoom = exp>0 ? (float)zint : 1.0/(float)zint;
	    glPixelZoom(zoom,zoom);
	    glRasterPos2i(i*dw/l, j*dh/l);
	    
	    if((arr=rjf(dcont[p].fname,&w,&h,&c))!=NULL)
	      glDrawPixels(w,h, c<2?GL_LUMINANCE:GL_RGB,GL_UNSIGNED_BYTE,arr);
	    
	    printf("p=%d; f=%s; orig w=h=%d; want=%d; exp=%d; score=%d\n",
		   p,
		   dcont[p].fname, 
		   w,
		   dw/l,
		   dcont[p].exp,
		   dcont[p].score);
	    
	    fflush(stdout);
	    free(arr);
	  }
      glReadPixels(0,0,dw,dh,
		   GL_RGB, GL_UNSIGNED_BYTE,
		   blayer);
      
      for(i=0; i<dw; i++)
	for(j=0; j<dh; j++)
	  {
	    for(k=0; k<3; k++)
	      {
		total[3*(dw*j +i)+k]
		  += (float) blayer[3*(dw*j +i)+k];
	      }
	    norm[dw*j +i] += 1;
	  }
 
   }      
  
}

  
void mouse(int button, int state, int x, int y)
{
  free(dcont);
  exit(0);
}


int main(int aardc, char **aardv)
{
  init(aardc, aardv);
  glutInit(&aardc, aardv);

  glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
  glutInitWindowSize(dw,dh);
  glutCreateWindow(aardv[0]);
  glutDisplayFunc(display);
  glutMouseFunc(mouse);

  glViewport(0,0, (GLfloat)dw,(GLfloat)dh);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluOrtho2D(0.0, (GLfloat)dw, 0.0, (GLfloat)dh);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

  glutMainLoop();
  exit(0);
}

