/*******************************************************************************
 * Copyright (c) 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 v0.5 
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v05.html
 * 
 * Contributors:
 *     IBM Corp. - Rational Software - initial implementation
 ******************************************************************************/
/*
 * Created on Jul 11, 2003
 */
package org.eclipse.cdt.internal.core.search.matching;

import java.io.IOException;

import org.eclipse.cdt.core.parser.ISourceElementCallbackDelegate;
import org.eclipse.cdt.core.parser.ast.IASTEnumerationSpecifier;
import org.eclipse.cdt.core.parser.ast.IASTEnumerator;
import org.eclipse.cdt.core.parser.ast.IASTField;
import org.eclipse.cdt.core.parser.ast.IASTOffsetableNamedElement;
import org.eclipse.cdt.core.parser.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTQualifiedNameElement;
import org.eclipse.cdt.core.parser.ast.IASTVariable;
import org.eclipse.cdt.core.search.ICSearchScope;
import org.eclipse.cdt.internal.core.CharOperation;
import org.eclipse.cdt.internal.core.index.IEntryResult;
import org.eclipse.cdt.internal.core.index.impl.IndexInput;
import org.eclipse.cdt.internal.core.index.impl.IndexedFile;
import org.eclipse.cdt.internal.core.search.IIndexSearchRequestor;
import org.eclipse.cdt.internal.core.search.indexing.AbstractIndexer;


/**
 * @author aniefer
 *
 * To change the template for this generated type comment go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
public class FieldDeclarationPattern extends CSearchPattern {

	/**
	 * @param name
	 * @param cs
	 * @param matchMode
	 * @param limitTo
	 * @param caseSensitive
	 */
	public FieldDeclarationPattern(char[] name, char[][] qual, int matchMode, SearchFor sfor, LimitTo limitTo, boolean caseSensitive) {
		super( matchMode, caseSensitive, limitTo );
		qualifications = qual;
		searchFor = sfor;
		simpleName = name;
	}


	public int matchLevel(ISourceElementCallbackDelegate node, LimitTo limit ) {
		if( node instanceof IASTField ){
			if( searchFor != FIELD || !canAccept( limit ) )
				return IMPOSSIBLE_MATCH;
		} else if ( node instanceof IASTVariable ){
			if( searchFor != VAR || !canAccept( limit ) )
				return IMPOSSIBLE_MATCH;			
		} else if ( node instanceof IASTEnumerator ){
			if( searchFor != FIELD || !canAccept( limit ) )
				return IMPOSSIBLE_MATCH;
		} else if( node instanceof IASTParameterDeclaration ){
			if( searchFor != VAR || !canAccept( limit ) )
				return IMPOSSIBLE_MATCH;
		} else return IMPOSSIBLE_MATCH;
		
		String nodeName = ((IASTOffsetableNamedElement)node).getName();
		
		//check name, if simpleName == null, its treated the same as "*"	
		if( simpleName != null && !matchesName( simpleName, nodeName.toCharArray() ) ){
			return IMPOSSIBLE_MATCH;
		}
		
		//check containing scopes
		//create char[][] out of full name, 
		String [] fullName = null;
		
		if( node instanceof IASTEnumerator ){
			//Enumerators don't derive from IASTQualifiedElement, so make the fullName
			//from the enumerations name. 
			// 7.2 - 10 : each enumerator declared by an enum-specifier is declared in the
			//scope that immediately contains the enum-specifier. 
			IASTEnumerationSpecifier enumeration = ((IASTEnumerator)node).getOwnerEnumerationSpecifier();
			fullName = enumeration.getFullyQualifiedName();
			
			String[] enumeratorFullName = new String[ fullName.length ];

			System.arraycopy( fullName, 0, enumeratorFullName, 0, fullName.length);
			enumeratorFullName[ fullName.length - 1 ] = nodeName;
			
			fullName = enumeratorFullName;
		} else if( node instanceof IASTQualifiedNameElement ){
			fullName = ((IASTQualifiedNameElement) node).getFullyQualifiedName(); 
		} 
		
		if( fullName != null ){
			char [][] qualName = new char [ fullName.length - 1 ][];
			for( int i = 0; i < fullName.length - 1; i++ ){
				qualName[i] = fullName[i].toCharArray();
			}
			//check containing scopes
			if( !matchQualifications( qualifications, qualName ) ){
				return IMPOSSIBLE_MATCH;
			}
		}
		
		return ACCURATE_MATCH;
	}
	
	public char[] indexEntryPrefix() {
		if( searchFor == FIELD ){
			return AbstractIndexer.bestFieldPrefix( _limitTo, simpleName, qualifications, _matchMode, _caseSensitive );
		} else if( searchFor == VAR ) {
			return AbstractIndexer.bestVariablePrefix(
							_limitTo,
							simpleName, qualifications,
							_matchMode, _caseSensitive
			);
		}
		return null;		
	}
	
	protected void resetIndexInfo(){
		decodedSimpleName = null;
		decodedQualifications = null;
	}
	
	protected void decodeIndexEntry(IEntryResult entryResult) {
		char[] word = entryResult.getWord();
		int size = word.length;
		int firstSlash = 0;
		int slash = 0;
		
		if( searchFor == FIELD ){
			firstSlash = CharOperation.indexOf( SEPARATOR, word, 0 );
			slash = CharOperation.indexOf(SEPARATOR, word, firstSlash + 1);
		} else if( searchFor == VAR ) {
			int realStart = CharOperation.indexOf( SEPARATOR, word, 0 );
			firstSlash = CharOperation.indexOf( SEPARATOR, word, realStart + 1);
			slash = CharOperation.indexOf(SEPARATOR, word, firstSlash + 1);
		}
				
		this.decodedSimpleName = CharOperation.subarray(word, firstSlash + 1, slash);
		
		if( slash != -1 && slash+1 < size ){
			char [][] temp = CharOperation.splitOn('/', CharOperation.subarray(word, slash+1, size));
			this.decodedQualifications = new char [ temp.length ][];
			for( int i = 0; i < temp.length; i++ ){
				this.decodedQualifications[ i ] = temp[ temp.length - i - 1 ];
			}
		}
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.cdt.internal.core.search.matching.CSearchPattern#feedIndexRequestor(org.eclipse.cdt.internal.core.search.IIndexSearchRequestor, int, int[], org.eclipse.cdt.internal.core.index.impl.IndexInput, org.eclipse.cdt.core.search.ICSearchScope)
	 */
	public void feedIndexRequestor(IIndexSearchRequestor requestor, int detailLevel, int[] references, IndexInput input, ICSearchScope scope) throws IOException {
		for (int i = 0, max = references.length; i < max; i++) {
			IndexedFile file = input.getIndexedFile(references[i]);
			String path;
			if (file != null && scope.encloses(path =file.getPath())) {
				requestor.acceptFieldDeclaration(path, decodedSimpleName,decodedQualifications);
			}
		}	
	}

	protected boolean matchIndexEntry() {
		/* check simple name matches */
		if (simpleName != null){
			if( ! matchesName( simpleName, decodedSimpleName ) ){
				return false; 
			}
		}
		
		if( !matchQualifications( qualifications, decodedQualifications ) ){
			return false;
		}
		
		return true;
	}
	
	private char [][] qualifications;
	private char [][] decodedQualifications;
	private char []   simpleName;
	private char []   decodedSimpleName;
	private char      decodedType;

	private SearchFor searchFor;
}
