/*******************************************************************************
 * Copyright (c) 2001, 2005 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;
/*


 */


import java.io.*;
import java.lang.reflect.Array;
import java.util.*;

public class Static extends Expression {
	protected static final HashMap sPrimitiveTypes;
	
	static {
		sPrimitiveTypes = new HashMap(10);
		sPrimitiveTypes.put("byte", Byte.TYPE); //$NON-NLS-1$
		sPrimitiveTypes.put("char", Character.TYPE); //$NON-NLS-1$
		sPrimitiveTypes.put("short", Short.TYPE); //$NON-NLS-1$
		sPrimitiveTypes.put("int", Integer.TYPE); //$NON-NLS-1$
		sPrimitiveTypes.put("long", Long.TYPE); //$NON-NLS-1$
		sPrimitiveTypes.put("float", Float.TYPE);		 //$NON-NLS-1$
		sPrimitiveTypes.put("double", Double.TYPE); //$NON-NLS-1$
	}

	protected ArrayList arrayDimensions;
	protected List fArrayArguments;
	protected StringWriter typeWriter = new StringWriter();
	protected boolean completedWithPeriod = false;
	protected char[] completionToken;
	public Class type;
	protected boolean isComplete;

	public boolean isProcessingArrayDimension;
/**
 * Create an unknown expression
 */
public Static(ClassLoader aClassLoader){
	fClassLoader = aClassLoader;
}
public Static(char[] aToken,char delimiter,ClassLoader aClassLoader){
	
	fClassLoader = aClassLoader;
	try { 
		typeWriter.write(aToken);
	} catch ( IOException exc ) {};
	checkForValidType();
	if ( type == null && delimiter == DelimiterPeriod ){
		typeWriter.write(DelimiterPeriod);
	}
		
}
public Static(char[] aToken,char delimiter,ClassLoader aClassLoader,boolean isArray){
	this(aToken,delimiter,aClassLoader);
	isProcessingArrayDimension = true;
	arrayDimensions = new ArrayList(1);
	arrayDimensions.add(new Statement(aClassLoader));
}

public boolean isComplete(){
	return isComplete;
}
public boolean isArray(){
	return arrayDimensions != null;
}
/**
 * See whether or not we have a valid type
 * This uses the class loader given to us if one specified.  The reason for this
 * is that Eclipse uses a special plugin class loader and when we are running
 * in a VM inside eclipse ( e.g. for IDEVM proxy stuff ) we must have
 * reference to the plugin that is using us otherwise we can't load its classes
 */
protected void checkForValidType(){

	type = (Class) sPrimitiveTypes.get(typeWriter.toString());
	if (type == null)
		try {
			if ( fClassLoader == null ) {
				type = Class.forName(typeWriter.toString());
			} else {
				type = fClassLoader.loadClass(typeWriter.toString());
			}
		} catch ( ClassNotFoundException exc ) {
			try {
				type = Class.forName("java.lang." + typeWriter.toString()); //$NON-NLS-1$
				StringWriter writer = new StringWriter();
				writer.write(type.getName());
				typeWriter = writer;
			} catch ( ClassNotFoundException exc1 ) {}
		} catch ( NoClassDefFoundError exc ) {
			// A mismatch in some way. Found a class, probably different case. One possibility
			// is found a class, but this was really a package. So class and package with same name
			// but different case caused this to occur. [46376].
		}
	
}
/**
 * If we have any static methods return the result of evaluating them against the type
 */
public Object evaluate() {

	// If we are an array but haven't created it do so
	if ( isArray() ) {
		if ( array == null ) {
			evaluateArray();
		}
		return array;
	} else {
		if ( type != null ) { 
			return type;
		} else { 
			// If we have no type then we are some kind incomplete expression that cannot be evaluted
			throw new RuntimeException();
		}
	}
}
/**
 * The type of us is either simply the class, or if we are an array then we must create the java.lang.reflect.Array
 * using the reflective APIs
 */
protected Object array;
public Class getTypeClass() {

	if ( isArray() ) {
		if ( array == null ) {
			// Do not evaluate the array and return its class.  Instead just work out the class by our type
			// and number of dimensions
			Object result = Array.newInstance(type,getNumberOfDimensions());
			return result.getClass();
		} else { 
			return array.getClass();
		}
	} else { 
		return type;
	}
}

protected String getTypeClassName() {
	return typeWriter.toString();
}
public Class getPrimitiveTypeClass(){
	return type;
}
protected int[] getNumberOfDimensions(){
	List dimensions = new ArrayList(1);
	dimensions.add(new Integer(fArrayArguments.size()));
	((MessageArgument)fArrayArguments.get(0)).contributeArgumentNumber(dimensions);
	// The total number of arguments is a set of Integer objects in the dimensions list
	// convert this to an int[]
	int[] intDimensions = new int[dimensions.size()];
	for (int i = 0; i < dimensions.size(); i++) {
		intDimensions[i] = ((Integer)dimensions.get(i)).intValue();
	}
	return intDimensions;
}
/**
 * Evaluate the array
 */
protected void evaluateArray(){
	if ( fArrayArguments != null ) { 
		// If the array isn't declared with a size but this is supplied with argument these will be in the fArrayArguments
		// new int[] { 2 ,3 } will have the constructor arguments supplied as two message arguments with 
		if ( array == null ) {
			// The size of the array arguments is our array size, however for a multi arg array we need
			// to find the size of any nested arrays within arguments themselves, e.g. 
			// new int[][] { {2,3} , {3,4} } then we have two array arguments, each of which is a MessageArgument
			// whose statement is an ArrayArguments that has two arguments, etc...
			// To find the number of arguments we create a list that we add our number of arguments to, and then
			// pass this all the way up the arguments chain using contributeArgumentNumber(List) so that each element
			// can add to the list the number of arguments ( if any ) that they have.  
			array = Array.newInstance(type,getNumberOfDimensions());
			// Set the elements in the array to be the result of evaluating the constructor arguments
			for (int i = 0; i < fArrayArguments.size(); i++) {
				Expression expression = (Expression)fArrayArguments.get(i);
				try {	
					Object element = expression.evaluate();
					Array.set(array,i,element);
				} catch ( Exception exc ) {
					// Any evaluation exceptions should be thrown back
					throw new RuntimeException();
				}
			}
		}
	} else if ( arrayDimensions != null ) {
		// To get the class of a reflective array we must actually first create it and then ask it for its class
		// The array Dimensions are present if the array was explicitly declared with a size, e.g. new int[2][3]
		// will have to arrayDimensions that represent the expressions 2 and 3 ( as NumberLiteral instances )
		if ( array == null ) {
			// Evaluate all of the arrayDimensions.  These should be integers
			int[] dimensionSizes = new int[arrayDimensions.size()];
			for (int i = 0; i < dimensionSizes.length; i++) {
				try { 
					Integer dimensionSize = (Integer) ((Expression)arrayDimensions.get(i)).evaluate();
					dimensionSizes[i] = dimensionSize.intValue();
				} catch ( Exception exc ) {
					throw new RuntimeException();
				}
			}
			// For a multi arg array we need to create using the static method on array that takes an int[] that represents
			// the number of dimensions, e.g. for new String[2][3] we do Array.newInstance(String.class,new int[] { 2 , 3 };
			array = Array.newInstance(type,dimensionSizes);
		}
	}
}
/**
 * If the token is a period then it could either be part of the type or else a static method call
 */
public Expression push(char[] token , char delimiter ) {

	// If we don't yet have a valid type then see if we now do
	if (type == null){
		try { 
			typeWriter.write(token);
		} catch ( IOException exc ) {};
		checkForValidType();
		// If we got a valid type and a period then remember it
		if ( delimiter == DelimiterPeriod ) {
			if (type != null) {
				completedWithPeriod = true;
				return this;
			}
		}		
	}
	
	if ( arrayDimensions != null && isProcessingArrayDimension ) {
		Expression lastArrayDimension = (Expression)arrayDimensions.get(arrayDimensions.size()-1);
		lastArrayDimension.push(token,delimiter);
		if ( delimiter == DelimiterCloseSquareBrace && isProcessingArrayDimension ) {
			isProcessingArrayDimension = false;
		}
		return this;
	}
	
	if ( delimiter == DelimiterOpenSquareBrace && !isProcessingArrayDimension ) {
		if ( arrayDimensions == null ) arrayDimensions = new ArrayList(1);
		Statement statement = new Statement(fClassLoader);
		arrayDimensions.add(statement);
		isProcessingArrayDimension = true;
		return this;		
	}
	
	// If we have a type and the delimiter is a ( then it must be a message beginning
	if ( type != null ) {
		if (delimiter == DelimiterOpenParen) {
			isComplete = true;
			return new Message( this , token , fClassLoader );
		} else if (completedWithPeriod){
			isComplete = true;
			Field field = new Field(this,token,fClassLoader);
			// If our token is a ), ' ' or , then the field is completed,
			// otherwise leave it open so it will process the remaining tokens
//			if (delimiter == DelimiterCloseParen || delimiter == DelimiterSpace || delimiter == DelimiterComma) {
			if (delimiter == DelimiterCloseParen || delimiter == DelimiterComma) {
				field.isComplete = true;
			}
			return field;
		}
	}
			
	// We are still looking for a type so append a .
	if ( type == null ) {
		typeWriter.write('.');
	}
	return this;
}
public String toString(){

	StringWriter writer = new StringWriter();
	writer.write("Static "); //$NON-NLS-1$
	if ( type == null ) { 
		writer.write("(Incomplete) {"); //$NON-NLS-1$
	} else {
		writer.write("(Complete) {"); //$NON-NLS-1$
	}
	writer.write(typeWriter.toString());
	writer.write("}"); //$NON-NLS-1$
	if ( arrayDimensions != null ) {
		writer.write(" array dimensions="); //$NON-NLS-1$
		writer.write(new Integer(arrayDimensions.size()).toString());
	}
	if ( fArrayArguments != null ) {	
		writer.write(" array dimensions="); //$NON-NLS-1$
		writer.write(new Integer(fArrayArguments.size()).toString());
	}
	return writer.toString();

}

public boolean isPrimitive() {
	return getTypeClass().isPrimitive();
}
public void setArrayArguments(List arguments) {
	fArrayArguments = arguments;
}
}
