package yacs.domain;

/**
 * <p>Klasse zur Repräsentation von einzelnen Elementen für symbolische finite
 * Domänen. Der Wert eines Elements wird durch eine Instanz der Klasse
 * <code>String</code> zum Ausdruck gebracht. Die Methoden dieser Klasse
 * implementieren Operationen auf <code>Strings</code>, wie das Anhängen durch
 * <code>plus()</code> oder Entfernen durch <code>minus()</code> eines
 * Substrings an bzw. aus einem bestehenden <code>String</code>. Die Methoden
 * <code>times()</code> und <code>divide()</code> sowie <code>uminus()</code>
 * sind "Dummies", die nur ein <code>SymbolicFDElement</code> mit der Belegung
 * "" (leerer <code>String</code>) bzw. das bestehende Objekt zurückgeben. Die
 * Vergleichsoperatoren entsprechen lexikographischen
 * <code>String</code>-Vergleichen (<code>equals()</code> und
 * <code>compareTo()</code>).
 *
 * <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 SymbolicFDElement extends DomainElement {

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

  /** Der Wert dieses Elements. */
  private String value;

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

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

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

  /**
   * Konstruktor -- Benötigt ein <code>String</code>-Objekt zur Instantiierung.
   * @param value String
   */
  public SymbolicFDElement(String value) {
    this.value = value;
  }

  public Object getValue() {
    return this.value;
  }

  /**
   * Liefert ein <code>SymbolicFDElement</code>, welches als Belegung den um den
   * übergebenen Parameter ergänzten <code>String</code> enthält.
   * @param param DomainElement
   * @return DomainElement
   */
  public DomainElement plus(DomainElement param) {
    return new SymbolicFDElement(this.value.concat(param.getValue().toString()));
  }

  /**
   * Liefert ein <code>SymbolicFDElement</code>, welches als Belegung den um
   * sämtliche Vorkommen des übergebenen Parameters reduzierten
   * <code>String</code> enthält.
   * @param param DomainElement
   * @return DomainElement
   */
  public DomainElement minus(DomainElement param) {
    return new SymbolicFDElement(this.value.replaceAll(param.getValue().toString(), ""));
  }

  /**
   * Dummy, liefert immer ein <code>SymbolicFDElement</code> mit der Belegung ""
   * (leerer <code>String</code>).
   * @param param DomainElement
   * @return DomainElement
   */
  public DomainElement times(DomainElement param) {
    return new SymbolicFDElement("");
  }

  /**
   * Dummy, liefert immer ein <code>SymbolicFDElement</code> mit der Belegung ""
   * (leerer <code>String</code>).
   * @param param DomainElement
   * @return DomainElement
   */
  public DomainElement divide(DomainElement param) {
    return new SymbolicFDElement("");
  }

  /**
   * Dummy, liefert immer das aktuelle Objekt.
   * @return DomainElement
   */
  public DomainElement uminus() {
    return this;
  }

  /**
   * Vergleicht die <code>Strings</code> mit <code>equals()</code>.
   * @param param DomainElement
   * @return boolean
   */
  public boolean equals(DomainElement param) {
    return this.value.equals(param.getValue().toString());
  }

  /**
   * Vergleicht die <code>Strings</code> mit <code>!(equals())</code>.
   * @param param DomainElement
   * @return boolean
   */
  public boolean notEquals(DomainElement param) {
    return !(this.value.equals(param.getValue().toString()));
  }

  /**
   * Vergleicht die <code>Strings</code> lexikographisch mit
   * <code>compareTo()</code>.
   * @param param DomainElement
   * @return boolean
   */
  public boolean greaterAs(DomainElement param) {
    if (this.value.compareTo(param.getValue().toString()) > 0) {
      return true;
    } else {
      return false;
    }
  }

  /**
   * Vergleicht die <code>Strings</code> lexikographisch mit
   * <code>compareTo()</code>.
   * @param param DomainElement
   * @return boolean
   */
  public boolean lowerAs(DomainElement param) {
    if (this.value.compareTo(param.getValue().toString()) < 0) {
      return true;
    } else {
      return false;
    }
  }

  /**
   * Vergleicht die <code>Strings</code> lexikographisch mit
   * <code>compareTo()</code>.
   * @param param DomainElement
   * @return boolean
   */
  public boolean greaterEqualAs(DomainElement param) {
    if (this.value.compareTo(param.getValue().toString()) >= 0) {
      return true;
    } else {
      return false;
    }
  }

  /**
   * Vergleicht die <code>Strings</code> lexikographisch mit
   * <code>compareTo()</code>.
   * @param param DomainElement
   * @return boolean
   */
  public boolean lowerEqualAs(DomainElement param) {
    if (this.value.compareTo(param.getValue().toString()) <= 0) {
      return true;
    } else {
      return false;
    }
  }

  public String toString() {
    return this.value.toString();
  }

}
