package yacs.net;

import yacs.domain.*;

import java.util.*;

/**
 * <p>Klasse zur Repräsentation einer Lösung eines Constraint-Problems. Eine
 * Lösung besteht aus der Menge der Variablen des Problems und einer jeweils
 * zugeordneten Wertebelegung.</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 Solution {

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

  /**
   * HashMap zum Ablegen des Variablennamens (als "Key", String) und der jeweils
   * zugehörigen Wertebelegung (als "Value", Instanz des Interface
   * <code>yacs.domain.DomainElement</code>).
   */
  private Map solution = new HashMap();

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

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

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

  /**
   * Fügt die übergebene Variable (String) mit der angegebenen Wertebelegung
   * (Instanz des Interface <code>yacs.domain.DomainElement</code>) dieser
   * Lösung hinzu.
   * @param variableName String
   * @param variableValue DomainElement
   */
  public void addVariable(String variableName, DomainElement variableValue) {
    solution.put(variableName, variableValue);
  }

  /**
   * Liefert eine "unmodifizierbare" Liste mit den Namen (Strings) der an dieser
   * Lösung involvierten Variablen.
   * @return List
   */
  public List getVariables() {
    return Collections.unmodifiableList(new LinkedList(solution.keySet()));
  }

  /**
   * Liefert die Wertebelegung der übergebenen Variable in dieser Lösung.
   * @param variableName String
   * @return DomainElement
   */
  public DomainElement getValue(String variableName) {
    return (DomainElement)solution.get(variableName);
  }

  /**
   * Überprüft, ob die übergebene Lösung identisch mit der aktuellen ist.
   * @param solution Solution
   * @return boolean
   */
  public boolean equals(Solution solution) {
    return this.solution.equals(solution.solution);
  }

  /**
   * Generiert zu Debugging-Zwecken einen String mit den
   * Variablen/Wertebelegungen dieser Lösung.
   * @return String
   */
  public String toString() {
    String actVariableName;
    DomainElement actVariableValue;
    String returnString = new String();
    Iterator it = solution.keySet().iterator();
    // Alle gespeicherten Variablen durchgehen:
    while (it.hasNext()) {
      actVariableName = (String)it.next();
      returnString += actVariableName;
      actVariableValue = (DomainElement)solution.get(actVariableName);
      returnString += " = " + actVariableValue.toString();
      if (it.hasNext()) {
        returnString += ", ";
      }
    }
    returnString += "; ";
    return returnString;
  }

/*
  public static void main(String[] args) {
    //
    // Test der equals()-Methode ...
    //
    Solution s1 = new Solution();
    Solution s2 = new Solution();

    // Unterschiedliche Domänen-Objekte erzeugen:
    NumericFDElement value1 = new NumericFDElement(5);
    NumericFDElement value2 = new NumericFDElement(10);
    SymbolicFDElement value3 = new SymbolicFDElement("rot");
    SymbolicFDElement value4 = new SymbolicFDElement("grün");
    IntervalDomainElement value5 = new IntervalDomainElement(5,6);
    IntervalDomainElement value6 = new IntervalDomainElement(10,11);

    // ... und den Lösungen ...
    s1.addVariable("Variable1", value1);
    s1.addVariable("Variable2", value2);
    s1.addVariable("Variable3", value2);
    s1.addVariable("Variable4", value2);
    s1.addVariable("Variable5", value2);
    s1.addVariable("Variable6", value2);
    // ... hinzufügen.
    s2.addVariable("Variable1", value1);
    s2.addVariable("Variable2", value2);
    s2.addVariable("Variable3", value2);
    s2.addVariable("Variable4", value2);
    s2.addVariable("Variable5", value2);
    s2.addVariable("Variable6", value2);

    // Funktioniert nur, wenn die "Values" dieselben Objekte sind! Solutions
    // mit gleich angelegten DomainElements als "Values" ergeben false:
    System.out.println("s1.equals(s2): " + s1.equals(s2));
  }
*/

}
