package yacs.net;

import yacs.exceptions.*;
import yacs.solver.*;

import java.util.*;

/**
 * <p>Klasse zur Repräsentation einer Constraint-Lösungsstrategie von YACS.</p>
 *
 * <p>Copyright (C) 2005  Wolfgang Runte
 * <br><br>
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * <br><br>
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * <br><br>
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
 * USA</p>
 *
 * @author Wolfgang Runte (woru@tzi.org)
 * @version YACS 0.1.1
 */
public class Strategy {

// ********** private attributs **********

  /** Der Name der Constraint-Lösungsstrategie. */
  private String strategyName;

  /**
   * Liste der in dieser Strategie spezifizierten Constraint-Solver zum
   * Preprozessing (enthält Instanzen der Klasse
   * <code>yacs.Solver.PreprocessingSolver</code>).
   */
  private List preprocessingSolvers = new LinkedList();

  /**
   * Liste der in dieser Strategie spezifizierten Constraint-Solver zur
   * Konsistenzherstellung (enthält Instanzen der Klasse
   * <code>yacs.Solver.ConsistencySolver</code>).
   */
  private List consistencySolvers = new LinkedList();

  /**
   * Liste der in dieser Strategie spezifizierten Constraint-Solver zur
   * Lösungssuche (enthält Instanzen der Klasse
   * <code>yacs.Solver.SearchSolver</code>).
   */
  private List searchSolvers = new LinkedList();

// ********** public attributs **********

// ********** private methods **********

// ********** protected methods **********

  /**
   * Fügt einen Constraint-Solver für das Preprozessing hinzu.
   * @param solver PreprocessingSolver
   */
  protected void addPreprocessingSolver(PreprocessingSolver solver) throws
          OnlyPreprocessingSolversAllowedException {
    if (solver instanceof PreprocessingSolver) {
      this.preprocessingSolvers.add(solver);
    } else {
      throw new OnlyPreprocessingSolversAllowedException();
    }
  }

  /**
   * Fügt einen Constraint-Solver für die Konsistenzherstellung hinzu.
   * @param solver ConsistencySolver
   */
  protected void addConsistencySolver(ConsistencySolver solver) throws
          OnlyConsistencySolversAllowedException {
    if (solver instanceof ConsistencySolver) {
      this.consistencySolvers.add(solver);
    } else {
      throw new OnlyConsistencySolversAllowedException();
    }
  }

  /**
   * Fügt einen Constraint-Solver für die Lösungssuche hinzu.
   * @param solver SearchSolver
   */
  protected void addSearchSolver(SearchSolver solver) throws
          OnlySearchSolversAllowedException {
    if (solver instanceof SearchSolver) {
      this.searchSolvers.add(solver);
    } else {
      throw new OnlySearchSolversAllowedException();
    }
  }

// ********** public methods **********

  /**
   * Konstruktor -- Benötigt den Namen der Strategie.
   * @param strategyName String
   */
  public Strategy(String strategyName) {
    this.strategyName = strategyName;
  }

  /**
   * Liefert den Namen der Constraint-Lösungsstragie.
   * @return String
   */
  public String getStrategyName() {
    return this.strategyName;
  }

  /**
   * Liefert die Liste der in dieser Strategie spezifizierten Constraint-Solver
   * zum Preprozessing (enthält Instanzen der Klasse
   * <code>yacs.Solver.PreprocessingSolver</code>).
   * @return List
   */
  public List getPreprocessingSolvers() {
    return this.preprocessingSolvers;
  }

  /**
   * Liefert die Liste der in dieser Strategie spezifizierten Constraint-Solver
   * zur Konsistenzherstellung (enthält Instanzen der Klasse
   * <code>yacs.Solver.ConsistencySolver</code>).
   * @return List
   */
  public List getConsistencySolvers() {
    return this.consistencySolvers;
  }

  /**
   * Liefert die Liste der in dieser Strategie spezifizierten Constraint-Solver
   * zur Lösungssuche (enthält Instanzen der Klasse
   * <code>yacs.Solver.SearchSolver</code>).
   * @return List
   */
  public List getSearchSolvers() {
    return this.searchSolvers;
  }

  /**
   * Rückgabe der Strategie als <code>String</code> (für Debugging).
   * @return String
   */
  public String toString() {
    String returnString = new String();
    Iterator it;
    returnString += "Name: " + getStrategyName() + "\n";
    // Preprozessing-Solver hinzufügen:
    returnString += "preprocessing solvers: ";
    it = this.getPreprocessingSolvers().iterator();
    while (it.hasNext()) {
      returnString += it.next() + " ";
    }
    returnString += "\n";
    // Consistency-Solver hinzufügen:
    returnString += "consistency solvers: ";
    it = this.getConsistencySolvers().iterator();
    while (it.hasNext()) {
      returnString += it.next() + " ";
    }
    returnString += "\n";
    // Search-Solver hinzufügen:
    returnString += "search solvers: ";
    it = this.getSearchSolvers().iterator();
    while (it.hasNext()) {
      returnString += it.next() + " ";
    }
    returnString += "\n";
    return returnString;
  }

}
