import java.io.Serializable;

/**
 * Gère un lien entre deux classes.
 * @author V.BOULANGER
 */
public class Link implements Serializable{

    public static int _linkId = 0;
    public static final int STRONG = 0;
    public static final int WEAK = 1;
    public static final int COMPOSITION = 2;
    public static final int AGGREGATION = 3;
    public static final int INHERITANCE = 4;
    public static final int CARD_UNLIMITED = -1;
    public static final int CARD_NULL = 0;
    public static final int CARD_ONE = 1;

    private int _id;
    private Class _start;
    private int _minCardinalityStart;
    private int _maxCardinalityStart;
    private Class _end;
    private int _minCardinalityEnd;
    private int _maxCardinalityEnd;
    private int _type;

    /**
     * Constructeur - Crée une instance d'une classe.
     * @param start La classe de départ.
     * @param end La classe d'arrivée.
     */
    public Link(Class start, Class end){
        _linkId++;
        this._id = _linkId;
        this._start = start;
        this._end = end;
        this._minCardinalityStart = Link.CARD_NULL;
        this._maxCardinalityStart = Link.CARD_UNLIMITED;
        this._minCardinalityEnd = Link.CARD_NULL;
        this._maxCardinalityEnd = Link.CARD_UNLIMITED;
        this._type = Link.STRONG;
    }

    /**
     * Constructeur - Crée une instance d'une classe avec des paramètres déterminés.
     * @param start La classe de départ.
     * @param end La classe d'arrivée.
     * @param minCardinalityStart La cardinalité minimum de la classe de départ.
     * @param maxCardinalityStart La cardinalité maximuù de la classe de départ.
     * @param minCardinalityEnd La cardinalité minimum de la classe d'arrivée.
     * @param maxCardinalityEnd La cardinalité maximum de la classe d'arrivée.
     * @param type Le type de lien.
     */
    public Link(Class start, Class end, int minCardinalityStart, int maxCardinalityStart, int minCardinalityEnd, int maxCardinalityEnd, int type){
        _linkId++;
        this._id = _linkId;
        this._start = start;
        this._end = end;
        this._minCardinalityStart = minCardinalityStart;
        this._maxCardinalityStart = maxCardinalityStart;
        this._minCardinalityEnd = minCardinalityEnd;
        this._maxCardinalityEnd = maxCardinalityEnd;
        this._type = type;
    }

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

    /**
     * Récupère la classe de départ du lien.
     * @return La classe de départ du lien.
     */
    public Class getStart() {
        return _start;
    }

    /**
     * Paramètre la classe de départ du lien.
     * @param start La classe de départ du lien.
     */
    public void setStart(Class start) {
        this._start = start;
    }

    /**
     * Récupère la classe d'arrivée du lien.
     * @return La classe d'arrivée du lien.
     */
    public Class getEnd() {
        return _end;
    }

    /**
     * Paramètre la classe d'arrivée.
     * @param end La classe d'arrivée.
     */
    public void setEnd(Class end) {
        this._end = end;
    }

    /**
     * Récupère la cardinalité minimum de la classe de départ.
     * @return La cardinalité minimum de la classe de départ.
     */
    public int getMinCardinalityStart() {
        return _minCardinalityStart;
    }

    /**
     * Paramètre la cardinalité minimum de la classe de départ.
     * @param minCardinalityStart La cardinalité minimum de la classe de départ.
     */
    public void setMinCardinalityStart(int minCardinalityStart) {
        this._minCardinalityStart = minCardinalityStart;
    }

    /**
     * Récupère la cardinalité maximum de la classe de départ.
     * @return La cardinalité maximum de la classe de départ.
     */
    public int getMaxCardinalityStart() {
        return _maxCardinalityStart;
    }

    /**
     * Paramètre la cardinalité maximum de la classe de départ.
     * @param maxCardinalityStart La cardinalité maximum de la classe de départ.
     */
    public void setMaxCardinalityStart(int maxCardinalityStart) {
        this._maxCardinalityStart = maxCardinalityStart;
    }

    /**
     * Récupère la cardinalité minimum de la classe d'arrivée.
     * @return La cardinalité minimum de la classe d'arrivée.
     */
    public int getMinCardinalityEnd() {
        return _minCardinalityEnd;
    }

    /**
     * Paramètre la cardinalité minimum de la classe d'arrivée.
     * @param minCardinalityEnd La cardinalité minimum de la classe d'arrivée.
     */
    public void setMinCardinalityEnd(int minCardinalityEnd) {
        this._minCardinalityEnd = minCardinalityEnd;
    }

    /**
     * Récupère la cardinalité maximum de la classe d'arrivée.
     * @return La cardinalité maximum de la classe d'arrivée.
     */
    public int getMaxCardinalityEnd() {
        return _maxCardinalityEnd;
    }

    /**
     * Paramètre la cardinalité maximum de la classe d'arrivée.
     * @param maxCardinalityEnd La cardinalité maximum de la classe d'arrivée.
     */
    public void setMaxCardinalityEnd(int maxCardinalityEnd) {
        this._maxCardinalityEnd = maxCardinalityEnd;
    }

    /**
     * Récupère le type du lien.
     * @return Le type du lien.
     */
    public int getType() {
        return _type;
    }

    /**
     * Paramètre le type du lien
     * @param type Le type du lien.
     */
    public void setType(int type) {
        this._type = type;
    }

    /**
     * Modifie la direction du lien (permute les classes de départ et d'arrivée).
     */
    public void switchDirection(){
        Class start = this._start;
        int minStart = this._minCardinalityStart;
        int maxStart = this._maxCardinalityStart;
        this._start = _end;
        this._end = start;
        this._minCardinalityStart = _minCardinalityEnd;
        this._maxCardinalityStart = _maxCardinalityEnd;
        this._minCardinalityEnd = minStart;
        this._maxCardinalityEnd = maxStart;
    }
}
