/**
   * Adds a cell format to the hash map, keyed on its index. If the format record is not
   * initialized, then its index number is determined and its initialize method called. If the font
   * is not a built in format, then it is added to the list of formats for writing out
   *
   * @param fr the format record
   */
  public final void addFormat(DisplayFormat fr) throws NumFormatRecordsException {
    if (!fr.isInitialized()) {
      fr.initialize(nextCustomIndexNumber);
      nextCustomIndexNumber++;
    }

    if (nextCustomIndexNumber > maxFormatRecordsIndex) {
      nextCustomIndexNumber = maxFormatRecordsIndex;
      throw new NumFormatRecordsException();
    }

    if (fr.getFormatIndex() >= nextCustomIndexNumber) {
      nextCustomIndexNumber = fr.getFormatIndex() + 1;
    }

    if (!fr.isBuiltIn()) {
      formatsList.add(fr);
      formats.put(new Integer(fr.getFormatIndex()), fr);
    }
  }
  /**
   * Rationalizes the display formats. Duplicate formats are removed and the format indices of the
   * cells adjusted accordingly. It is invoked immediately prior to writing writing out the sheet
   *
   * @param im the index mapping for the font rationalization
   */
  public IndexMapping rationalizeDisplayFormats() {
    ArrayList newformats = new ArrayList();
    int numremoved = 0;
    IndexMapping mapping = new IndexMapping(nextCustomIndexNumber);

    // Iterate through the old list
    Iterator i = formatsList.iterator();
    DisplayFormat df = null;
    DisplayFormat df2 = null;
    boolean duplicate = false;
    while (i.hasNext()) {
      df = (DisplayFormat) i.next();

      Assert.verify(!df.isBuiltIn());

      // Compare against formats already on the list
      Iterator i2 = newformats.iterator();
      duplicate = false;
      while (i2.hasNext() && !duplicate) {
        df2 = (DisplayFormat) i2.next();
        if (df2.equals(df)) {
          duplicate = true;
          mapping.setMapping(df.getFormatIndex(), mapping.getNewIndex(df2.getFormatIndex()));
          numremoved++;
        }
      }

      // If this format is not a duplicate then add it to the new list
      if (!duplicate) {
        newformats.add(df);
        int indexnum = df.getFormatIndex() - numremoved;
        if (indexnum > maxFormatRecordsIndex) {
          System.err.println("Warning:  too many number formats - using default format");
          indexnum = 0; // the default number format index
        }
        mapping.setMapping(df.getFormatIndex(), df.getFormatIndex() - numremoved);
      }
    }

    // Set the new list
    formatsList = newformats;

    // Update the index codes for the remaining formats
    i = formatsList.iterator();

    while (i.hasNext()) {
      df = (DisplayFormat) i.next();
      df.initialize(mapping.getNewIndex(df.getFormatIndex()));
    }

    return mapping;
  }