/*
 * Licensed Materials - Property of Rogue Wave Software, Inc. 
 * © Copyright Rogue Wave Software, Inc. 2014, 2015 
 * © 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 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;

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

/**
 * 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 tiles = new Vector();

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


}