// File  : snow.java
// Date  : 9.8.2005 23:15:35

// Autor: Sabine Neugebaur I8W
// Datum: 8.7.1996
// Das Schneeflockentanzen ist von www.netspace.org/~bperkins/snow.java entnommen

import java.applet.*;
import java.io.*;
import java.awt.*;

public class snow extends java.applet.Applet implements Runnable {
  final int Number_Flakes=1000;
  final int SNOW=1;
  final int MOUNTAIN=2;
  final int AIR=0;
  int X_Size=512;
  int Y_Size=512;
  Thread artist=null;
  int flakes[][] ;
  int Screen[][];

  public snow() {
    setForeground(Color.white);
    setBackground(Color.black);
    Screen=new int[X_Size][Y_Size];
    flakes = new int[Number_Flakes][2];
    setSize(X_Size,Y_Size);
  }
  public void init() {
    int x,y;
    int y_change=0; // zaehlt die Wechsel von bergauf nach bergab und umgekehrt
    super.init();
    for(int i =0;i<X_Size;i++)
      for(int j =0;j<Y_Size;j++)
        Screen[i][j]=AIR;
    y=Y_Size/8*7; // Beginn der Bergkette
    int i=0;
    for ( x = 0; x < X_Size;x++) { // Zufaellige Bergkette erzeugen
      if (x == i) {
          i+=Math.max(5,Math.min((int)(Math.random()*Y_Size/5),60));
          y_change++;
      }
      if (y_change%2 == 0)
        y++;
      else
        y--;
      y=Math.min(y,Y_Size);
      y=Math.max(y,0);
      Screen[x][y]=MOUNTAIN;
      for(int y1=y;y1<Y_Size;y1++) // Alle Punkte unterhalb y
        Screen[x][y1]=MOUNTAIN;    // als Berg markieren
    }
    for(i=0; i<Number_Flakes; i++) // Schneeflocken erzeugen
      do {
        flakes[i][0]=(int)(Math.random()*X_Size);
        flakes[i][1]=(int)(Math.random()*Y_Size);
      } while (Screen[flakes[i][0]][flakes[i][1]]!=AIR);
  }

  public void draw_flake(int x, int y , Graphics g){
    g.fillRect(x,y,1,1);
  }

  public void draw_mountain(int x, int y , Graphics g){
    g.setColor(Color.green);
    g.fillRect(x,y,1,1);
    g.setColor(getForeground());
  }

  public void move_flake_left(int x, int y , Graphics g){
    g.fillRect(x-1,y,1,1);
    g.clearRect(x,y,1,1);
  }

  public void move_flake_right(int x, int y , Graphics g){
    g.fillRect(x+1,y,1,1);
    g.clearRect(x,y,1,1);
  }

  public void move_flake_down(int x, int y , Graphics g){
    g.fillRect(x,y+1,1,1);
    g.clearRect(x,y,1,1);
  }

  public void update(Graphics g) {
    int i;
    for ( i= 0; i < Number_Flakes; i++) {
      double direction = Math.random();
      if (direction <.333) {
        move_flake_left(flakes[i][0],flakes[i][1], g );
        flakes[i][0] = flakes[i][0]-1;
      }
      if (direction <.666 && direction > .333 ) {
        move_flake_right(flakes[i][0],flakes[i][1], g );
        flakes[i][0] = flakes[i][0]+1;
      }
      if (direction > .666) {
        move_flake_down(flakes[i][0],flakes[i][1], g );
        flakes[i][1] = flakes[i][1]+1;
      }
      if (flakes[i][0] <= 0){
        move_flake_right(flakes[i][0],flakes[i][1], g );
        flakes[i][0] = flakes[i][0]+1;
      }
      if (flakes[i][0] >= X_Size){
        move_flake_left(flakes[i][0],flakes[i][1], g );
        flakes[i][0] = flakes[i][0]-1;
      }
      if (Screen[flakes[i][0]][flakes[i][1]]>0) { // Schneeflocke ist auf Schnee oder Berg getroffen
        int x=flakes[i][0];
        int y=flakes[i][1]-1;
        if (y >= 0)
          while (Screen[x][y]==AIR) { // Schneeflockenrutschen
            if ( Math.random() < 0.8)
              if (Screen[Math.max(0,x-1)][Math.min(Y_Size-1 , y+1)] == AIR) {
                x=Math.max(0,x-1);
                y=Math.min(Y_Size-1, y+1);
              }
              else if (Screen[Math.min(X_Size-1 , x+1)][Math.min(Y_Size-1 , y+1)] == AIR) {
                x=Math.min(X_Size-1, x+1);
                y=Math.min(Y_Size-1, y+1);
              }
            else
              break;
          }
        else
          y=0;
        draw_flake(x,y,g);
        Screen[x][y] = SNOW;
        flakes[i][0]=(int)(Math.random()*X_Size);
        flakes[i][1] = 0;
      }
    }
  }

  public void paint(Graphics g) {
    for(int i =0;i<X_Size;i++)
      for(int j =0;j<Y_Size;j++)
        if (Screen[i][j] == SNOW)
          draw_flake(i,j,g);
        else if (Screen[i][j] == MOUNTAIN)
          draw_mountain(i,j,g);
    for ( int i= 0; i < Number_Flakes; i++)
      draw_flake(flakes[i][0],flakes[i][1], g );
  }

  public void start() {
    if (artist == null){
      artist= new Thread(this);
      artist.start();
    }
  }

  public void stop(){
    artist = null;
  }

  public void run() {
    while(artist != null) {
     try { Thread.sleep(1);} catch(InterruptedException e){}
     repaint();
    }
    artist = null;
  }
}

