/*******************************************************************************
 * 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.internal.core.search.matching;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.IAnnotatable;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ASTVisitor;
import org.eclipse.jdt.internal.compiler.ast.*;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.util.HashtableOfIntValues;
import org.eclipse.jdt.internal.core.search.matching.MatchLocator.WrappedCoreException;

/**
 * Specific visitor of field or method declaration which can identify and store
 * the local and  other elements of one or several matching nodes.
 * <p>
 * This visitor can also peek up local or anonymous type declaration and restart
 * a new {@link MatchLocator} traverse on this type.
 * </p>
 */
class MemberDeclarationVisitor extends ASTVisitor {
	// Matches information
	private final MatchLocator locator;
	private final IJavaElement enclosingElement;
	private final MatchingNodeSet nodeSet;
	private final ASTNode[] matchingNodes;
	private final ASTNode matchingNode;

	// Local type storage
	HashtableOfIntValues occurrencesCounts = new HashtableOfIntValues(); // key = class name (char[]), value = occurrenceCount (int)
	int nodesCount = 0;

	// Local and other elements storage
	private Annotation annotation;
	private LocalDeclaration localDeclaration;
	IJavaElement localElement;
	IJavaElement[] localElements, otherElements;
	IJavaElement[][] allOtherElements;
	int ptr = -1;
	int[] ptrs;

public MemberDeclarationVisitor(IJavaElement element, ASTNode[] nodes, MatchingNodeSet set, MatchLocator locator) {
	this.enclosingElement = element;
	this.nodeSet = set;
	this.locator = locator;
	if (nodes == null) {
		this.matchingNode = null;
		this.matchingNodes = null;
	} else {
		this.nodesCount = nodes.length;
		if (nodes.length == 1) {
			this.matchingNode = nodes[0];
			this.matchingNodes = null;
		} else {
			this.matchingNode = null;
			this.matchingNodes = nodes;
			this.localElements = new IJavaElement[this.nodesCount];
			this.ptrs = new int[this.nodesCount];
			this.allOtherElements = new IJavaElement[this.nodesCount][];
		}
	}
}
public void endVisit(Argument argument, BlockScope scope) {
    this.localDeclaration = null;
}
public void endVisit(LocalDeclaration declaration, BlockScope scope) {
    this.localDeclaration = null;
}
public void endVisit(MarkerAnnotation markerAnnotation, BlockScope unused) {
	this.annotation = null;
}
public void endVisit(NormalAnnotation normalAnnotation, BlockScope unused) {
	this.annotation = null;
}
public void endVisit(SingleMemberAnnotation singleMemberAnnotation, BlockScope unused) {
	this.annotation = null;
}
IJavaElement getLocalElement(int idx) {
	if (this.nodesCount == 1) {
		return this.localElement;
	}
	if (this.localElements != null) {
		return this.localElements[idx];
	}
	return null;
}
IJavaElement[] getOtherElements(int idx) {
	if (this.nodesCount == 1) {
		if (this.otherElements != null) {
			int length = this.otherElements.length;
			if (this.ptr < (length-1)) {
				System.arraycopy(this.otherElements, 0, this.otherElements = new IJavaElement[this.ptr+1], 0, this.ptr+1);
			}
		}
		return this.otherElements;
	}
	IJavaElement[] elements = this.allOtherElements == null ? null : this.allOtherElements[idx];
	if (elements != null) {
		int length = elements.length;
		if (this.ptrs[idx] < (length-1)) {
			System.arraycopy(elements, 0, elements = this.allOtherElements[idx] = new IJavaElement[this.ptrs[idx]+1], 0, this.ptrs[idx]+1);
		}
	}
	return elements;
}
private int matchNode(ASTNode reference) {
	if (this.matchingNode != null) {
		if (this.matchingNode == reference) return 0;
	} else {
	    int length = this.matchingNodes.length;
		for (int i=0; i<length; i++) {
			if (this.matchingNodes[i] == reference)  { // == is intentional
				return i;
			}
		}
	}
	return -1;
}
/*
 * Store the handle for the reference of the given index (e.g. peek in #matchingNodes
 * or #matchingNode).
 * Note that for performance reason, matching node and associated handles are
 * not stored in array when there's only one reference to identify.
 */
private void storeHandle(int idx) {
	if (this.localDeclaration == null) return;
	IJavaElement handle = this.locator.createHandle(this.localDeclaration, this.enclosingElement);
    if (this.nodesCount == 1) {
    	if (this.localElement == null) {
    		if (this.annotation == null) {
		    	this.localElement =  handle;
    		} else {
		    	IJavaElement annotHandle = this.locator.createHandle(this.annotation, (IAnnotatable) handle);
		    	if (annotHandle == null) {
			    	annotHandle = this.locator.createHandle(this.annotation, (IAnnotatable) this.enclosingElement);
		    	}
		    	this.localElement = annotHandle == null ? handle : annotHandle;
    		}
    	} else {
	    	if (++this.ptr == 0) {
	    		this.otherElements = new IJavaElement[10];
	    	} else {
	            int length = this.otherElements.length;
	            if (this.ptr == length) {
	            	System.arraycopy(this.otherElements, 0, this.otherElements = new IJavaElement[length+10], 0, length);
	            }
            }
    		if (this.annotation == null) {
		    	this.otherElements[this.ptr] = handle;
    		} else {
		    	IJavaElement annotHandle = this.locator.createHandle(this.annotation, (IAnnotatable) handle);
		    	if (annotHandle == null) {
			    	annotHandle = this.locator.createHandle(this.annotation, (IAnnotatable) this.enclosingElement);
		    	}
		    	this.otherElements[this.ptr] = annotHandle == null ? handle : annotHandle;
    		}
    	}
    } else {
    	if (this.localElements[idx] == null) {
	    	if (this.annotation == null) {
		    	this.localElements[idx] =  handle;
    		} else {
		    	IJavaElement annotHandle = this.locator.createHandle(this.annotation, (IAnnotatable) handle);
		    	if (annotHandle == null) {
			    	annotHandle = this.locator.createHandle(this.annotation, (IAnnotatable) this.enclosingElement);
		    	}
		    	this.localElements[idx] = annotHandle == null ? handle : annotHandle;
    		}
			this.ptrs[idx] = -1;
	    } else {
	        int oPtr = ++this.ptrs[idx];
	    	if (oPtr== 0) {
    			this.allOtherElements[idx] = new IJavaElement[10];
    		} else {
            	int length = this.allOtherElements[idx].length;
	            if (oPtr == length) {
	            	System.arraycopy(this.allOtherElements[idx], 0, this.allOtherElements[idx] = new IJavaElement[length+10], 0, length);
        	    }
	        }
	    	if (this.annotation == null) {
	 		   	this.allOtherElements[idx][oPtr] = handle;
    		} else {
		    	IJavaElement annotHandle = this.locator.createHandle(this.annotation, (IAnnotatable) handle);
		    	if (annotHandle == null) {
			    	annotHandle = this.locator.createHandle(this.annotation, (IAnnotatable) this.enclosingElement);
		    	}
	 		   	this.allOtherElements[idx][oPtr] = annotHandle == null ? handle : annotHandle;
    		}
    	}
    }
}
public boolean visit(Argument argument, BlockScope scope) {
    this.localDeclaration = argument;
    return true;
}
public boolean visit(LocalDeclaration declaration, BlockScope scope) {
    this.localDeclaration = declaration;
    return true;
}
public boolean visit(MarkerAnnotation markerAnnotation, BlockScope unused) {
	this.annotation = markerAnnotation;
	return true;
}
public boolean visit(NormalAnnotation normalAnnotation, BlockScope unused) {
	this.annotation = normalAnnotation;
	return true;
}
public boolean visit(QualifiedNameReference nameReference, BlockScope unused) {
	if (this.nodesCount > 0){
		int idx = matchNode(nameReference);
		if (idx >= 0) {
			storeHandle(idx);
		}
	}
	return false;
}
public boolean visit(QualifiedTypeReference typeReference, BlockScope unused) {
	if (this.nodesCount > 0){
		int idx = matchNode(typeReference);
		if (idx >= 0) {
			storeHandle(idx);
		}
	}
	return false;
}
public boolean visit(SingleMemberAnnotation singleMemberAnnotation, BlockScope unused) {
	this.annotation = singleMemberAnnotation;
	return true;
}
public boolean visit(SingleNameReference nameReference, BlockScope unused) {
	if (this.nodesCount > 0){
		int idx = matchNode(nameReference);
		if (idx >= 0) {
			storeHandle(idx);
		}
	}
	return false;
}
public boolean visit(SingleTypeReference typeReference, BlockScope unused) {
	if (this.nodesCount > 0){
		int idx = matchNode(typeReference);
		if (idx >= 0) {
			storeHandle(idx);
		}
	}
	return false;
}
public boolean visit(TypeDeclaration typeDeclaration, BlockScope unused) {
	try {
		char[] simpleName;
		if ((typeDeclaration.bits & ASTNode.IsAnonymousType) != 0) {
			simpleName = CharOperation.NO_CHAR;
		} else {
			simpleName = typeDeclaration.name;
		}
		int occurrenceCount = this.occurrencesCounts.get(simpleName);
		if (occurrenceCount == HashtableOfIntValues.NO_VALUE) {
			occurrenceCount = 1;
		} else {
			occurrenceCount = occurrenceCount + 1;
		}
		this.occurrencesCounts.put(simpleName, occurrenceCount);
		if ((typeDeclaration.bits & ASTNode.IsAnonymousType) != 0) {
			this.locator.reportMatching(typeDeclaration, this.enclosingElement, -1, this.nodeSet, occurrenceCount);
		} else {
			Integer level = (Integer) this.nodeSet.matchingNodes.removeKey(typeDeclaration);
			this.locator.reportMatching(typeDeclaration, this.enclosingElement, level != null ? level.intValue() : -1, this.nodeSet, occurrenceCount);
		}
		return false; // don't visit members as this was done during reportMatching(...)
	} catch (CoreException e) {
		throw new WrappedCoreException(e);
	}
}
}
