package tim.prune.function.cache;

import java.io.File;

import tim.prune.fileutils.FileList;


/**
 * Class to hold information about a single tile set
 * within the overall Tile Cache.
 */
public class TileSet
{
	/** Summary row info for whole tileset */
	private final RowInfo _rowInfo = new RowInfo();
	/** Path relative to mapcache root */
	private final String _path;
	/** Comma-separated list of configs using this tileset */
	private final String _usedBy;


	/**
	 * Constructor
	 * @param inDir directory of tileset
	 * @param inPath String describing relative path from cache root
	 * @param inUsedBy String describing which configs use this Tileset
	 */
	public TileSet(File inDir, String inPath, String inUsedBy)
	{
		_path = inPath;
		_usedBy = inUsedBy;
		// Go through zoom directories and construct row info objects
		if (inDir != null && inDir.exists() && inDir.isDirectory() && inDir.canRead())
		{
			for (File subdir : FileList.filesIn(inDir))
			{
				if (subdir != null && subdir.exists() && subdir.isDirectory()
					&& subdir.canRead() && isNumeric(subdir.getName()))
				{
					RowInfo row = makeRowInfo(subdir);
					_rowInfo.addRow(row);
				}
			}
		}
	}

	/**
	 * Check if a directory name is numeric
	 * @param inName name of directory
	 * @return true if it only contains characters 0-9
	 */
	public static boolean isNumeric(String inName)
	{
		if (inName == null || inName.equals("")) {
			return false;
		}
		for (int i=0; i<inName.length(); i++)
		{
			char a = inName.charAt(i);
			if (a < '0' || a > '9') {
				return false;
			}
		}
		return true;
	}

	/**
	 * Check if a filename is numeric up until the first dot
	 * This appears to be much faster than scanning for a . with indexOf, then
	 * chopping to make a new String, and then calling isNumeric to scan through again
	 * @param inName name of file
	 * @return true if it only contains characters 0-9 before the first dot
	 */
	public static boolean isNumericUntilDot(String inName)
	{
		if (inName == null || inName.equals("") || inName.charAt(0) == '.') {
			return false;
		}
		for (int i=0; i<inName.length(); i++)
		{
			char c = inName.charAt(i);
			if (c == '.') {
				return true; // found the dot, so stop
			}
			if (c < '0' || c > '9') {
				return false; // not numeric
			}
		}
		// Didn't find a dot, so can't be a valid name
		return false;
	}

	/**
	 * Make a RowInfo object from the given directory
	 * @param inDir directory for a single zoom level
	 * @return RowInfo object describing files and size
	 */
	private static RowInfo makeRowInfo(File inDir)
	{
		RowInfo row = new RowInfo();
		for (File subdir : FileList.filesIn(inDir))
		{
			if (subdir != null && subdir.exists() && subdir.isDirectory()
				&& subdir.canRead() && isNumeric(subdir.getName()))
			{
				// Found a directory of images (finally!)
				for (File f : FileList.filesIn(subdir))
				{
					if (f != null && f.exists() && f.isFile() && f.canRead())
					{
						if (isNumericUntilDot(f.getName())) {
							row.addTile(f.length());
						}
					}
				}
			}
		}
		return row;
	}

	/**
	 * @return row info object
	 */
	public RowInfo getRowInfo() {
		return _rowInfo;
	}

	/** @return relative path to tileset */
	public String getPath() {
		return _path;
	}

	/** @return users of tileset */
	public String getUsedBy() {
		return _usedBy;
	}
}
