import java.awt.*;

public class ImArray {
    int height, width;
    int im[], oim[];
    double neigh[];
    Image image;

  ImArray(int h, int w, int d[]){
    height = h;
    width = w;
    im = d;
    oim = null;
    neigh = genNeighborhood(d, h, w);
  }

  ImArray(int h, int w, int d[], int i[]){
    height = h;
    width = w;
    im = d;
    oim = i;
    neigh = genNeighborhood(d, h, w);
  }

  ImArray(int h, int w, int d[], int i[], Image jim){
    height = h;
    width = w;
    im = d;
    oim = i;
    image = jim;
    neigh = genNeighborhood(d, h, w);
  }

    static double[] genNeighborhood(int d[], int h, int w){
	int mypix, tot=0, sqtot=0, ct=0;
	double avg;
	double totvar = 0;
	double ne[] = new double[d.length];

	for(int x = 0; x < w; x++) {
	    for(int y = 0; y < h; y++){
		for(int dx = -1; dx<2;dx++){
		    for(int dy = -1; dy<2;dy++){
			if((y+dy < 0) ||
			   (y+dy >= h) ||
			   (x+dx >= w) ||
			   (x+dx < 0))
			    continue;
			
			mypix = d[(x+dx)+((y+dy)*w)];
			sqtot += mypix*mypix;
			tot += mypix;
			ct++;
		    }
		}
		
		ne[x+(y*w)] = Math.abs((sqtot-(tot*tot))/ct);
	    }
	}
	return ne;
    }

  ImArray shrink(int s){
    int nh = ((int) (height/s));
    int nw = ((int) (width/s));
    int[] nd = new int[(nh+1)*(nw+1)];
    for(int x=0;x<nw;x++){
      for(int y=0;y<nh;y++){
	nd[x+(nw*y)] = 0;
      }
    }    
    for(int x=0;x<width;x++){
      for(int y=0;y<height;y++){
	nd[((int) (x/s)) + (((int) (y/s))*nw)]  += im[x+(width*y)]/(s*s);
      }
    }
    return new ImArray(nh, nw, nd);
  }

  public static double imageDifference(ImArray im1, ImArray im2, cornerTransform ct){
    double diff = 0;
    double pixct = 0;
    double borderweight = 1;

    for(int ctx=0;ctx<(im1.width);ctx++){
      for(int cty=0;cty<(im1.height);cty++){
	int ttx, tty;
	ttx = ct.x(ctx, cty);
	tty = ct.y(ctx, cty);
	if((ttx >= 0) && (tty >= 0) &&
	   (ttx < im2.width) && (tty < im2.height)
	   && (im2.im[ttx+(tty*im2.width)] != 0)){
	  /*	  if((ctx > (.9*im1.width)) || (cty > (.9*im1.height)) ||
	     (ctx < (.1*im1.width)) || (cty < (.1*im1.height)) ||
	     (ttx < (.1*im2.width)) || (tty < (.1*im2.height)) ||
	     (ttx > (.9*im2.width)) || (tty > (.9*im2.height))){
	  */
	    borderweight = im1.neigh[ctx+(im1.width*cty)];
	    //	    System.out.println("Borderweight: "+borderweight+" at "+ctx+", "+cty);
	    double vtmp = Math.abs(im1.im[ctx+(cty*im1.width)]-
				   im2.im[ttx+(tty*im2.width)]);

	    diff += borderweight*vtmp*vtmp;
	    pixct+=borderweight;
	}
	else{
	  diff += 0;
	}
      }
    }
    return diff/pixct;
  }


}

