/*
 * 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.IlvSimpleResource;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;


/**
 * <code>SimpleResourceFactory</code> is a factory that will create new
 * instances of <code>IlvSimpleResource</code> that are numbered sequentially.
 */
public class SimpleResourceFactory implements IlvResourceFactory
{
  /**
   * The number of the next resource that will be created.
   */
  private int resourceCount;

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

  /**
   * Creates a new <code>SimpleResourceFactory</code> for the specified chart.
   */
  public SimpleResourceFactory(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 resources.
   */
  private void resetSequence() {
    resourceCount = 1;
  }

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

  /**
   * Creates a new <code>IlvSimpleResource</code> from the given parameters.
   * Subclasses should override this method to create a different type of
   * resource, not <code>createResource</code>.
   * @param resourceNum The resource number.
   */
  protected IlvResource createResourceImpl(int resourceNum) {
    IlvResource newRes = new IlvSimpleResource("Res. #" + resourceNum,
                                               "New Resource #" + resourceNum);
    return newRes;
  }

  /**
   * Creates a new <code>IlvSimpleResource</code>.
   * Subclasses should override <code>createResourceImpl</code> instead of this
   * method in order to create a different type of resource.
   */
  Override
  public IlvResource createResource() {
    // Look for a unique ID
    Set<String> ids = getResourceIDs();
    IlvResource resource;
    do {
      resource = createResourceImpl(resourceCount++);
    } while (ids.contains(resource.getID()));
    return resource;
  }

}