import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.*;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

/**
 * Affiche une fenêtre du logiciel.
 */
public class AppThinkerWindow extends JFrame {

    private AppThinkerMenuBar _menubar;
    private AppThinkerStatusbar _statusbar;

    private Project _project;
    private JPanel _contentPanel;
    private Composition _composition;
    private UmlToolbar _toolbar;

    /**
     * Constructeur de la classe AppThinkerWindow
     */
    public AppThinkerWindow(){
        //Paramétrage de la fenêtre
        this.setTitle("AppThinker");
        this.setExtendedState(JFrame.MAXIMIZED_BOTH);
        this.setMinimumSize(new Dimension(750, 500));
        Image img = null;
        try { img = ImageIO.read(AppThinker.class.getResource("img/logoAppThinker.png")); } catch (Exception ex) { }
        this.setIconImage(img);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLocationRelativeTo(null);

        this.setLayout(new BorderLayout());

        //Ajout du menu à la fenêtre
        _menubar = new AppThinkerMenuBar(this);
        this.setJMenuBar(_menubar);

        /*JTabbedPane tabbedPane = new JTabbedPane();

        JPanel panel1 = new JPanel();
        panel1.add(new JLabel("Panel #1"));
        tabbedPane.addTab("Start", panel1);

        JPanel panel2 = new JPanel();
        panel2.add(new JLabel("Projet #1"));
        tabbedPane.addTab("Mon Projet 1", panel2);

        JPanel panel3 = new JPanel();
        panel3.add(new JLabel("Projet #1"));
        tabbedPane.addTab("Mon Projet 2", panel3);

        this.add(tabbedPane, BorderLayout.CENTER);*/

        _contentPanel = new JPanel();
        _contentPanel.setLayout(new BorderLayout());

        this.add(_contentPanel, BorderLayout.CENTER);

        //Ajout de la statusbar à la fenêtre
        _statusbar = new AppThinkerStatusbar();
        this.add(_statusbar, BorderLayout.SOUTH);

        this.setVisible(true);
    }

    /**
     * Crée un nouveau Projet.
     */
    public void newProject(){
        _project = new Project();
        this.displayComposition(_project.getComposition());
        this._statusbar.setStatusMessage("The project has been created.");
    }

    /**
     * Ouvre un projet existant dans la fenêtre.
     */
    public void openProject(){
        FileNameExtensionFilter fileFilter = new FileNameExtensionFilter("AppThinker project", "appt");
        JFileChooser dialog = new JFileChooser();
        dialog.setDialogType(JFileChooser.OPEN_DIALOG);
        dialog.setDialogTitle("Open an AppThinker project");
        dialog.setFileFilter(fileFilter);
        dialog.setAcceptAllFileFilterUsed(false);
        if(dialog.showOpenDialog(null) == JFileChooser.APPROVE_OPTION){
            ObjectInputStream ois = null;
            Project project = null;
            try {
                final FileInputStream fichier = new FileInputStream(dialog.getSelectedFile().getPath());
                ois = new ObjectInputStream(fichier);
                project = (Project) ois.readObject();
            } catch (final java.io.IOException e) {
                e.printStackTrace();
            } catch (final ClassNotFoundException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (ois != null) {
                        ois.close();
                        _project = project;
                        this.displayComposition(_project.getComposition());
                        this._statusbar.setStatusMessage("The project has been opened.");
                    }
                } catch (final IOException ex) {
                    ex.printStackTrace();
                }
            }
        }
    }

    /**
     * Ferme le projet en cours.
     */
    public void closeProject(){
        this.setTitle("AppThinker");
        this.getMenubar().setProjectEnable(false);
        UmlToolbar toolbar = (UmlToolbar) _project.getComposition().getToolbar();
        toolbar.setEnabled(false);
        this.getStatusbar().setStatusMessage("The project has been closed.");
        this.getStatusbar().setFileMessage("No project opened.");
        this.clearComposition();
        _project = null;
    }

    /**
     * Récupère la menubar contenue dans la fenêtre.
     * @return La menubar contenue dans la fenêtre.
     */
    public AppThinkerMenuBar getMenubar(){
        return this._menubar;
    }

    /**
     * Récupère la statusbar contenue dans la fenêtre.
     * @return La statusbar contenue dans la fenêtre.
     */
    public AppThinkerStatusbar getStatusbar(){
        return this._statusbar;
    }

    /**
     * Affiche une composition au centre de la fenêtre.
     * @param composition La composition à afficher.
     */
    public void displayComposition(Composition composition){
        _composition = composition;
        composition.setWindow(this);

        //Ajout de la toolbar de la composition à la fenêtre
        UmlToolbar toolbar = (UmlToolbar) composition.getToolbar();
        _toolbar = toolbar;
        _contentPanel.add(toolbar, BorderLayout.NORTH);

        //Ajout du diagramme à la fenêtre
        JScrollPane compositionPane = new JScrollPane(_composition);
        _composition.setBackground(new Color(218, 233, 244));
        _contentPanel.add(compositionPane, BorderLayout.CENTER);

        //Modification de la barre de statut
        _statusbar.setFileMessage(composition.getProject().getName());

        //Modification du titre et activation des fonctionnalités d'édition
        this.setTitle((composition.getProject().getPath() == null) ? "AppThinker - " + composition.getProject().getName() + "*" : "AppThinker - " + composition.getProject().getName() + " (" + composition.getProject().getPath() + ")");
        _menubar.addCompositionMenu(composition);
        _menubar.setProjectEnable(true);
        _toolbar.setEnabled(true);
    }

    /**
     * Récupère le projet en cours.
     * @return Le projet en cours.
     */
    public Project getProject(){
        return _project;
    }

    /**
     * Retourne la composition en cours de visualisation.
     * @return La composition en cours de visualisation.
     */
    public Composition getComposition(){
        return _composition;
    }

    /**
     * Retire la composition de la fenêtre.
     */
    public void clearComposition(){
        this.remove(_contentPanel);
        this._menubar.removeCompositionMenu();
    }
}
