/*******************************************************************************
 * Copyright (c) 2000, 2004 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 org.eclipse.wst.jsdt.internal.compiler.parser;

/**
 * Internal field structure for parsing recovery 
 */
import org.eclipse.wst.jsdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.wst.jsdt.internal.compiler.ast.ASTNode;
import org.eclipse.wst.jsdt.internal.compiler.ast.Block;
import org.eclipse.wst.jsdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.wst.jsdt.internal.compiler.ast.FieldDeclaration;
import org.eclipse.wst.jsdt.internal.compiler.ast.ImportReference;
import org.eclipse.wst.jsdt.internal.compiler.ast.Initializer;
import org.eclipse.wst.jsdt.internal.compiler.ast.TypeDeclaration;

public class RecoveredUnit extends RecoveredElement {

	public CompilationUnitDeclaration unitDeclaration;
	
	public RecoveredImport[] imports;
	public int importCount;
	public RecoveredType[] types;
	public int typeCount;
public RecoveredUnit(CompilationUnitDeclaration unitDeclaration, int bracketBalance, Parser parser){
	super(null, bracketBalance, parser);
	this.unitDeclaration = unitDeclaration;
}
/*
 *	Record a method declaration: should be attached to last type
 */
public RecoveredElement add(AbstractMethodDeclaration methodDeclaration, int bracketBalanceValue) {

	/* attach it to last type - if any */
	if (this.typeCount > 0){
		RecoveredType type = this.types[this.typeCount -1];
		int start = type.bodyEnd;
		int end = type.typeDeclaration.bodyEnd;
		type.bodyEnd = 0; // reset position
		type.typeDeclaration.declarationSourceEnd = 0; // reset position
		type.typeDeclaration.bodyEnd = 0;
		
		if(start < end) {
			Initializer initializer = new Initializer(new Block(0), 0);
			initializer.bodyStart = end;
			initializer.bodyEnd = end;
			initializer.declarationSourceStart = end;
			initializer.declarationSourceEnd = start;
			type.add(initializer, bracketBalanceValue);
		}
		
		return type.add(methodDeclaration, bracketBalanceValue);
	}
	return this; // ignore
}
/*
 *	Record a field declaration: should be attached to last type
 */
public RecoveredElement add(FieldDeclaration fieldDeclaration, int bracketBalanceValue) {

	/* attach it to last type - if any */
	if (this.typeCount > 0){
		RecoveredType type = this.types[this.typeCount -1];
		type.bodyEnd = 0; // reset position
		type.typeDeclaration.declarationSourceEnd = 0; // reset position
		type.typeDeclaration.bodyEnd = 0;
		return type.add(fieldDeclaration, bracketBalanceValue);
	}
	return this; // ignore
}
public RecoveredElement add(ImportReference importReference, int bracketBalanceValue) {
	if (this.imports == null) {
		this.imports = new RecoveredImport[5];
		this.importCount = 0;
	} else {
		if (this.importCount == this.imports.length) {
			System.arraycopy(
				this.imports, 
				0, 
				(this.imports = new RecoveredImport[2 * this.importCount]), 
				0, 
				this.importCount); 
		}
	}
	RecoveredImport element = new RecoveredImport(importReference, this, bracketBalanceValue);
	this.imports[this.importCount++] = element;

	/* if import not finished, then import becomes current */
	if (importReference.declarationSourceEnd == 0) return element;
	return this;		
}
public RecoveredElement add(TypeDeclaration typeDeclaration, int bracketBalanceValue) {
	
	if ((typeDeclaration.bits & ASTNode.IsAnonymousTypeMASK) != 0){
		if (this.typeCount > 0) {
			// add it to the last type
			RecoveredType lastType = this.types[this.typeCount-1];
			lastType.bodyEnd = 0; // reopen type
			lastType.typeDeclaration.bodyEnd = 0; // reopen type
			lastType.typeDeclaration.declarationSourceEnd = 0; // reopen type
			lastType.bracketBalance++; // expect one closing brace
			return lastType.add(typeDeclaration, bracketBalanceValue);
		}
	}
	if (this.types == null) {
		this.types = new RecoveredType[5];
		this.typeCount = 0;
	} else {
		if (this.typeCount == this.types.length) {
			System.arraycopy(
				this.types, 
				0, 
				(this.types = new RecoveredType[2 * this.typeCount]), 
				0, 
				this.typeCount); 
		}
	}
	RecoveredType element = new RecoveredType(typeDeclaration, this, bracketBalanceValue);
	this.types[this.typeCount++] = element;

	/* if type not finished, then type becomes current */
	if (typeDeclaration.declarationSourceEnd == 0) return element;
	return this;	
}
/* 
 * Answer the associated parsed structure
 */
public ASTNode parseTree(){
	return this.unitDeclaration;
}
/*
 * Answer the very source end of the corresponding parse node
 */
public int sourceEnd(){
	return this.unitDeclaration.sourceEnd;
}
public String toString(int tab) {
	StringBuffer result = new StringBuffer(tabString(tab));
	result.append("Recovered unit: [\n"); //$NON-NLS-1$
	this.unitDeclaration.print(tab + 1, result);
	result.append(tabString(tab + 1));
	result.append("]"); //$NON-NLS-1$
	if (this.imports != null) {
		for (int i = 0; i < this.importCount; i++) {
			result.append("\n"); //$NON-NLS-1$
			result.append(this.imports[i].toString(tab + 1));
		}
	}
	if (this.types != null) {
		for (int i = 0; i < this.typeCount; i++) {
			result.append("\n"); //$NON-NLS-1$
			result.append(this.types[i].toString(tab + 1));
		}
	}
	return result.toString();
}
public CompilationUnitDeclaration updatedCompilationUnitDeclaration(){

	/* update imports */
	if (this.importCount > 0){
		ImportReference[] importRefences = new ImportReference[this.importCount];
		for (int i = 0; i < this.importCount; i++){
			importRefences[i] = this.imports[i].updatedImportReference();
		}
		this.unitDeclaration.imports = importRefences;
	}
	/* update types */
	if (this.typeCount > 0){
		int existingCount = this.unitDeclaration.types == null ? 0 : this.unitDeclaration.types.length;
		TypeDeclaration[] typeDeclarations = new TypeDeclaration[existingCount + this.typeCount];
		if (existingCount > 0){
			System.arraycopy(this.unitDeclaration.types, 0, typeDeclarations, 0, existingCount);
		}
		// may need to update the declarationSourceEnd of the last type
		if (this.types[this.typeCount - 1].typeDeclaration.declarationSourceEnd == 0){
			this.types[this.typeCount - 1].typeDeclaration.declarationSourceEnd = this.unitDeclaration.sourceEnd;
			this.types[this.typeCount - 1].typeDeclaration.bodyEnd = this.unitDeclaration.sourceEnd;
		}
		int actualCount = existingCount;
		for (int i = 0; i < this.typeCount; i++){
			TypeDeclaration typeDecl = this.types[i].updatedTypeDeclaration();
			// filter out local types (12454)
			if ((typeDecl.bits & ASTNode.IsLocalTypeMASK) == 0){
				typeDeclarations[actualCount++] = typeDecl;
			}
		}
		if (actualCount != this.typeCount){
			System.arraycopy(
				typeDeclarations, 
				0, 
				typeDeclarations = new TypeDeclaration[existingCount+actualCount], 
				0, 
				existingCount+actualCount);
		}
		this.unitDeclaration.types = typeDeclarations;
	}
	return this.unitDeclaration;
}
public void updateParseTree(){
	this.updatedCompilationUnitDeclaration();
}
/*
 * Update the sourceEnd of the corresponding parse node
 */
public void updateSourceEndIfNecessary(int bodyStart, int bodyEnd){
	if (this.unitDeclaration.sourceEnd == 0)
		this.unitDeclaration.sourceEnd = bodyEnd;
}
}
