package net.sf.jasperreports.engine.fill;

import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
import net.sf.jasperreports.engine.JRRuntimeException;

public class JRClonePool {
  private final JRFillCloneable original;
  
  private final LinkedList availableClones;
  
  private final boolean trackLockedClones;
  
  private final Set lockedClones;
  
  public JRClonePool(JRFillCloneable original, boolean trackLockedClones, boolean useOriginal) {
    this.original = original;
    this.availableClones = new LinkedList();
    this.trackLockedClones = trackLockedClones;
    if (trackLockedClones) {
      this.lockedClones = new HashSet();
    } else {
      this.lockedClones = null;
    } 
    if (useOriginal)
      this.availableClones.add(original); 
  }
  
  public Object getClone() {
    JRFillCloneable clone;
    if (this.availableClones.isEmpty()) {
      JRFillCloneFactory factory = new JRFillCloneFactory();
      clone = this.original.createClone(factory);
    } else {
      clone = this.availableClones.removeFirst();
    } 
    if (this.trackLockedClones)
      this.lockedClones.add(clone); 
    return clone;
  }
  
  public void releaseClone(Object clone) {
    if (this.trackLockedClones)
      if (!this.lockedClones.remove(clone))
        throw new JRRuntimeException("Cannot release clone.");  
    this.availableClones.addLast(clone);
  }
}
