/*
 * Licensed Materials - Property of Perforce Software, Inc. 
 * © Copyright Perforce Software, Inc. 2014, 2021 
 * © Copyright IBM Corp. 2009, 2014
 * © Copyright ILOG 1996, 2009
 * All Rights Reserved.
 *
 * Note to U.S. Government Users Restricted Rights:
 * The Software and Documentation were developed at private expense and
 * are "Commercial Items" as that term is defined at 48 CFR 2.101,
 * consisting of "Commercial Computer Software" and
 * "Commercial Computer Software Documentation", as such terms are
 * used in 48 CFR 12.212 or 48 CFR 227.7202-1 through 227.7202-4,
 * as applicable.
 */
package shared.data;


import ilog.views.gantt.*;
import ilog.views.gantt.event.GanttModelChangedEvent;
import ilog.views.gantt.event.GanttModelListener;
import ilog.views.gantt.model.IlvSimpleActivity;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;


/**
 * <code>SimpleActivityFactory</code> is a factory that will create new
 * instances of <code>IlvSimpleActivity</code> that are numbered sequentially.
 */
public class SimpleActivityFactory implements IlvActivityFactory
{
  /**
   * The number of the next activity that will be created.
   */
  private int activityCount;

  /**
   * The chart that the factory is associated with.
   */
  private IlvHierarchyChart chart;

  /**
   * Creates a new <code>SimpleActivityFactory</code> for the specified chart.
   */
  public SimpleActivityFactory(IlvHierarchyChart chart) {
    this.chart = chart;
    resetSequence();

    // Whenever the chart's Gantt model is changed, we reset the factory's
    // numbering system.
    chart.addGanttModelListener(new GanttModelListener()
    {
      Override
      public void ganttModelChanged(GanttModelChangedEvent evt) {
        if (!evt.isAboutToChangeEvent()) {
          resetSequence();
        }
      }
    });
  }

  /**
   * Resets the numbering sequence that the factory assigns to new activities.
   */
  private void resetSequence() {
    activityCount = 1;
  }

  /**
   * Returns the set of all activity ID's in the chart's data model.
   */
  private Set<String> getActivityIDs() {
    Set<String> idSet = new HashSet<String>();
    IlvGanttModel model = chart.getGanttModel();
    if (model != null) {
      for (Iterator<IlvActivity> i = IlvGanttModelUtil.activityPreorderIterator(model);
           i.hasNext();) {
        IlvActivity a = i.next();
        idSet.add(a.getID());
      }
    }
    return idSet;
  }

  /**
   * Creates a new <code>IlvSimpleActivity</code> from the given parameters.
   * Subclasses should override this method to create a different type of
   * activity, not <code>createActivity</code>.
   * @param interval The time interval.
   * @param activityNum The activity number.
   */
  protected IlvActivity createActivityImpl(IlvTimeInterval interval,
                                           int activityNum) {
    IlvActivity newAct = new IlvSimpleActivity("Act. #" + activityNum,
                                               "New Activity #" + activityNum,
                                               interval);
    return newAct;
  }

  /**
   * Creates a new <code>IlvSimpleActivity</code> from the given parameters.
   * Subclasses should override <code>createActivityImpl</code> instead of this
   * method in order to create a different type of activity.
   * @param interval The time interval.
   */
  Override
  public IlvActivity createActivity(IlvTimeInterval interval) {
    // Look for a unique ID
    Set<String> ids = getActivityIDs();
    IlvActivity activity;
    do {
      activity = createActivityImpl(interval, activityCount++);
    } while (ids.contains(activity.getID()));
    return activity;
  }

}