/*
 * @(#)GridHR.java      
 *
 * Copyright (c) 1997 NAKAGAWA Masami
 *
 * Permission to use, copy, modify, and distribute this software
 * for NON-COMMERCIAL purpose and without fee is hereby granted. 
 */

import java.applet.*;
import java.awt.*;
import java.util.*;

/**
 * A GridHR class to decorate a Web page instead of HR tag.
 * 
 * @author	NAKAGAWA Masami
 * @version	1.0, 10 Aug 1997
 */
public class GridHR extends Applet implements Runnable {
    int num = 50;
    Image offImage;
    Graphics offScreen;
    Graphics onScreen;
    boolean raised = true;
    Thread thread;
    int red;
    int green;
    int blue;
    int count;
    Dimension d;
    Color bgColor = new Color(0xFFFFFF);
    int rmin = 0x00;
    int rmax = 0xFF;
    int gmin = 0x00;
    int gmax = 0xFF;
    int bmin = 0x00;
    int bmax = 0xFF;
    int minInterval = 10;
    int maxInterval = 100;
    int gap = 4;

    public void init() {
        String s = getParameter("number");
        if (s != null) num = Integer.parseInt(s);
        s = getParameter("bgColor");
        if (s != null) bgColor = new Color(Integer.parseInt(s, 16));
        s = getParameter("red");
        if (s != null) {
            StringTokenizer st = new StringTokenizer(s, ",");
            if (st.hasMoreElements()) rmin = Integer.parseInt((String)st.nextElement(), 16);
            if (st.hasMoreElements()) rmax = Integer.parseInt((String)st.nextElement(), 16);
        }
        s = getParameter("green");
        if (s != null) {
            StringTokenizer st = new StringTokenizer(s, ",");
            if (st.hasMoreElements()) gmin = Integer.parseInt((String)st.nextElement(), 16);
            if (st.hasMoreElements()) gmax = Integer.parseInt((String)st.nextElement(), 16);
        }
        s = getParameter("blue");
        if (s != null) {
            StringTokenizer st = new StringTokenizer(s, ",");
            if (st.hasMoreElements()) bmin = Integer.parseInt((String)st.nextElement(), 16);
            if (st.hasMoreElements()) bmax = Integer.parseInt((String)st.nextElement(), 16);
        }
        s = getParameter("interval");
        if (s != null) {
            StringTokenizer st = new StringTokenizer(s, ",");
            if (st.hasMoreElements()) minInterval = Integer.parseInt((String)st.nextElement());
            if (st.hasMoreElements()) maxInterval = Integer.parseInt((String)st.nextElement());
        }
        s = getParameter("gap");
        if (s != null) {
            gap = Integer.parseInt(s);
            if (gap < 0) gap = 0;
        }
        s = getParameter("raised");
        if (s != null) raised = Boolean.getBoolean(s);
        d = size();
        offImage = createImage(d.width, d.height);
        offScreen = offImage.getGraphics();
        onScreen = getGraphics();
        int amp = maxInterval - minInterval;
        red = (int)(Math.random() * amp) + minInterval;
        green = (int)(Math.random() * amp) + minInterval;
        blue = (int)(Math.random() * amp) + minInterval;
        offScreen.setColor(bgColor);
        offScreen.fillRect(0, 0, d.width, d.height);
        for (int i = 0; i < num; i++) {
            offScreen.setColor(nextColor());
            offScreen.fill3DRect(0, 0, d.width / num - gap, d.height, raised);
            offScreen.copyArea(0, 0, d.width, d.height, d.width / num, 0);
        }
    }

    public void start() {
        if (thread == null) {
            thread = new Thread(this);
            thread.start();
        }
    }

    public void stop() {
        if (thread != null) {
            thread.stop();
        }
        thread = null;
    }

    public void paint(Graphics g) {
        if (offImage != null) {
            g.drawImage(offImage, 0, 0, null);
        }
    }
    
    private Color nextColor() {
        count++;
        return new Color(
            (int)((rmax - rmin) * ((Math.sin(2 * Math.PI * count / red) + 1) / 2) + rmin),
            (int)((gmax - gmin) * ((Math.sin(2 * Math.PI * count / green) + 1) / 2) + gmin),
            (int)((bmax - bmin) * ((Math.sin(2 * Math.PI * count / blue) + 1) / 2) + bmin));
    }

    public void run() {
        while (true) {
            offScreen.copyArea(0, 0, d.width, d.height, d.width / num, 0);
            offScreen.setColor(nextColor());
            offScreen.fill3DRect(0, 0, d.width / num - gap, d.height, raised);
            onScreen.drawImage(offImage, 0, 0, null);
            try {
                thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}