// (c) 2000 Benjamin Fry, MIT Media Laboratory, fry@media.mit.edu
// Aesthetics + Computation Group, Massachussetts Institute of Technology


import java.io.*; // for read/write to/from disk


// evaluate everything and store it in ram (fastest)
// only stores a half matrix, to reflect the mirroring about x==y
public class SimilarityMatrixCache extends SimilarityMatrix {
  float data[];
  int offset[];


  public SimilarityMatrixCache(MicroArray ma, int metric) throws Exception {
    super(ma, metric);

    int off = 0;
    offset = new int[gcount];
    for (int i = 1; i < gcount; i++) {
      offset[i] = off;
      off += i;
    }

    int percent = -1;
    data = new float[off];
    for (int i = 0; i < gcount; i++) {
      for (int j = 0; j < i; j++) {
	data[offset[i] + j] = super.get(i, j);
      }
      percent = Utilities.reportPercent(offset[i] + gcount, 
					offset[gcount-1] + gcount, percent);
    }

    System.out.println("writing cache.sim...");
    try {
      DataOutputStream raf = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("cache.sim")));
      raf.writeInt(ecount);
      raf.writeInt(gcount);
      for (int i = 0; i < gcount; i++) raf.writeInt(offset[i]);
      raf.writeInt(data.length);
      for (int i = 0; i < data.length; i++) raf.writeFloat(data[i]);
      raf.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
    System.out.println("...done writing");

    /*
    System.out.println("writing cache.sim.xls...");
    //DataOutputStream stream = 
    //new DataOutputStream(new FileOutputStream("similarity.xls"));
    PrintStream stream = 
      new PrintStream(new FileOutputStream("cache.sim.xls"));
    for (int j = 0; j < gcount; j++) {
      for (int i = 0; i < gcount; i++) {
	//stream.writeFloat(get(i, j));
	float a = get(i, j);
	//stream.print((a == Float.NaN) ? "\t" : (a + "\t"));
	stream.print(Float.isNaN(a) ? "\t" : (a + "\t"));
	//stream.print(get(i, j) + "\t");
      }
      stream.println();
    }
    stream.close();
    System.out.println("...done writing");
    */    
  }


  public SimilarityMatrixCache(String filename) throws Exception {
    System.out.println("reading... " + filename);
    DataInputStream raf = new DataInputStream(new BufferedInputStream(new FileInputStream(filename)));
    ecount = raf.readInt();
    gcount = raf.readInt();
    offset = new int[gcount];
    for (int i = 0; i < gcount; i++) offset[i] = raf.readInt();
    data = new float[raf.readInt()];
    for (int i = 0; i < data.length; i++) {
      data[i] = raf.readFloat();
    }
    raf.close();
    System.out.println("...done reading");
  }


  public float get(int i, int j) {
    if (i == j) return 1;
    return (i > j) ? data[offset[i] + j] : data[offset[j] + i];
  }
}

