/*******************************************************************************
 * Copyright (c) 2000, 2009 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.core.tests.model;

import java.util.Comparator;
import java.util.List;

import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration;
import org.eclipse.jdt.core.dom.ArrayType;
import org.eclipse.jdt.core.dom.BodyDeclaration;
import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.Initializer;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.PrimitiveType;
import org.eclipse.jdt.core.dom.QualifiedName;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.SimpleType;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.core.util.CompilationUnitSorter;

import com.ibm.icu.text.Collator;

/**
 * The class <code>DefaultJavaElementComparator</code> is a standard
 * implementation of a comparator.
 * <p>
 * <ul>
 * <li>static fields, arranged alphabetically by name and access modifier
 * (public, protected, private, default)</li>
 * <li>static initializers in order of appearance</li>
 * <li>instance fields, arranged alphabetically by name and access modifier
 * (public, protected, private, default)</li>
 * <li>instance initializers in order of appearance</li>
 * <li>type declarations, arranged alphabetically by name and access modifier
 * (public, protected, private, default)</li>
 * <li>constructors, arranged by parameter order and access modifier
 * (public, protected, private, default)</li>
 * <li>methods, arranged by alphabetically by name and parameter order and
 * access modifier (public, protected, private, default)</li>
 * </p>
 */
class DefaultJavaElementComparator implements Comparator {

	private static final int STATIC_TYPE_CATEGORY = 0;
	private static final int STATIC_FIELD_CATEGORY = 1;
	private static final int STATIC_INITIALIZER_CATEGORY = 2;
	private static final int STATIC_METHOD_CATEGORY = 3;
	private static final int TYPE_CATEGORY = 4;
	private static final int FIELD_CATEGORY = 5;
	private static final int INITIALIZER_CATEGORY = 6;
	private static final int CONSTRUCTOR_CATEGORY = 7;
	private static final int METHOD_CATEGORY = 8;

	private Collator collator;

	private int[] categories;

	/**
	 * Creates an instance that sorts the various categories of body
	 * declarations in the following order:
	 * <ol>
	 * <li>static types</li>
	 * <li>static fields </li>
	 * <li>static initializers</li>
	 * <li>non-static fields</li>
	 * <li>instance initializers</li>
	 * <li>types</li>
	 * <li>static methods</li>
	 * <li>constructors</li>
	 * <li>non-static methods</li>
	 * </ol>
	 */
	public DefaultJavaElementComparator() {
		// initialize default categories
		this.categories = new int[] {
			1, // static type
			2, // static field
			3, // static initializer
			7, // static method
			6, // type
			4, // field
			5, // initializer
			8, // constructor
			9  // method
		};
		this.collator = Collator.getInstance();
	}

	/**
	 * Creates an instance that arranges the various categories of body
	 * declarations.
	 * This constructor is used to specify customized values for the different categories.
	 * They are a convinient way to distinguish AST nodes.
	 * The lower a value is, the higher the node will appear in the sorted
	 * compilation unit.
	 * <p>
	 * There are nine categories with theirs default values:
	 * <ol>
	 * <li>static types (1)</li>
	 * <li>static fields (2)</li>
	 * <li>static initializers (3)</li>
	 * <li>fields (4) </li>
	 * <li>initializers (5)</li>
	 * <li>types (6)</li>
	 * <li>static methods (7)</li>
	 * <li>constructors (8)</li>
	 * <li>methods (9)</li>
	 * </ol>
	 * </p>
	 *
	 * @param staticTypeCategory the given value for the static type category
	 * @param staticFieldCategory the given value for the static field category
	 * @param staticInitializerCategory the given value for the static initializer category
	 * @param staticMethodCategory the given value for static the method category
	 * @param typeCategory the given value for the type category
	 * @param fieldCategory the given value for field category
	 * @param initializerCategory the given value for initializer category
	 * @param constructorCategory the given value for constructor category
	 * @param methodCategory the given value for method category
	 */
	public DefaultJavaElementComparator(
		int staticTypeCategory,
		int staticFieldCategory,
		int staticInitializerCategory,
		int staticMethodCategory,
		int typeCategory,
		int fieldCategory,
		int initializerCategory,
		int constructorCategory,
		int methodCategory) {
			this.categories = new int[] {
				staticTypeCategory,
				staticFieldCategory,
				staticInitializerCategory,
				staticMethodCategory,
				typeCategory,
				fieldCategory,
				initializerCategory,
				constructorCategory,
				methodCategory
			};
		this.collator = Collator.getInstance();
	}

	/**
	 * This method is used to retrieve the category for a body declaration node according to the
	 * preferences passed at the creation of the comparator.
	 *
	 * @param node the given node
	 * @return the category corresponding to the given node
	 *
	 * @since 2.1
	 */
	private int getCategory(BodyDeclaration node) {
		switch(node.getNodeType()) {
			case ASTNode.METHOD_DECLARATION :
				MethodDeclaration methodDeclaration = (MethodDeclaration) node;
				if (methodDeclaration.isConstructor()) {
					return this.categories[CONSTRUCTOR_CATEGORY];
				}
				if (Flags.isStatic(methodDeclaration.getModifiers())) {
					return this.categories[STATIC_METHOD_CATEGORY];
				}
				return this.categories[METHOD_CATEGORY];
			case ASTNode.ANNOTATION_TYPE_MEMBER_DECLARATION :
				if (Flags.isStatic(node.getModifiers())) {
					return this.categories[STATIC_METHOD_CATEGORY];
				}
				return this.categories[METHOD_CATEGORY];
			case ASTNode.FIELD_DECLARATION :
				FieldDeclaration fieldDeclaration = (FieldDeclaration) node;
				if (Flags.isStatic(fieldDeclaration.getModifiers())) {
					return this.categories[STATIC_FIELD_CATEGORY];
				}
				return this.categories[FIELD_CATEGORY];
			case ASTNode.ENUM_CONSTANT_DECLARATION :
				return this.categories[STATIC_FIELD_CATEGORY];
			case ASTNode.TYPE_DECLARATION :
			case ASTNode.ENUM_DECLARATION :
			case ASTNode.ANNOTATION_TYPE_DECLARATION :
				AbstractTypeDeclaration abstractTypeDeclaration = (AbstractTypeDeclaration) node;
				if (Flags.isStatic(abstractTypeDeclaration.getModifiers())) {
					return this.categories[STATIC_TYPE_CATEGORY];
				}
				return this.categories[TYPE_CATEGORY];
			case ASTNode.INITIALIZER :
				Initializer initializer = (Initializer) node;
				if (Flags.isStatic(initializer.getModifiers())) {
					return this.categories[STATIC_INITIALIZER_CATEGORY];
				}
				return this.categories[INITIALIZER_CATEGORY];
		}
		return 0;
	}

	/**
	 * The <code>DefaultJavaElementComparator</code> implementation of this
	 * <code>java.util.Comparator</code> method can only be used to compare
	 * instances of <code>org.eclipse.jdt.core.dom.BodyDeclaration</code>.
	 * <p>
	 * The categories of each body declaration are compared. If they are
	 * in different categories, they are ordered based on their category.
	 * Body declarations within the same category are ordered by signature
	 * string. Body declarations with the same signature string are ordered
	 * by their original relative positions.
	 * </p>
	 */
	public int compare(Object o1, Object o2) {
		if (!(o1 instanceof BodyDeclaration) && !(o2 instanceof BodyDeclaration)) {
			throw new ClassCastException();
		}
		BodyDeclaration node1 = (BodyDeclaration) o1;
		BodyDeclaration node2 = (BodyDeclaration) o2;
		int category1 = getCategory(node1);
		int category2 = getCategory(node2);

		if (category1 != category2) {
			return category1 - category2;
		}
		if (o1 == o2) {
			return 0;
		}
		String node1Signature = buildSignature(node1);
		String node2Signature = buildSignature(node2);
		if (node1Signature.length() != 0 && node2Signature.length() != 0) {
			int compare = this.collator.compare(node1Signature, node2Signature);
			if (compare != 0) {
				return compare;
			}
		}
		int sourceStart1 = ((Integer) node1.getProperty(CompilationUnitSorter.RELATIVE_ORDER)).intValue();
		int sourceStart2 = ((Integer) node2.getProperty(CompilationUnitSorter.RELATIVE_ORDER)).intValue();
		return sourceStart1 - sourceStart2;
	}

	private String buildSignature(BodyDeclaration node) {
		switch(node.getNodeType()) {
			case ASTNode.METHOD_DECLARATION :
				MethodDeclaration methodDeclaration = (MethodDeclaration) node;
				StringBuffer buffer = new StringBuffer();
				buffer.append(methodDeclaration.getName().getIdentifier());
				final List parameters = methodDeclaration.parameters();
				int length1 = parameters.size();
				for (int i = 0; i < length1; i++) {
					SingleVariableDeclaration parameter = (SingleVariableDeclaration) parameters.get(i);
					buffer.append(parameter.getName().getIdentifier());
					Type type = parameter.getType();
					buffer.append(buildSignature(type));
				}
				return String.valueOf(buffer);
			case ASTNode.ANNOTATION_TYPE_MEMBER_DECLARATION :
				AnnotationTypeMemberDeclaration annotationTypeMemberDeclaration = (AnnotationTypeMemberDeclaration) node;
				return annotationTypeMemberDeclaration.getName().getIdentifier();
			case ASTNode.FIELD_DECLARATION :
				FieldDeclaration fieldDeclaration = (FieldDeclaration) node;
				return ((VariableDeclarationFragment) fieldDeclaration.fragments().get(0)).getName().getIdentifier();
			case ASTNode.ENUM_CONSTANT_DECLARATION :
				EnumConstantDeclaration enumConstantDeclaration = (EnumConstantDeclaration) node;
				return enumConstantDeclaration.getName().getIdentifier();
			case ASTNode.INITIALIZER :
				return ((Integer) node.getProperty(CompilationUnitSorter.RELATIVE_ORDER)).toString();
			case ASTNode.TYPE_DECLARATION :
			case ASTNode.ENUM_DECLARATION :
			case ASTNode.ANNOTATION_TYPE_DECLARATION :
				AbstractTypeDeclaration abstractTypeDeclaration = (AbstractTypeDeclaration) node;
				return abstractTypeDeclaration.getName().getIdentifier();
		}
		return null;
	}

	private String buildSignature(Type type) {
		switch(type.getNodeType()) {
			case ASTNode.PRIMITIVE_TYPE :
				PrimitiveType.Code code = ((PrimitiveType) type).getPrimitiveTypeCode();
				return code.toString();
			case ASTNode.ARRAY_TYPE :
				ArrayType arrayType = (ArrayType) type;
				StringBuffer buffer = new StringBuffer();
				buffer.append(buildSignature(arrayType.getElementType()));
				int dimensions = arrayType.getDimensions();
				for (int j = 0; j < dimensions; j++) {
					buffer.append("[]"); //$NON-NLS-1$
				}
				return buffer.toString();
			case ASTNode.SIMPLE_TYPE :
				SimpleType simpleType = (SimpleType) type;
				return buildSignature(simpleType.getName());
		}
		return null; // should never happen
	}

	private String buildSignature(Name name) {
		if (name.isSimpleName()) {
			return ((SimpleName) name).getIdentifier();
		}
		QualifiedName qualifiedName = (QualifiedName) name;
		return buildSignature(qualifiedName.getQualifier()) + "." + buildSignature(qualifiedName.getName()); //$NON-NLS-1$
	}
}
