/// Evolver Copyright 2000, Morgan McGuire
/// matrix@alum.mit.edu   http://graphics3d.com/matrix
import java.util.Random;

/**
 * A "stable" noise function.  This always returns the same noise
 * function, and is locally continuous so that it is relatively size
 * independent.
 */
public class Noise extends ImageOperator implements ELOperator 
{
  public Noise()
  {
    filename = "noise1.jpg";
  }

  synchronized protected void waitForImage()
  {
    if (image == null) {
      System.out.print("(Loading " + filename + ")");
      image = new ELMatrix(filename);
      extendRange();
      create128();
    }
  }

  protected void extendRange() 
  {
    // Rescale
    float red[] = image.red;
    float grn[] = image.grn;
    float blu[] = image.blu;
    for(int i = image.numElements - 1; i >= 0; i--) {
      red[i] = red[i] * 2.0f - 1.0f;
      grn[i] = grn[i] * 2.0f - 1.0f;
      blu[i] = blu[i] * 2.0f - 1.0f;
    }
  }


  public Noise(boolean rand)
  {
    int d = 256;
    Random random = new Random(12345);

    ELMatrix temp = ELMatrix.alloc(d, d);
    image = ELMatrix.alloc(d, d);

    for(int y = 0; y < d; y++) {
      for(int x = 0; x < d; x++) {
        float value = random.nextFloat() * 10.0f - 5.0f;
        temp.set(x, y, value, value, value);
      }
    }
    
    // Blur the noise so it has some cohesion.
    Blur blur = new Blur();
    blur.apply(new ELMatrix[]{temp}, image, new ELEnvironment());

    // Free the temp variable
    temp = temp.free();
  }

  public String name()
  {
    return "Noise";
  }

  public String description()
  {
    return "A smooth noise function";
  }  
}
