package ip.hak;

import java.awt.*;
import java.awt.image.ColorModel;
import java.awt.image.MemoryImageSource;

public class Mountain
    extends ip.gui.frames.ClosableFrame {
  Image img = null;
  boolean paintOn = false;

  public Mountain(String title) {
    super(title);
  }

  public static void main(String args[]) {
    Mountain m = new Mountain("Mountain Generator");
    m.start();
  }

  public void paint(Graphics g) {
    if (!paintOn)
      return;

    int w = img.getWidth(this);
    int h = img.getHeight(this);

    setSize(20 + w, 30 + h);
    setVisible(true);
    g.drawImage(img, 10, 20, w, h, this);
  }

  public void start() {
    makeRandomImage();
    takeDHT();
    multOneOnF();
    takeIDHT();
    threeDImage();
  }

  int n = 256;
  short r[][] = new short[n][n];
  short g[][] = new short[n][n];
  short b[][] = new short[n][n];

  float rf[][] = new float[n][n];
  float gf[][] = new float[n][n];
  float bf[][] = new float[n][n];

  public void makeRandomImage() {
    for (int x = 0; x < n; x++)
      for (int y = 0; y < n; y++) {
        r[x][y] = (short) (Math.random() * 256);
        g[x][y] = (short) (Math.random() * 256);
        b[x][y] = (short) (Math.random() * 256);
      }
  }

  public void takeDHT() {
    for (int x = 0; x < n; x++)
      for (int y = 0; y < n; y++) {
        rf[x][y] = (float) r[y][x];
        gf[x][y] = (float) g[y][x];
        bf[x][y] = (float) b[y][x];
      }
    rf = DHT2D.forwardDHT2D(rf);
    gf = DHT2D.forwardDHT2D(gf);
    bf = DHT2D.forwardDHT2D(bf);
  }

  public void multOneOnF() {
    int hn = n / 2;

    for (int x = 0; x < n; x++)
      for (int y = 0; y < n; y++) {
        double f = oneOnF(x, y, hn, hn);
        rf[x][y] = (float) (rf[x][y] * f);
        gf[x][y] = (float) (gf[x][y] * f);
        bf[x][y] = (float) (bf[x][y] * f);
      }
  }

  public double oneOnF(int x, int y, int xc, int yc) {
    double dx = x - xc;
    double dy = y - yc;
    double dx2 = dx * dx;
    double dy2 = dy * dy;

    return 1 / Math.sqrt(dx2 + dy2 + 1);
  }

  public void takeIDHT() {
    rf = DHT2D.inverseDHT2D(rf);
    gf = DHT2D.inverseDHT2D(gf);
    bf = DHT2D.inverseDHT2D(bf);
  }

  public Image short2Image(int wi, int he) {
    Toolkit tk = Toolkit.getDefaultToolkit();
    ColorModel cm = ColorModel.getRGBdefault();

    int pels[] = new int[wi * he];
    for (int x = 0; x < wi; x++)
      for (int y = 0; y < he; y++) {
        pels[x + y * wi] = 0xff000000 | (r[x][y] << 16)
            | (g[x][y] << 8)
            | b[x][y];
      }
    Image i = tk.createImage(new MemoryImageSource(wi, he, cm, pels, 0, wi));
    return i;
  }

  public void waitForImage(Component component, Image image) {
    MediaTracker tracker = new MediaTracker(component);
    try {
      tracker.addImage(image, 0);
      tracker.waitForID(0);
      if (!tracker.checkID(0))
        System.out.println("Load failure!");
    } catch (InterruptedException e) {
    }
  }

  public void threeDImage() {
    for (int x = 0; x < n; x++)
      for (int y = 0; y < n; y++) {
        r[x][y] = (short) (rf[y][x]);
        g[x][y] = (short) (gf[y][x]);
        b[x][y] = (short) (bf[y][x]);
      }
    img = short2Image(n, n);
    waitForImage(this, img);
    paintOn = true;
    graphics.idx.Application.image3D(img, r);
  }
}