/**
 * @version 1.00 1999-09-11
 * @author Cay Horstmann
 */

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;

public class CompositeTest {  
  public static void main(String[] args) {
    JFrame f = new JFrame("Composition");
		f.setContentPane(new Composite());
    f.setBounds(100,100,400, 400);
		f.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) { 
        System.exit(0);
			}
		});
    f.show();
	}
}

class Composite extends JPanel
  implements ActionListener, ChangeListener {
  private CompositePanel canvas;
	private JComboBox ruleCombo;
	private JSlider alphaSlider;
  private JTextField explication;

  Composite() {
		setLayout(new BorderLayout());
		canvas = new CompositePanel();
		add(canvas, "Center");

		ruleCombo = new JComboBox();
		ruleCombo.addItem("CLEAR");
		ruleCombo.addItem("SRC");
		ruleCombo.addItem("SRC_OVER");
		ruleCombo.addItem("DST_OVER");
		ruleCombo.addItem("SRC_IN");
		ruleCombo.addItem("SRC_OUT");
		ruleCombo.addItem("DST_IN");
		ruleCombo.addItem("DST_OUT");
		ruleCombo.addActionListener(this);

		alphaSlider = new JSlider();
    final TextField textField = new TextField(2);      
    alphaSlider.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent event) {
				textField.setText("" + alphaSlider.getValue());
			}
		});
	
		alphaSlider.addChangeListener(this);
		JPanel panel = new JPanel();
		panel.add(ruleCombo);
		panel.add(new JLabel("Alpha"));
		panel.add(alphaSlider);
		panel.add(textField);
		add(panel, "North");

		explication = new JTextField();
		add(explication, "South");

		canvas.setAlpha(alphaSlider.getValue());
		canvas.setRule(ruleCombo.getSelectedItem());
		explication.setText(canvas.getExplication());
		textField.setText("" + alphaSlider.getValue());
	}

  public void stateChanged(ChangeEvent event) {
		canvas.setAlpha(alphaSlider.getValue());
	}

  public void actionPerformed(ActionEvent event) {
		canvas.setRule(ruleCombo.getSelectedItem());
    explication.setText(canvas.getExplication());
	}
}

class CompositePanel extends JPanel {
  private Shape ellipse;
  private Shape rectangle;
  private float alpha;
  private int rule;
  private String explication;
	BufferedImage image;
  public CompositePanel() {
    ellipse = new Ellipse2D.Double(100, 100, 150, 100);
		rectangle = new Rectangle2D.Double(150, 150, 150, 100);
	}

  public void paintComponent(Graphics g) {
    super.paintComponent(g);
		Graphics2D g2 = (Graphics2D)g;
		if (image == null) 
			image = new BufferedImage(
        getWidth(),getHeight(), BufferedImage.TYPE_INT_ARGB);
		Graphics2D gI = image.createGraphics();
		gI.setPaint(Color.red);
		gI.fill(ellipse);
		AlphaComposite composite =
      AlphaComposite.getInstance(rule, alpha);
		gI.setComposite(composite);
		gI.setPaint(Color.blue);
		gI.fill(rectangle);
		g2.drawImage(image, null, 0, 0);
	}

	public void setRule(Object r) {
		if (r.equals("CLEAR")) {
      rule = AlphaComposite.CLEAR;
			explication = "Source efface destination";
		}
		else if (r.equals("SRC")) {
      rule = AlphaComposite.SRC;
			explication = "Source écrase destination et pixels vides";
		}
		else if (r.equals("SRC_OVER")) {  
			rule = AlphaComposite.SRC_OVER;
			explication = "Source se mélange à destination et écrase pixels vides";
		}
		else if (r.equals("DST_OVER")) {
			rule = AlphaComposite.DST_OVER;
			explication = "Source écrase pixels vides";
		}
		else if (r.equals("SRC_IN")) {
      rule = AlphaComposite.SRC_IN;
			explication = "Source écrase destination seulement";
		}
		else if (r.equals("SRC_OUT")) {
      rule = AlphaComposite.SRC_OUT;
			explication = "Source efface destination et écrase pixels vides";
		}
		else if (r.equals("DST_IN")) {
      rule = AlphaComposite.DST_IN;
			explication = "Source efface destination seulement";
		}
		else if (r.equals("DST_OUT")) {
	 	 rule = AlphaComposite.DST_OUT;
		 explication = "Source efface destination par complément alpha";
		}
		repaint();
	}

	public void setAlpha(int a) {
		alpha = (float)a / 100.0F;
		repaint();
	}
	public String getExplication() { return explication;}
}
