import java.awt.*;
import java.applet.Applet;
import java.util.*;
import java.awt.event.*;

public class snow_m extends Applet implements Runnable, MouseListener, MouseMotionListener
{
    Thread thread;
    Image off;
    Graphics grf;
    Random rand;
    int snowX[];
    int snowY[];
    int snowX1[];
    int snowY1[];
    int wind;
    int speed = 60;
    int snows;
    int dw, dh;
    int mado , mdn1 = 0 , mdr1 = 0 , mdr2 = 0;
    int dif1=0, dif2=0;
    Image back, mado1 , mado2 ;
    MediaTracker mt;
    boolean fg = true, fm = false;

    public void init(){
        rand = new Random();
        dw = getSize().width;
        dh = getSize().height;
        mdr1=dw / 2;
        mdr2=-dw / 10;
        mt = new MediaTracker(this);
        off = createImage(dw, dh);
        grf = off.getGraphics();
        String string = getParameter("snows");
        if (string == null)
            snows = 100;
        else
            snows = Integer.valueOf(string).intValue();
        snowX = new int[snows+1];
        snowY = new int[snows+1];
        snowX1 = new int[snows * 20 + 1];
        snowY1 = new int[snows * 20 + 1];
        for (int i = 0; i < snows; i++){
                snowX[i]  = rand.nextInt() % (dw / 2) + dw / 2;
                snowY[i]  = rand.nextInt() % (dh / 2) + dh / 2;
        }
        for (int i = 0; i < snows * 20; i++){
                snowX1[i]  = rand.nextInt() % (dw / 2) + dw / 2;
                snowY1[i]  = rand.nextInt() % (dh / 2) + dh / 2;
        }
        mt = new MediaTracker(this);
        string = getParameter("image");
        if(string != null){
            back = getImage(getDocumentBase(), string);
            mt.addImage(back, 0);
        }
        string = getParameter("image2");
        mado1 = getImage(getDocumentBase(), string);
        mt.addImage(mado1, 0);
        try{
            mt.waitForID(0);
        }
        catch (InterruptedException e){
            return;
        }
        mado2 = mado1;
        addMouseListener(this);
        addMouseMotionListener(this);
    }

    public void start(){
        if (thread == null){
            thread = new Thread(this);
            thread.start();
        }
    }

    public void stop(){
        thread = null;
    }

	public void destroy(){
	    thread = null;
	}

    public void run(){
        while (thread != null){
            try{
                Thread.sleep((long)speed);
                repaint();
            }
            catch (InterruptedException e){
                return;
            }
        }
    }

    public void paint(Graphics g){
        if(back != null)
            grf.drawImage(back, 0, 0, this);
        else{
            grf.setColor(new Color(0, 0, 0));
            grf.fillRect(0, 0, dw, dh);
        }
        if(fg)
            drawBackSnow();
        if(mado1 != null){
            grf.drawImage(mado2, mdr2, 0, this);
            grf.drawImage(mado1, mdr1, 0, this);
        }
        g.drawImage(off, 0, 0, null);
    }

    public void update(Graphics g){
        paint(g);
    }

    public void drawBackSnow(){
        grf.setColor(Color.white);
        if(!fm || fg){
            for (int i = 0; i < snows * 20; i++){
                int a = i / 20;
                if(i % 20 == 0){
                    grf.fillRect(snowX[a], snowY[a],2, 2);
                    snowX[a] += rand.nextInt() % 2 + wind * 2;
                    snowY[a] += (rand.nextInt() % 8 + 3) / 3 + 1;
                    if (snowX[a] >= dw)
                        snowX[a] = 0;
                    if (snowX[a] < 0)
                        snowX[a] = dw - 1;
                    if (snowY[a] >= dh || snowY[a] < 0){
                        snowX[a] = Math.abs(rand.nextInt() % dw);
                        snowY[a] = 0;
                    }
                }
                int c = i;
                grf.drawLine(snowX1[c], snowY1[c],snowX1[c], snowY1[c]);
                snowX1[c] += rand.nextInt() % 2 + wind ;
                snowY1[c] += (rand.nextInt() % 6 + 5) / 5;
                if (snowX1[c] >= dw)
                    snowX1[c] = 0;
                if (snowX1[c] < 0)
                    snowX1[c] = dw - 1;
                if (snowY1[c] >= dh || snowY1[c] < 0){
                    snowX1[c] = Math.abs(rand.nextInt() % dw);
                    snowY1[c] = 0;
                }
            }
        }
        switch (rand.nextInt() % 300){
            case 0:
                wind = 0;
                return;
            case 1:
                wind = 1;
                return;
            case 2:
                wind = -1;
                return;
            case 3:
                wind = 2;
                return;
            case 4:
                wind = -2;
                return;
            case 5:
                wind = 3;
                return;
            case 6:
                wind = -3;
                break;
                default:
        }
        return;
    }

    public void mousePressed(MouseEvent e){
        int x=e.getX();
        int y=e.getY();
        if(x>mdr1 && x<mdr1+dw/2){
            mado = 1;
            dif1 = x - mdr1;
        }
        else if(x>mdr2 && x<mdr2+dw/2){
            mado = 2;
            dif2 = x - mdr2;
        }
        else mado = 0;
        mdn1 = x;
    }

   public void mouseDragged(MouseEvent e){
        int x =e.getX();
        int y =e.getY();
        fm = true;
        if(mado == 0){;}
        if(mado == 1){
            mdr1 = x - dif1;
            if (mdr1 >= dw) mdr1 = dw - 5;
            if (mdr1 <= - dw / 2) mdr1 = - dw / 2 + 5;
        }
        if(mado == 2){
            mdr2 = x - dif2;
            if (mdr2 >= dw) mdr2 = dw - 5;
            if (mdr2 <= - dw / 2) mdr2 = - dw / 2 + 5;
        }
        repaint();
    }

    public void mouseReleased(MouseEvent e){
        if (!fm){
            if (fg){
                fg = false;
                thread = null;
                repaint();
            }else{
                fg = true;
                thread = new Thread(this);
                thread.start();
                repaint();
            }
        }
        fm = false;
    }
    public void mouseClicked(MouseEvent e){;}
    public void mouseEntered(MouseEvent e){;}
    public void mouseExited(MouseEvent e){;}
    public void mouseMoved(MouseEvent e){;}
}

