import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * Gère un projet.
 * @author V.BOULANGER
 */
public class Project implements Serializable {

    public static int _projectId = 0;

    private int _id;
    private String _name;
    private String _author;
    private String _version;
    private String _designation;
    private String _path;
    private Composition _composition;

    /**
     * Constructeur - Crée une instance de Projet.
     */
    public Project(){
        _projectId++;
        _id = _projectId;
        _name = "Untitled project";
        _author = "Unknown";
        _version = "0.0.1";
        _designation = "AppThinker UML Project.";
        _path = null;
        //Initialisation du projet avec un diagramme UML
        _composition = new UmlDiagram(this);
    }

    /**
     * Constructeur - Crée une instance de Projet avec des paramètres déterminés.
     * @param name Le nom du projet.
     * @param author L'auteur du projet.
     * @param version La version du projet.
     * @param designation La désignation du projet.
     * @param path Chemin vers le ficher enregistré.
     * @param composition La composition inclue dans le projet.
     */
    public Project(String name, String author, String version, String designation, String path, Composition composition){
        _projectId++;
        _id = _projectId;
        _name = name;
        _author = author;
        _version = version;
        _designation = designation;
        _path = path;
        _composition = composition;
    }

    /**
     * Récupère la composition associée au projet.
     * @return La composition associée au projet.
     */
    public Composition getComposition(){
        return this._composition;
    }

    /**
     * Récupère le numéro du Projet.
     * @return Le numéro du projet.
     */
    public int getId(){
        return this._id;
    }

    /**
     * Récupère le nom du Projet.
     * @return Le nom du projet.
     */
    public String getName(){
        return this._name;
    }

    /**
     * Paramètre le nom du Projet.
     * @param name Le nom du projet.
     */
    public void setName(String name){
        this._name = name;
    }

    /**
     * Récupère l'auteur du Projet.
     * @return L'auteur du projet.
     */
    public String getAuthor(){
        return this._author;
    }

    /**
     * Paramètre l'auteur du Projet.
     * @param author L'auteur du projet.
     */
    public void setAuthor(String author){
        this._author = author;
    }

    /**
     * Récupère le numéro de version du Projet.
     * @return Le numéro de version du projet.
     */
    public String getVersion(){
        return this._version;
    }

    /**
     * Paramètre le numéro de version du Projet.
     * @param version Le numéro de version du projet.
     */
    public void setVersion(String version){
        this._version = version;
    }

    /**
     * Récupère la désignation du Projet.
     * @return La désignation du projet.
     */
    public String getDesignation(){
        return this._designation;
    }

    /**
     * Paramètre la désignation du Projet.
     * @param designation La désignation du projet.
     */
    public void setDesignation(String designation){
        this._designation = designation;
    }

    /**
     * Récupère la désignation du Projet.
     * @return Le chemin du fichier du projet.
     */
    public String getPath(){
        return this._path;
    }

    /**
     * Paramètre la désignation du Projet.
     * @param path Le chemin vers le fichier du projet.
     */
    public void setPath(String path){
        this._path = path;
    }

    /**
     * Sauvegarde le projet en cours.
     * @return true : le projet a été sauvegardé, false sinon.
     */
    public boolean saveProject(){
        //Si le projet ne contient pas de path, on demande à l'enregistrer dans un emplacement
        FileNameExtensionFilter fileFilter = new FileNameExtensionFilter("AppThinker project", "appt");
        String path = this.getPath();
        if(path == null){
            JFileChooser dialog = new JFileChooser();
            dialog.setDialogTitle("Save an AppThinker project");
            dialog.setDialogType(JFileChooser.SAVE_DIALOG);
            dialog.setFileFilter(fileFilter);
            dialog.setAcceptAllFileFilterUsed(false);
            if(dialog.showOpenDialog(null) == JFileChooser.APPROVE_OPTION){
                String filePath = dialog.getSelectedFile().getPath();
                path = (filePath.contains(".appt")) ? filePath : filePath + ".appt";
            }
        }
        //On serialize le projet dans un fichier
        this.setPath(path);
        ObjectOutputStream oos = null;
        try {
            final FileOutputStream fichier = new FileOutputStream(path);
            oos = new ObjectOutputStream(fichier);
            oos.writeObject(this);
            oos.flush();
        } catch (final java.io.IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (oos != null) {
                    oos.flush();
                    oos.close();
                    return true;
                }
            } catch (final IOException ex) {
                ex.printStackTrace();
            }
            return false;
        }
    }

    /**
     * Sauvegarde le projet en cours à un autre emplacement.
     * @return true: le projet a été sauvegardé, false sinon.
     */
    public boolean saveAsProject(){
        //Enregistrer le projet sous un autre emplacement
        FileNameExtensionFilter fileFilter = new FileNameExtensionFilter("AppThinker project", "appt");
        String path = this.getPath();

        JFileChooser dialog = new JFileChooser();
        dialog.setDialogTitle("Save an AppThinker project");
        dialog.setDialogType(JFileChooser.SAVE_DIALOG);
        dialog.setFileFilter(fileFilter);
        dialog.setAcceptAllFileFilterUsed(false);
        if(dialog.showOpenDialog(null) == JFileChooser.APPROVE_OPTION){
            String filePath = dialog.getSelectedFile().getPath();
            path = (filePath.contains(".appt")) ? filePath : filePath + ".appt";
        }

        //On serialize le projet dans un fichier
        this.setPath(path);
        ObjectOutputStream oos = null;
        try {
            final FileOutputStream fichier = new FileOutputStream(path);
            oos = new ObjectOutputStream(fichier);
            oos.writeObject(this);
            oos.flush();
        } catch (final java.io.IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (oos != null) {
                    oos.flush();
                    oos.close();
                    return true;
                }
            } catch (final IOException ex) {
                ex.printStackTrace();
            }
            return false;
        }
    }
}
