/*******************************************************************************
 * Copyright (c) 2001, 2006 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.jem.internal.proxy.initParser;
/*
 *  $RCSfile: Constructor.java,v $
 *  $Revision: 1.6 $  $Date: 2006/05/17 20:13:05 $ 
 */


import java.util.*;

import org.eclipse.jem.internal.proxy.common.AmbiguousMethodException;
import org.eclipse.jem.internal.proxy.common.MethodHelper;
/**
 * Insert the type's description here.
 * Creation date: (11/01/00 8:52:36 PM)
 * @author: Administrator
 */
public class Constructor extends Expression {
	public boolean argsOpened = false;
	public boolean argsClosed = false;
	public boolean trailingPeriod = false;
	public ArrayList arguments = new ArrayList(2);
	public Static type;
	protected boolean fIsComplete;
	public boolean insideArgsOpenedParen = false;
	public boolean insideArgsClosedParen = false;
	public boolean isString = false;
	public java.lang.reflect.Constructor ctor;
/**
 * Constructor constructor comment.
 */
public Constructor(ClassLoader aClassLoader) {
	super();
	fClassLoader = aClassLoader;
}

public boolean isComplete(){
	return fIsComplete;
}

/**
 * Invoke the construtor
 */
public Object evaluate() throws Exception {

	if ( type.isArray() ) {
		// For arrays we get the array that is actually held inside the static
		// To instantiate the array it is possible that the static knows the array size, e.g. new int[2]
		// or else it must be given this from the number of arguments we have, e.g. new int[] { 2 , 3 }
		if ( arguments.size() > 0 ) {
			type.setArrayArguments(arguments);
		}
		Object result = type.evaluate();
		// Deal with array initialization arguments
		return result;
	} else {
		// For non arrays we find the method and invoke it on the type
		cacheCtor();
		// Get the array of arguments
		Object[] args = new Object[arguments.size()];
		Iterator itr = arguments.iterator();
		for (int i = 0; i < arguments.size() ; i++){
			Expression anExpression = (Expression)itr.next();
			args[i] = anExpression.evaluate();
		}
	
		try {
			return ctor.newInstance(args);	
		} catch (Exception e) {
			// If we got this far, then we have a valid parse, so anything is an evaluation exception.
			throw new EvaluationException(e);
		}
	}
}
/** A constructor can only return the class of its type
 */
public Class getTypeClass() throws Exception {
	if ( type.isArray() ) {
		// For arrays we get the array that is actually held inside the static
		// To instantiate the array it is possible that the static knows the array size, e.g. new int[2]
		// or else it must be given this from the number of arguments we have, e.g. new int[] { 2 , 3 }
		if ( arguments.size() > 0 ) {
			type.setArrayArguments(arguments);
		}
	}
	return type.getTypeClass();
}

protected String getTypeClassName() {
	return type.getTypeClassName();
}

private void cacheCtor() throws Exception {
	
	if (ctor == null) {
		Class[] argTypes = new Class[arguments.size()];
		Iterator itr = arguments.iterator();
		for (int i=0; i<argTypes.length; i++)
			argTypes[i] = getEvaluationTypeClass((Expression) itr.next());
			
		try {
			ctor = MethodHelper.findCompatibleConstructor(getEvaluationTypeClass(this), argTypes);
		} catch (NoSuchMethodException e) {
			throw new EvaluationException(e);
		} catch (AmbiguousMethodException e) {
			throw new EvaluationException(e);
		} catch (IllegalAccessException e) {
			throw new EvaluationException(e);
		}
	}
}
protected boolean isDelimiterOpened(char token){
	return type.isArray() ? token == DelimiterOpenElipse : token == DelimiterOpenParen;	
}
protected boolean isDelimiterClosed(char token){
	return type.isArray() ? token == DelimiterCloseElipse : token == DelimiterCloseParen;
}
/**
 * push method comment.
 */
public Expression push(char[] token, char tokenDelimiter) {

	// If we are closed and we receive a . with no token then remember this
	if ( argsClosed && !trailingPeriod && tokenDelimiter == DelimiterPeriod && token.length == 0 ) {
		trailingPeriod = true;
		return this;
	}
	// If we have been closed with a . and we receive a . then we are a field
	if ( trailingPeriod && tokenDelimiter == DelimiterPeriod ) {
		return new Field(this,token,fClassLoader);
	}
	// If we have been closed with a . and we receive a ( we are a message
	if ( trailingPeriod && tokenDelimiter == DelimiterOpenParen ) {
		return new Message(this,token,fClassLoader);
	}
	
	// Lazy initialize the type if required
	if ( type == null ) {
		switch ( tokenDelimiter ) {
			case DelimiterPeriod: {
				type = new Static(token,tokenDelimiter,fClassLoader);
				type.setClassLoader(fClassLoader);
				return this;
			}
			case DelimiterOpenParen: {
				type = new Static(token,tokenDelimiter,fClassLoader);
				type.setClassLoader(fClassLoader);
				argsOpened = true;
				return this;
			} 
			case DelimiterOpenSquareBrace: { 
//				throw new CannotProcessArrayTypesException();
				// Array dimenions are created as staements in the arrayDimensions
				// This is for expressions like new String[] or new String[3], where the Statement represents the 3, i.e.
				// the code that declares the size of the array
				type = new Static(token,tokenDelimiter,fClassLoader,true);
				return this;
			}
			// If we get a { and our static is an array then this is the array initialization parameters
			case DelimiterOpenElipse: { 
				if ( type != null && type.isArray() ) {
					argsOpened = true;
				}
			}
			default: {
				return null;
			}
		}
	}
	
	// If we have a static that is an array then it consumes token until it is complete
	if ( type != null && type.isArray() ) {
		// The type consumes token as long as it is still in the array declaration section
		if ( type.isProcessingArrayDimension || tokenDelimiter == DelimiterOpenSquareBrace ) {
			type.push(token,tokenDelimiter);
			return this;
		}
	}
		
	// If the type is incomplete and the token is a . ( for another class ) or a [ for an array then push it onto the type
	if (!type.isArray() && type.getTypeClass() == null && (tokenDelimiter == DelimiterPeriod || tokenDelimiter == DelimiterOpenSquareBrace)) {
		type.push(token , tokenDelimiter);
		return this;
	}
	// If the type is incomplete and the token is a ( then push it onto the type and open the parens
	if (!type.isArray()){
		if (type.getTypeClass() == null && !argsOpened && isDelimiterOpened(tokenDelimiter)) {
			argsOpened = true;
			insideArgsOpenedParen = true;
			type.push(token , DelimiterSpace );
			return this;
		}
	} else { 
		if ( !argsOpened && isDelimiterOpened(tokenDelimiter)) {
			argsOpened = true;
			insideArgsOpenedParen = true;
			return this;			
		}
	}
	
	// If the args are already closed and we get another close expression, then just return ourselves
	// This occurs in the case of nested array arguments within constructors
	if ( argsClosed && (tokenDelimiter == DelimiterCloseParen)){
		fIsComplete = true;
		return this;
	}
	
	// If the arguments are closed and we receive a { then this is an inner class declaration, e.g.
	// new javax.swing.table.DefaultTableModel(){}
	// This can't be processed by us so we need to throw an exception
	if (argsClosed && tokenDelimiter == DelimiterOpenElipse ) {
		throw new CannotProcessInnerClassesException();
	}

	// If the args are opened and a token was supplied then it must be an argument
	if (argsOpened){
		// If we already have an incomplete argument then this may be a constructor, a static reference, etc...
		// and we should forward the request to the argument
		Expression openArgument = null;
		if ( arguments.size() > 0 ){
			openArgument = (Expression)arguments.get(arguments.size()-1);
			if ( !openArgument.isComplete() ) {
				openArgument.push(token,tokenDelimiter);
				// If the argument is complete and we received a ) then the constructor is complete
				// or if we receive a } and are an array we are complete
				if ( openArgument.isComplete() && isDelimiterClosed(tokenDelimiter) ){
					argsClosed = true;
				}
				return this;
			} 
		}
			
		Expression newArgument = null;
		// If we are not already inside the open arg and we get another open paren this is probably a cast
		// or some kind of statement, and OperMinus is probably the start of a number
		// If the args are not already open we must be opened with either a { or a ( depending on whether we are an array or not
		// however if the args are opened already and we receive a ( then this is the start of a new statement
//		if ((!insideArgsOpenedParen && isDelimiterOpened(tokenDelimiter)) || tokenDelimiter == DelimiterOpenParen){
		if (tokenDelimiter == DelimiterOpenElipse || tokenDelimiter == DelimiterOpenParen){
			insideArgsOpenedParen = true;
			newArgument = new Statement(fClassLoader).push(token,tokenDelimiter);
			if ( newArgument instanceof ArrayArguments ) {
				((ArrayArguments)newArgument).setType(type);
			}
			newArgument = new MessageArgument(newArgument);
			arguments.add(newArgument);

		}
		
		// Start of a possible string or number or character
		if ( ( token.length > 0 || tokenDelimiter == DelimiterQuote || tokenDelimiter == DelimiterSingleQuote) || tokenDelimiter == OperMinus ){
			newArgument = new Statement(fClassLoader).push(token,tokenDelimiter);
			newArgument = new MessageArgument(newArgument);
			arguments.add(newArgument);
		}
		// If the token after the argument is a ) then the message is being closed
		if ( !insideArgsOpenedParen || argumentsAreComplete() && isDelimiterClosed(tokenDelimiter) ) {
			argsClosed = true;
			return this;
		}
		if ( insideArgsOpenedParen && isDelimiterClosed(tokenDelimiter) ) {
			insideArgsClosedParen  = true;
			return this;
		}

		// If the token after the argument is a , or a ' ' then the argument is being closed
		if ( tokenDelimiter == DelimiterComma || tokenDelimiter == DelimiterSpace ) {
			// If our arguments are closed then we must be complete.  We need to signal the fact we are closed
			// otherwise we will not be processed correctly if we are part of a stack 
			if ( argsClosed ) {
				fIsComplete = true;
			}			
			return this;
		}
		
		// If we receive a close bracket then we are closed as long as the last argument is closed
		if(argsOpened &&  isDelimiterClosed(tokenDelimiter)){
			// No parms - we are a closed constructor
			if(arguments.size() == 0){
				argsClosed = true;
				return this;
			} 
		}
		
		// If our last argument is closed and receive a ) and we have no new argument then we are closed
		if (tokenDelimiter == DelimiterCloseParen && newArgument == null){
			Expression lastArgument = (Expression)arguments.get(arguments.size()-1);
			if ( lastArgument.isComplete() ) {
				argsClosed = true;
				return this;
			}
		}			
				
		// Otherwise the new argument is stil processing.  Return it
		return newArgument;
	}

	return this;
}
protected boolean argumentsAreComplete(){
	if ( arguments.size() == 0) return true;
	return ((Expression)arguments.get(arguments.size()-1)).isComplete();
}
public String toString(){

	java.io.StringWriter writer = new java.io.StringWriter();
	writer.write("Constructor \""); //$NON-NLS-1$
	if ( type != null ) {
		writer.write(type.typeWriter.toString());
	} else {
		writer.write("UNTYPED"); //$NON-NLS-1$
	}
	for (int i = 0; i < arguments.size() ; i++){
		writer.write(" Arg("); //$NON-NLS-1$
		writer.write("" + (i+1)); //$NON-NLS-1$
		writer.write(") = "); //$NON-NLS-1$
		writer.write(arguments.get(i).toString());
	}
	
	return writer.toString();

}

/**
 * This is never primitive
 */
public boolean isPrimitive() {
	return false;
}
}
