/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package opennlp.tools.coref;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import opennlp.tools.coref.mention.MentionContext;

/**
 * Represents the elements which are part of a discourse.
 */
public class DiscourseModel {

  private List<DiscourseEntity> entities;

  int nextEntityId = 1;

  /**
   * Creates a new discourse model.
   */
  public DiscourseModel() {
    entities = new ArrayList<DiscourseEntity>();
  }

  /**
   * Indicates that the specified entity has been mentioned.
   * 
   * @param e The entity which has been mentioned.
   */
  public void mentionEntity(DiscourseEntity e) {
    if (entities.remove(e)) {
      entities.add(0,e);
    }
    else {
      System.err.println("DiscourseModel.mentionEntity: failed to remove "+e);
    }
  }

  /**
   * Returns the number of entities in this discourse model.
   * 
   * @return the number of entities in this discourse model.
   */
  public int getNumEntities() {
    return entities.size();
  }

  /**
   * Returns the entity at the specified index.
   * 
   * @param i The index of the entity to be returned.
   * @return the entity at the specified index.
   */
  public DiscourseEntity getEntity(int i) {
    return entities.get(i);
  }

  /**
   * Adds the specified entity to this discourse model.
   * 
   * @param e the entity to be added to the model.
   */
  public void addEntity(DiscourseEntity e) {
    e.setId(nextEntityId);
    nextEntityId++;
    entities.add(0,e);
  }

  /**
   * Merges the specified entities into a single entity with the specified confidence.
   * 
   * @param e1 The first entity.
   * @param e2 The second entity.
   * @param confidence The confidence.
   */
  public void mergeEntities(DiscourseEntity e1,DiscourseEntity e2,float confidence) {
    for (Iterator<MentionContext> ei=e2.getMentions();ei.hasNext();) {
      e1.addMention(ei.next());
    }
    //System.err.println("DiscourseModel.mergeEntities: removing "+e2);
    entities.remove(e2);
  }

  /**
   * Returns the entities in the discourse model.
   * 
   * @return the entities in the discourse model.
   */
  public DiscourseEntity[] getEntities() {
    DiscourseEntity[] des = new DiscourseEntity[entities.size()];
    entities.toArray(des);
    return des;
  }

  /**
   * Removes all elements from this discourse model.
   */
  public void clear() {
    entities.clear();
  }
}
