/**
 * cd.java - 16/07/2010
 *
 * auteur : JPQ
 *
 * L'ordinateur propose une grille de 2 lignes et 2 colonnes dans lesquels
 * se trouvent un disque bleu ou un carré jaune
 *
 * Le bouton "L" permet de changer les figures d'une ligne ou d'une colonne
 * le choix de la ligne ou de la colonne est aléatoire
 * Le bouton "D" permet de changer les figures d'une diagonale (prise au hasard)
 * Le bouton "1" permet de changer une des 4 figures
 * choix de la figure se faisant toujours de façon aléatoire
 *
 * Le but du jeu est d'arriver à obtenir 4 figures du même type, 4 disques bleus
 * ou 4 carrés jaunes.
 * Le bouton "Init" relance une grille aléatoire, le bouton "invisible" permet
 * d'opérer sans voir les figures !
 * ajout de main() le 08/01/18 et modification le 29/08/22
 *
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;

public class cd extends JPanel implements ActionListener {
	static final long serialVersionUID = 220829L;
	JButton reinit = new JButton ("Init");
	JButton visible = new JButton ("Invisible");
	boolean bvisible = true;
	JButton bl = new JButton ("L");
	JButton bd = new JButton ("D");
	JButton b1 = new JButton ("1");
	feuille dessin = new feuille();
	Random rnd = new Random();
// forme contient le type de figures pour les 4 cases de la grille
// true pour le disque, false pour le carré
	boolean[] forme = new boolean [4]; 

	public cd() {
		setFont(new Font("Arial, Helvetica, sans-serif", Font.PLAIN, 12));
		setLayout (new BorderLayout());
		JPanel p = new JPanel();
		p.setBackground(Color.LIGHT_GRAY);
		p.setBorder (BorderFactory.createMatteBorder(1, 1, 1, 1, Color.BLACK));
		add	(p, BorderLayout.NORTH);
		p.add(reinit);
		reinit.addActionListener (this);
		p.add (visible);
		visible.addActionListener (this);
		p.add (bl);
		bl.addActionListener(this);
		p.add (bd);
		bd.addActionListener(this);
		p.add (b1);
		b1.addActionListener(this);
		add (dessin, BorderLayout.CENTER);
		for (int i = 0; i < forme.length; i++)
			forme [i] = rnd.nextBoolean();
	}

	public void actionPerformed (ActionEvent evt) {
		if (evt.getSource() == visible) {
			bvisible = ! bvisible;
			if (bvisible)
				visible.setText ("invisible");
			else
				visible.setText ("visible");
		} else if (evt.getSource() == reinit) {
			for (int i = 0; i < forme.length; i++)
				forme [i] = rnd.nextBoolean();
		} else if (evt.getSource() == bl) {
// 4 lignes possibles; cases 01, 23, 02 ou 13
			int n4 = rnd.nextInt (4);
			int n1 = 1; int n2 = 3;
			switch (n4) {
				case 0 :
					n1 = 0;
					n2 = 1;
					break;
				case 1 :
					n1 = 2;
					n2 = 3;
					break;
				case 2 :
					n1 = 0;
					n2 = 2;
			}
			forme [n1] = ! forme [n1];
			forme [n2] = ! forme [n2];
		} else if (evt.getSource() == bd) {
// 2 diagonales possibles , cases 03 ou 12
			int n1 = 0;
			int n2 = 3;
			if (rnd.nextBoolean()) {
				n1 = 1;
				n2 = 2;
			}
			forme [n1] = ! forme [n1];
			forme [n2] = ! forme [n2];
		} else if (evt.getSource() == b1) {
// 1 case parmi 4
			int n1 = rnd.nextInt (4);
			forme [n1] = ! forme [n1];
		}
		dessin.repaint();
	}

	public static void main (String [] args) {
		int w = 400;
		int h = 400;

		cd c = new cd ();
		JFrame f = new JFrame ("cd");
		f.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
		f.add (c);
		f.setSize (w, h);
		f.setVisible (true);
	}

/**
 * classe feuille 29/08/22
 *
 */

protected class feuille extends Canvas {
	static final long serialVersionUID = 220829L;
// on peut régler les marges ici
// margeext pour la marge minimale entre le bord de la feuile et les 2 carrés
// margeint pour la marge entre le carré de bord noir et le carré jaune
// ou disque bleu
	int margex, margey, cote, cotefig;
	int margeext = 10;
	int margeint = 10;

	public feuille() {
		setBackground (Color.WHITE);
	}

// dessine la figure; forme[n] == True pour un disque; forme[n] == False pour un carré
	private void figure (Graphics g, int n) {
		int x = margex;
		int y = margey;
		if (n / 2 == 1)
			y += cote;
		if (n % 2 == 1)
			x += cote;
		g.setColor(Color.BLACK);
		g.drawRect (x, y, cote, cote);
		if (bvisible) {
			x += margeint;
			y += margeint;
			if (forme [n]) {
				g.setColor(Color.BLUE);
				g.fillOval (x, y, cotefig, cotefig);
			} else {
				g.setColor(Color.YELLOW);
				g.fillRect (x, y, cotefig, cotefig);
			}
		}
	}

	public void paint (Graphics g) {
// Calcul des marges (margex et margey) et de la longueur du carré : cote
		int dgw = getWidth();
		int dgh = getHeight();
		if (dgw >= dgh) {
			cote = (dgh - 2 * margeext) / 2;
			margex = dgw / 2 - cote;
			margey = margeext;
		} else {
			cote = (dgw - 2 * margeext) / 2;
			margex = margeext;
			margey = dgh / 2 - cote;
		}
// cotefig est le diamètre du disque ou la longueur du côté du carré
// dans le carré de bord noir
			cotefig = cote - 2 * margeint;
			boolean gagne = true;
			boolean f0 = forme [0];
			figure (g, 0);
			for (int i = 1; i < forme.length; i++) {
				figure (g, i);
				if (gagne && (f0 != forme [i]))
					gagne = false;
			}
			if (gagne) {
				g.setFont(new Font("Arial, Helvetica, sans-serif", Font.BOLD, 20));
				g.setColor (Color.RED);
				g.drawString ("GAGNÉ", dgw / 2 - 40, dgh / 2 + 10);
			}
		}
	}

}
