import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/**
 * This panel represents a panel (i.e. a rectangular area on the screen) where
 * random art is displayed.  The drawArt method draws a random art work.  This
 * method is called every 5 seconds, and a new piece of random art is generated
 * each time it is called.
 */
public class RandomArtPanel extends JPanel implements ActionListener {
	
	/**
	 * This method draws one random artwork.  The size of the drawing area is 
	 * supposed to be 500-by-400 pixels (but this can also be changed in the
	 * next subroutine).  If you want to know the size, you can call the
	 * methods getWidth() and getHeight(), which return int values giving
	 * the actual width and height of the panel, measuered in pixels.
	 * You can use the functions randomColor() and randomHue(), defined below,
	 * to select random colors for drawing, as in "g.setColor(randomHue(1.0, 0.5))".
	 *    For drawing, you can use the subroutines g.setColor(), g.drawString(),
	 * g.drawLine(), g.drawRect(), g.fillRect(), g.drawOval(), and g.fillOval(),
	 * g.draw3DRect(), g.fill3DRect(), g.drawRoundRect(), and g.fillRoundRect().
	 * These subroutines are part of the object g of type Graphics, which is a 
	 * parameter to this subroutine. 
	 */
	private void createArt(Graphics g) {
		
		int width, height;   // Actual widht and height of the panel.
		width = getWidth();
		height = getHeight();
		
		int i, x, y;  // Loop control variables for for loops.
		
		int choice;   // Decides which of 4 types of art to draw
		choice = (int)(4*Math.random());
				
		switch (choice) {
		case 0:  // Pseudo-Pollack:  lots of lines on a white background
			g.setColor(Color.WHITE);
			g.fillRect(0,0,width,height);
			int lineCount;  // number of lines to draw
			lineCount = 100 * (int)(Math.random() * 15 + 1);
			for (i = 0; i < lineCount; i++) {
				int x1,y1,x2,y2;  // coordinates of endpoints of line, to be selected randomly
				x1 = (int)(width * Math.random());
				y1 = (int)(height * Math.random());
				x2 = (int)(width * Math.random());
				y2 = (int)(height * Math.random());
				g.setColor( randomHue(0.5,1) );  
				g.drawLine(x1,y1,x2,y2);
			}
			break;
		case 1:  // Mangled Mondrian:  Colored horizontal and vertical bars
			int barCount;  // Number of bars to draw.
			barCount = 6 + (int)(Math.random() * 20);
			boolean brightBackground;  // Should background color be bright?
			brightBackground = Math.random() > 0.5;
			if (brightBackground)
				g.setColor( randomHue(0.5,1) ); 
			else
				g.setColor( randomHue(1,0.5) );
			g.fillRect(0,0,width,height);
			for (i = 0; i < barCount; i++) {
				int a;  // Width or height of bar.
				a = 3 + (int)(15*Math.random());
				if (brightBackground)
					g.setColor( randomHue(1,0.5) ); // dull bars on bright background
				else
					g.setColor( randomHue(0.5,1) ); // bright bars on dull background
				if (Math.random() < 0.5)
					g.fill3DRect(0, (int)(height*Math.random()), width, a, true); // horizontal bar
				else
					g.fill3DRect((int)(width*Math.random()), 0, a, height, true); // veritcal bar
			}
			break;
		case 2:  // Kan't be Kandinsky: grid of randomly colored squares with smaller nested squares
			for (x = 0; x < width; x += 50)
				for (y = 0; y < height; y += 50) {
					g.setColor( randomHue(0.6,1));
					g.fillRect(x,y,50,50);
					g.setColor( randomHue(1,0.4));
					g.fill3DRect(x+5,y+5,40,40,true);
				}
			break;
		case 3: // Randomly colored and sized squares on a random-gray background
			g.setColor(randomHue(0,Math.random()));
			g.fillRect(0,0,width,height);
			int squareCount;  // number of squares
			squareCount = 10 + (int)(90*Math.random());
			for (i = 0; i < squareCount; i++) {
				int a,b;  // Upper left corner of square
				int size; // Size of square
				a = (int)(Math.random()*(width-20));
				b = (int)(Math.random()*(height-20));
				int maxSize;  // Maximum allowed size of square.
				maxSize = Math.min( width - a, height - b);  // Square can't extend outside panel.
				maxSize = Math.min( maxSize, 200 );  // Can't be larger than 200 pixels.
				size = (int)(Math.random()*maxSize);
				g.setColor( randomColor() );
				g.fill3DRect(a,b,size,size,true);
			}
			break;
		}
		
	} // end createArt()
	
	/**
	 * When this subroutine is called, the return value is a random color,
	 * constructed with randomly selected amounts of red, green, and blue.
	 */
	private Color randomColor() {
		int r,g,b;  // Red, blue, and green components of color.
		r = (int)(256*Math.random());
		g = (int)(256*Math.random());
		b = (int)(256*Math.random());
		return new Color(r,g,b);
	}
	
	/**
	 * The return value of this subroutine is a color that has a random
	 * "hue" and has a saturation and a brightness that are specified as
	 * parameters to the subroutine.  A color's hue is its basic spectral
	 * color.  The saturation is a value between 0 and 1 that indicates
	 * how "pure" the color is; 1 gives a pure color while smaller values
	 * are equivalent to mixing some white into the color.  For example,
	 * a basic red color with a saturation of 0.5 would be pink.  The
	 * brightness is a value between 0 and 1, where 1 gives a color that
	 * is as bright as possible and values close to 0 will give a color
	 * that is almost black.  A brightness value of 0 will give black,
	 * no matter what the value of hue or saturation.
	 */
	private Color randomHue(double saturation, double brightness) {
		double hue = Math.random();
		return Color.getHSBColor((float)hue, (float)saturation, (float)brightness);
	}
	
	/**
	 * This is the "constructor" that is called to create an object of type
	 * BasicAnimationPanel.  It sets up all the initial properties of the object.
	 * You can change some of the statements here, as noted, to modifiy the
	 * behavior of the animation.  Note in particular setPreferredSize,
	 * setBackground, and frameCount.
	 *
	 */
	public RandomArtPanel() {
		setPreferredSize( new Dimension(500,400) );  // The size should be 50o-by-500.
		setBackground(Color.LIGHT_GRAY);   // Background color for the window.
		setFont(new Font("Serif",Font.PLAIN,12));  // Initial font size is 12.
		Timer timer = new Timer(5000,this);  // 5000 milliseconds (5 seconds) between artworks
		timer.setInitialDelay(1000);         // one second before first artwork appears
		timer.start();
	}
	
	
	//---- implementation details -- no need to read or understand past this point ----
	
	private boolean timerFired = false;  // Used to prevent drawing any art before timer fires.
	
	public void actionPerformed(ActionEvent evt) {
		timerFired = true;
		repaint();
	}
	
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		if (timerFired)
			createArt(g);
	}
	
	
} // end BasicAnimation
