package stringhistory;

import java.util.*;


/**
 * The class StringHistory instantiates objects to store strings in
 * a fifo manner. A string history has to be constructed with a
 * maxStringCount indicating the maximum number of strings that can be
 * stored. maxStringCount can be changed. If getting rid of strings is
 * necessary the oldest strings are sacrificed.
 */
public class StringHistory {
  private String name = "";     // name of the history
  private List strings;         // list of the strings
  private int maxStringCount;   // holds maximum number of strings


  /**
   * Create an empty string history and name it.
   * @params maxStringCount   maximum number of strings
   *         name             name of the string history
   */
  public StringHistory(int maxStringCount, String name) {
    this.maxStringCount = maxStringCount;
    strings = new ArrayList(maxStringCount);
    this.name = name;
  }



  /**
   * Clone (deep copy) the string history.
   * @return                  the cloned string history
   */
  public StringHistory cloneHistory() {
    StringHistory cloneHistory =
      new StringHistory(maxStringCount, name.substring(0));

    for (Iterator it = strings.iterator(); it.hasNext(); ) {
      cloneHistory.add(((String)it.next()).substring(0));
    }
    return cloneHistory;
  }



  /**
   * Empty the string history.
   */
  public void clear() {
    strings.clear();
  }



  /**
   * Set the name of the string history.
   * @params String name      name of the string history;
   *                          null creates an empty string
   */
  public void setName(String name) {
    if (name == null) {
      this.name = "";
    }
    else {
      this.name = name;
    }
  }



  /**
   * Add a string into the string history.
   * @params str              string to be added
   */
  public void add(String str) {
    if (strings.size() == maxStringCount) {
      strings.remove(0);
    }
    strings.add(str);
  }



  /**
   * Set the string count, i.e. redefine the capacity of the string
   * history.
   * If dropping of strings is necessary the oldest strings are dropped.
   * @params maxStringCount   max number of strings in the history
   */
  public void setStringCount(int maxStringCount) {
    this.maxStringCount = maxStringCount;

    int diff = strings.size() - maxStringCount;
    if (diff > 0) {
      for (int i = 0; i < diff; i++) {
        strings.remove(0);
      }
      ((ArrayList)strings).trimToSize();
    }
    else {
      ((ArrayList)strings).ensureCapacity(maxStringCount);
    }
  }


  /**
   * Return the string representation of this history. The first line
   * designating the oldest entry, the last line the youngest.
   */
  public String toString() {
    StringBuffer sb = new StringBuffer();
    int i = 1;

    if (name.length() == 0) {
      sb.append("string history; maxStringCount: " + maxStringCount + "\n");
    }
    else {
      sb.append('"' + name + '"' + "; maxStringCount: " + maxStringCount + "\n");
    }
    if (strings.size() == 0) {
      sb.append("empty\n");
    }

    for (Iterator it = strings.iterator(); it.hasNext(); ) {
      sb.append(i++ + ": " + it.next() + "\n");
    }
    return sb.toString();
  }

}
