/*
 * 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.
 */

import java.io.IOException;
import java.util.Vector;

import ilog.views.io.IlvInputStream;
import ilog.views.io.IlvOutputStream;
import ilog.views.io.IlvReadFileException;
import ilog.views.tiling.IlvTile;
import ilog.views.tiling.IlvTileCache;
import ilog.views.tiling.IlvTileController;

/**
 * A simple tile cache that caches a given number of tiles.
 */
public class SimpleTileCache extends IlvTileCache {
  // Default cache size.
  private int cacheSize = 5;
  // To store the tiles.
  transient private Vector<IlvTile> tiles = new Vector<IlvTile>();

  /**
   * Creates an instance of the default cache with the specified size.
   * 
   * @param size
   *          The default cache size.
   */
  public SimpleTileCache(int size) {
    cacheSize = size;
  }

  /**
   * Reads a cache from an <code>IlvInputStream</code>.
   * 
   * @param stream
   *          The input stream.
   * @exception IlvReadFileException
   *              if an error occurs while reading.
   */
  public SimpleTileCache(IlvInputStream stream) throws IlvReadFileException {
    cacheSize = stream.readInt("size");
  }

  /**
   * Writes the cache to an <code>IlvOutputStream</code>.
   */
  Override
  public void write(IlvOutputStream stream) throws IOException {
    super.write(stream);
    stream.write("size", cacheSize);
  }

  /**
   * Called each time that a loaded tile no longer has a lock.
   * 
   * @param tile
   *          The tile that has to be cached.
   */
  Override
  public void tileCached(IlvTile tile) {
    tiles.addElement(tile);
  }

  /**
   * Called each time that an unreleased cached tile is locked again.
   * 
   * @param tile
   *          The tile that is retrieved from the cache by a tile controller.
   */
  Override
  public void tileRetrieved(IlvTile tile) {
    tiles.removeElement(tile);
  }

  /**
   * Called by a tile controller each time that a tile is about to be loaded.
   * 
   * @param tile
   *          The tile that is about to be loaded.
   */
  Override
  public void tileAboutToLoad(IlvTile tile) {
    int toRemove = tiles.size() - cacheSize;
    if (toRemove <= 0)
      return;
    for (int i = toRemove; i > 0; i--) {
      IlvTile current = (IlvTile) tiles.elementAt(0);
      tiles.removeElementAt(0);
      releaseTile(current);
    }

  }

  /**
   * Removes the tile of the specified controller from the cache's internal
   * structures.
   */
  Override
  public void controllerDisposed(IlvTileController controller) {
    int i = 0;
    while (i < tiles.size()) {
      IlvTile tile = (IlvTile) tiles.elementAt(i);
      if (tile.getController() == controller)
        tiles.removeElementAt(i);
      else
        i++;
    }
  }

  /**
   * Returns the cache size.
   */
  public final int getCacheSize() {
    return cacheSize;
  }

  /**
   * Sets the cache size.
   */
  public void setCacheSize(int size) {
    cacheSize = size;
  }

}