/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package net.sourceforge.phpdt.internal.core.builder;

import net.sourceforge.phpdt.internal.compiler.env.NameEnvironmentAnswer;
import net.sourceforge.phpdt.internal.core.util.SimpleLookupTable;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;

class ClasspathDirectory extends ClasspathLocation {

	IContainer binaryFolder; // includes .class files for a single directory

	boolean isOutputFolder;

	String binaryLocation;

	SimpleLookupTable directoryCache;

	String[] missingPackageHolder = new String[1];

	ClasspathDirectory(IContainer binaryFolder, boolean isOutputFolder) {
		this.binaryFolder = binaryFolder;
		this.isOutputFolder = isOutputFolder;
		// IPath location = binaryFolder.getLocation();
		// this.binaryLocation = location != null ?
		// location.addTrailingSeparator().toString() : ""; //$NON-NLS-1$
		this.binaryLocation = "";
		this.directoryCache = new SimpleLookupTable(5);
	}

	public void cleanup() {
		this.directoryCache = null;
	}

	String[] directoryList(String qualifiedPackageName) {
		String[] dirList = (String[]) directoryCache.get(qualifiedPackageName);
		if (dirList == missingPackageHolder)
			return null; // package exists in another classpath directory or
							// jar
		if (dirList != null)
			return dirList;

		try {
			IResource container = binaryFolder.findMember(qualifiedPackageName); // this
																					// is a
																					// case-sensitive
																					// check
			if (container instanceof IContainer) {
				IResource[] members = ((IContainer) container).members();
				dirList = new String[members.length];
				int index = 0;
				for (int i = 0, l = members.length; i < l; i++) {
					IResource m = members[i];
					// if (m.getType() == IResource.FILE &&
					// ProjectPrefUtil.isClassFileName(m.getName()))
					// // add exclusion pattern check here if we want to hide
					// .class files
					// dirList[index++] = m.getName();
				}
				if (index < dirList.length)
					System.arraycopy(dirList, 0, dirList = new String[index],
							0, index);
				directoryCache.put(qualifiedPackageName, dirList);
				return dirList;
			}
		} catch (CoreException ignored) {
		}
		directoryCache.put(qualifiedPackageName, missingPackageHolder);
		return null;
	}

	boolean doesFileExist(String fileName, String qualifiedPackageName,
			String qualifiedFullName) {
		String[] dirList = directoryList(qualifiedPackageName);
		if (dirList == null)
			return false; // most common case

		for (int i = dirList.length; --i >= 0;)
			if (fileName.equals(dirList[i]))
				return true;
		return false;
	}

	public boolean equals(Object o) {
		if (this == o)
			return true;
		if (!(o instanceof ClasspathDirectory))
			return false;

		return binaryFolder.equals(((ClasspathDirectory) o).binaryFolder);
	}

	public NameEnvironmentAnswer findClass(String binaryFileName,
			String qualifiedPackageName, String qualifiedBinaryFileName) {
		if (!doesFileExist(binaryFileName, qualifiedPackageName,
				qualifiedBinaryFileName))
			return null; // most common case

		// try {
		// ClassFileReader reader = ClassFileReader.read(binaryLocation +
		// qualifiedBinaryFileName);
		// if (reader != null) return new NameEnvironmentAnswer(reader);
		// } catch (Exception e) {} // treat as if class file is missing
		return null;
	}

	public IPath getProjectRelativePath() {
		return binaryFolder.getProjectRelativePath();
	}

	public boolean isOutputFolder() {
		return isOutputFolder;
	}

	public boolean isPackage(String qualifiedPackageName) {
		return directoryList(qualifiedPackageName) != null;
	}

	public void reset() {
		this.directoryCache = new SimpleLookupTable(5);
	}

	public String toString() {
		return "Binary classpath directory " + binaryFolder.getFullPath().toString(); //$NON-NLS-1$
	}
}
