import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
// per le immagini
import java.io.*;
import javax.imageio.*;
import java.awt.image.*;
import javax.swing.filechooser.FileFilter;


/* PROVA LABORATORIO "TIPO" 2004 */

// il frame principale
class myFrame extends JFrame {
    //dimensioni schermo
    Dimension dScreen = Toolkit.getDefaultToolkit().getScreenSize();
    //pannello pubblico
    public myPanel mainPanel;
   // costruttore
    public myFrame() {
        setTitle("Esempio per prova Itinere 2004");
        setSize(dScreen.width/2, dScreen.height/2);
        //il pannello appare centrato
        setLocation((dScreen.width - getSize().width) / 2,
                    (dScreen.height - getSize().height) / 2);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        // crea e inserisce pannello nel frame
        mainPanel = new myPanel();
        getContentPane().add(mainPanel);
        // inserisce menu nel frame
         new menuProva2(this);
    }    
}

//pannello principale
class myPanel extends JPanel {
    //pannelli
    panelA pannelloA;
    panelB pannelloB;
    //costruttore
    public myPanel() {
        super();
        setLayout(new GridLayout(1,2));
        pannelloA = new panelA();
        pannelloB = new panelB();
        add(pannelloA);
        add(new JScrollPane(pannelloB));
    }
}

// pannello per le forme geometriche
class panelA extends JPanel {
    // colore delle forme
    private Color colore;
    private boolean vuotoPieno;
    //costruttore
    public panelA() {
        // colore di sfondo
        setBackground(Color.WHITE);
        // colore casuale scelto iniziale
        colore = new Color((float)Math.random(), (float)Math.random(), (float)Math.random());
        // flag per vuoto/pieno
        vuotoPieno = true;
    }
    
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;
        //setta rendering x ANTI-ALIASING
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);        
        //prende centro del pannello
        Dimension center = new Dimension((getSize().width/2), getSize().height/2);
        //setto colore a scelta
        g2.setPaint(colore);
        
        //Rettangolo centrato sullo schermo di dimensione pari alla meta del pannello
        /*
        Rectangle2D rect = new Rectangle2D.Double();
        rect.setFrameFromCenter(center.width, center.height,
                        center.width + getSize().width / 4,
                        center.height + getSize().height / 4);
        */
        
        // Uguale con ovale...
        RoundRectangle2D rect = new RoundRectangle2D.Double();
        rect.setRoundRect(center.width - getSize().width / 4,
                          center.height - getSize().height / 4,
                        getSize().width / 2,
                        getSize().height / 2, 30, 30);

        // disegna il rettangolo vuoto oppure pieno
        if (vuotoPieno) g2.fill(rect); else g2.draw(rect);
            
        //Cerchio inscritto sul rettangolo
        g2.setPaint(invertiColore(colore));
        Ellipse2D circle = new Ellipse2D.Double();
        circle.setFrameFromCenter(center.width, center.height,
                        center.width + getSize().width / 4,
                        center.height + getSize().height / 4);
        // disegna il cerchio pieno oppure vuoto
        if (!vuotoPieno) g2.fill(circle); else g2.draw(circle);
                    
        // Stella a 5 punte inscritta nel cerchio
        int dimX = getSize().width / 4;
        int dimY = getSize().height / 4;
        double angolo = 2 * Math.PI / 5;
        int[] X = new int[5];
        int[] Y = new int[5];
        X[0] = (int)(Math.cos(-Math.PI/2) * dimX);
        Y[0] = (int)(Math.sin(-Math.PI/2) * dimY);
        X[1] = (int)(Math.cos(angolo*2-Math.PI/2) * dimX);
        Y[1] = (int)(Math.sin(angolo*2-Math.PI/2) * dimY);
        X[2] = (int)(Math.cos(angolo*4-Math.PI/2) * dimX);
        Y[2] = (int)(Math.sin(angolo*4-Math.PI/2) * dimY);
        X[3] = (int)(Math.cos(angolo-Math.PI/2) * dimX);
        Y[3] = (int)(Math.sin(angolo-Math.PI/2) * dimY);
        X[4] = (int)(Math.cos(angolo*3-Math.PI/2) * dimX);
        Y[4] = (int)(Math.sin(angolo*3-Math.PI/2) * dimY);
        Polygon pol = new Polygon(X, Y, 5);
        GeneralPath path = new GeneralPath(pol);
        path.setWindingRule(GeneralPath.WIND_NON_ZERO);
        //Sposto il contesto grafico nel centro del pannello        
        g2.translate(center.width, center.height);
        //Disegno la forma
        g2.fill(path);
        //Riposiziono il contesto grafico a 0,0
        g2.translate(-center.width, -center.height);
    }
    
    //restituisce un colore che è complementare a quello dato come paramentro
    private Color invertiColore(Color c) {
        return (new Color(255 - c.getRed(), 255 - c.getGreen(), 255 - c.getBlue()));
    }
    
    public void setInverti() {
        vuotoPieno = !vuotoPieno;
        repaint();
    }
    
    public void setColore(Color c) {
        colore = c;
        repaint();
    }
}

// pannello per le immagini
class panelB extends JPanel {
    //immagine da caricare
    BufferedImage immagine;     //immagine da visualizzare
    JFileChooser fileChooser;   //finestra di dialogo per aprire i file
    JLabel label;               //label nel quale verrà disegnata l'immagine
    
    //costruttore
    public panelB() {
        setBackground(Color.ORANGE);
        //Creo il JFileChooser
        fileChooser = new JFileChooser();
        //Disabilito al visualizzazione di tutti i tipi di file
        fileChooser.setAcceptAllFileFilterUsed(false);
        //Abilito la visualizzazione dei file di tipo jpg
        fileChooser.setFileFilter(new JPGFilter());    
        // Imposto la directory iniziale
        fileChooser.setCurrentDirectory(new File("e:\\Immagini/FotoSilvio/Etna"));         
        label = new JLabel();
        add(label);
    }
    
    public void paintComponent(Graphics g) {
        super.paintComponent(g);        
    }
    
    public void openFile() {
        //Imposto il titolo della finestra
        fileChooser.setDialogTitle("Apri file");
        //Visualizzo la finestra di dialogo
        int risposta=fileChooser.showOpenDialog(this);
        //Se ho premuto il tasto apri...
        if (risposta==fileChooser.APPROVE_OPTION)  {  
          //Recupero il file selezionato
          File f = fileChooser.getSelectedFile();
          try {
                BufferedImage buff = ImageIO.read(f);
                //recupero le dimensioni dell'immagine
                int w=buff.getWidth();
                int h=buff.getHeight();
                //Creo un'immagine nuova delle stesse dimensioni
                immagine = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
                /* Disegno l'immagine caricata sulla nuova immagine.
                  Operazione che garantisce un immagine di tipo TYPE_INT_ARGB */
                Graphics2D g2 = immagine.createGraphics();
                g2.drawImage(buff, 0, 0, null);
                //rilascio contesto grafico
                g2.dispose();       
                //aggiorno icona
                label.setIcon(new ImageIcon(immagine));
                //ridisegno
                repaint();               
          }
          catch (Exception ex) {}
        }        
    }
    
    public void filterImage() {
        if (immagine == null) return;
        // ottengo un contesto grafico
        Graphics2D g2 = immagine.createGraphics();
        //Imposto come colore il bianco
        g2.setColor(Color.white);
        //Imposto la modalità XOR e come colore XOR il nero
        g2.setXORMode(Color.black);
        //Riempio l'immagine con un rettangolo grande quando l'immagine,
        g2.fillRect(0, 0, immagine.getWidth(), immagine.getHeight());
        //Rilascio le risorse
        g2.dispose();        
        //Ridisegno l'immagine
        label.setIcon(new ImageIcon(immagine));
    }
}

// il menu del frame principale
class menuProva2 implements ActionListener {
    //variabile di istanza
    private myFrame frame;
    // le scelte di menu
    JMenuItem menu1_1, menu1_2, menu1_3, menu2_1, menu2_2;
    //costruttore
    public menuProva2(myFrame f) {
        //creazione barra menù
        JMenuBar menuBar = new JMenuBar();
        f.setJMenuBar(menuBar);
        //menu1
        JMenu menu1 = new JMenu("Menu 1");
        menu1_1 = menu1.add("Inverti");
        menu1_2 = menu1.add("Rosso");
        menu1_3 = menu1.add("Giallo");
        //menu2
        JMenu menu2 = new JMenu("Menu 2");
        menu2_1 = menu2.add("Carica Immagine");
        menu2_2 = menu2.add("Elabora Immagine");
        //inserimento menu nella barra del menu
        menuBar.add(menu1);
        menuBar.add(menu2);
        // ascoltatore degli eventi: questa stessa classe
        menu1_1.addActionListener(this);
        menu1_2.addActionListener(this);
        menu1_3.addActionListener(this);
        menu2_1.addActionListener(this);
        menu2_2.addActionListener(this);
        
        // passo il frame al fine di controllare i pannelli dagli eventi del menù.
        frame = f;
        
    }
    
    public void actionPerformed(ActionEvent e) {
        //eventi per il pannelloA
        if (e.getSource().equals(menu1_1) ) frame.mainPanel.pannelloA.setInverti();
        if (e.getSource().equals(menu1_2) ) frame.mainPanel.pannelloA.setColore(Color.RED);
        if (e.getSource().equals(menu1_3) ) frame.mainPanel.pannelloA.setColore(Color.YELLOW);
        
        //eventi per il pannelloB
        if (e.getSource().equals(menu2_1) ) frame.mainPanel.pannelloB.openFile();
        if (e.getSource().equals(menu2_2) ) frame.mainPanel.pannelloB.filterImage();
    }

}

// Filtro per le immagini JPG
class JPGFilter extends FileFilter {
  // file da accettare: jpg o jpeg (oppure sono cartelle)
  public boolean accept(File f) {
    String str = f.getName().toLowerCase();
    return str.endsWith(".jpg")||str.endsWith(".jpeg")||f.isDirectory();
  }
  
  // descrizione del filtro
  public String getDescription() {
    return "Immagine JPG";
  }
}


// classe principale
public class Prova2 {
public static void main(String[] args) {
     JFrame f = new myFrame();
     f.show();
  }
}