/*
 * ActivityDependenceInterface.java
 *
 * Created on 21. říjen 2000, 15:31
 * Documented 8.7.2001
 */

package timetable.data;

/** Abstraktní třída implementující základní rozhraní, které musí každá závislost mezi aktivitami splňovat.
 * <br>
 * Abychom mohli vyjádřit například, že jedna aktivita musí být před druhou, je nutné určit pořadí aktivit.
 * Proto má rozhraní dvěmetody pro nastavení aktivity, tj. nastavení první a druhé z nich.
 *
 * @author Tomáš Müller
 * @version 1.0
 */
public abstract class AbstractActivityDependence implements ActivityDependenceInterface {
    /** První z aktivit */
    protected Activity first;
    
    /** Druhá z aktivit */
    protected Activity second;
    
    /** Typ závislosti*/
    protected int type=0;
    
    /** Konstruktor. */
    public AbstractActivityDependence() {
        this(null,null);
    }
    
    /** Konstruktor.
     * @param first první aktivita
     * @param second druhá aktivita
     */
    public AbstractActivityDependence(Activity first, Activity second) {
        this.first=first;
        this.second=second;
    }

    /** Zjištění splnění podmínky
     * @param activityStart1 začátek první aktivity
     * @param activityStart2 začátek druhé aktivity
     * @return true, pokud bude podmínka splěna
     */
    public abstract boolean isOK(int activityStart1,int activityStart2);
    
    /** Vrátí jméno závislosti - pro vizualizaci. Např: časová závislots
     * @return jméno závislosti
     */
    public abstract String getDependenceName();
    
    /** Vrátí pole jmen jednotlivých typů podmínky - pro vizualizaci ! 
     * @return pole jmen typů
     */
    public abstract String[] getTypes();

    /** Zjištění typu podmínky
     * @return typ podmínky
     */
    public int getType() {
        return type;
    }
    
    /** Zjištění splění závislosti
     * @return true, pokud je závislost splněna
     */
    public boolean isOK() {
        return isOK(first.start,second.start);
    }
    
    /** Zjištění splění závislosti, pokud bude mít jedna z aktivit změněn počáteční čas.
     * @param a aktivita (první nebo druhá)
     * @param start začátek aktivity a
     * @return true, pokud bude podmínka splěna
     */
    public boolean isOK(Activity a, int start) {
        if (a==first) 
            return isOK(start,second.start);
        else if (a==second)
            return isOK(first.start,start);
        else return true;
    }
    
    /** Zjištění první aktivity závislosti
     * @return první aktivita závislosti
     */
    public Activity getFirstActivity() { return first; }
    
    /** Zjištění druhé aktivity závislosti
     * @return druhá aktivia závislosti
     */
    public Activity getSecondActivity() { return second; }
    
    /** Metoda vracející druhou z aktivit.
     * @param a jedna z aktivit
     * @return druhá z aktivit
     */
    public Activity getAnotherActivity(Activity a) {
        if (a==first) return second; 
        else if (a==second) return first;
        else return null;
    }
    
    /** Zjistí, zda-li se nějaká aktivita účastní podmínky.
     * @param a aktivita
     * @return true, pokud se aktivita a účastní podmínky
     */
   public boolean participate(Activity a) {
       return (a==first || a==second);
   }

    /** Zapíše objekt do streamu
    * @param out stream
    * @param allActivities množina všech aktivit
    */
   public abstract void write(java.io.ObjectOutputStream out,ActivityGroup allActivites) throws java.io.IOException ;
   
   /** Načte objekt ze streamu
    * @param in stream
    * @param allActivities množina všech aktivit
    * @return načtený objekt
    */  
   public abstract ActivityDependenceInterface read(java.io.ObjectInputStream in, ActivityGroup allActivities) throws java.io.IOException, java.lang.ClassNotFoundException ;
   
    /** Nastavení první aktivity závislosti. 
     * @param a aktivita
     */
   public void setFirstActivity(Activity a) {
       this.first=a;
   }   
   
    /** Nastavení druhé aktivity závislosti
     * @param b aktivita
     */
   public void setSecondActivity(Activity b) {
       this.second=b;
   }
   
    /** nastavení typu podmínky. Tímto lze umožnit implementaci více podmínek jednou třídou. 
     * @param i typ podmínky     
     */
   public void setType(int i) {
       type=i;
   }
   
}
