/*******************************************************************************
 * 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.ide;
/*


 */

import org.eclipse.jem.internal.proxy.core.*;
import java.lang.reflect.*;
import java.util.Arrays;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
/**
 * IDE VM version of the Array proxy
 */

public final class IDEArrayBeanProxy extends IDEObjectBeanProxy implements IArrayBeanProxy {

	private IDEStandardBeanTypeProxyFactory fBeanTypeProxyFactory;
	
IDEArrayBeanProxy(IDEProxyFactoryRegistry aRegistry, Object array,IBeanTypeProxy aType) {
	super(aRegistry, array ,aType);
	fBeanTypeProxyFactory = (IDEStandardBeanTypeProxyFactory)aRegistry.getBeanTypeProxyFactory();
}

/* (non-Javadoc)
 * @see org.eclipse.jem.internal.proxy.ide.IDEBeanProxy#equals(java.lang.Object)
 */
public boolean equals(Object obj) {
	if (super.equals(obj))
		return true;
	if (!(obj instanceof IDEArrayBeanProxy))
		return false;
	Object arrayBean = ((IDEArrayBeanProxy) obj).getBean();

	if (getBean() == null || arrayBean == null)
		return false;
	Object thisArrayBean = getBean();
	Class aclass = thisArrayBean.getClass();
	Class bclass = arrayBean.getClass();
	Class acomp = aclass.getComponentType();
	Class bcomp = bclass.getComponentType();
	if (acomp.isPrimitive() || bcomp.isPrimitive()) {
		if (acomp != bcomp)
			return false;
		if (acomp == Integer.TYPE)
			return Arrays.equals((int[]) thisArrayBean, (int[]) arrayBean);
		else if (acomp == Boolean.TYPE)
			return Arrays.equals((boolean[]) thisArrayBean, (boolean[]) arrayBean);
		else if (acomp == Long.TYPE)
			return Arrays.equals((long[]) thisArrayBean, (long[]) arrayBean);
		else if (acomp == Short.TYPE)
			return Arrays.equals((short[]) thisArrayBean, (short[]) arrayBean);
		else if (acomp == Double.TYPE)
			return Arrays.equals((double[]) thisArrayBean, (double[]) arrayBean);
		else if (acomp == Float.TYPE)
			return Arrays.equals((float[]) thisArrayBean, (float[]) arrayBean);
		else if (acomp == Character.TYPE)
			return Arrays.equals((char[]) thisArrayBean, (char[]) arrayBean);
		else if (acomp == Byte.TYPE)
			return Arrays.equals((byte[]) thisArrayBean, (byte[]) arrayBean);
		else
			return false;
	} else
		return Arrays.equals((Object[]) thisArrayBean, (Object[]) arrayBean);
}
/**
 * Get the object at the specified index.
 */
public IBeanProxy get(int index) throws ThrowableProxy {
	// If the component type is primitive, we need to use the correct getter so that a valid value is returned,
	// if we just used the standard get, if the type was "int" the value returned would be an java.lang.Integer.
	IBeanTypeProxy compType = ((IArrayBeanTypeProxy) getTypeProxy()).getComponentType();
	if (!compType.isPrimitive()) {
		// Use standard getter.
		Object result = Array.get(fBean,index);
		if ( result == null ) return null;
		return ((IDEBeanTypeProxy)fBeanTypeProxyFactory.getBeanTypeProxy(result.getClass())).newBeanProxy(result);
	} else {
		// Use the correct primitive getter.
		int id = ((IDEPrimitiveBeanTypeProxy)compType).getPrimitiveType();
		switch (id) {
			case IDEPrimitiveBeanTypeProxy.BYTE:
				return fBeanTypeProxyFactory.byteType.createByteBeanProxy(Array.getByte(fBean,index));
			case IDEPrimitiveBeanTypeProxy.BOOLEAN:
				return fBeanTypeProxyFactory.booleanType.createBooleanBeanProxy(Array.getBoolean(fBean,index));
			case IDEPrimitiveBeanTypeProxy.CHAR:
				return fBeanTypeProxyFactory.charType.createCharBeanProxy(Array.getChar(fBean,index));
			case IDEPrimitiveBeanTypeProxy.DOUBLE:
				return fBeanTypeProxyFactory.doubleType.createDoubleBeanProxy(Array.getDouble(fBean,index));
			case IDEPrimitiveBeanTypeProxy.FLOAT:
				return fBeanTypeProxyFactory.floatType.createFloatBeanProxy(Array.getFloat(fBean,index));
			case IDEPrimitiveBeanTypeProxy.INTEGER:
				return fBeanTypeProxyFactory.intType.createIntegerBeanProxy(Array.getInt(fBean,index));
			case IDEPrimitiveBeanTypeProxy.LONG:
				return fBeanTypeProxyFactory.longType.createLongBeanProxy(Array.getLong(fBean,index));
			case IDEPrimitiveBeanTypeProxy.SHORT:
				return fBeanTypeProxyFactory.shortType.createShortBeanProxy(Array.getShort(fBean,index));
			default :
				return null; // Shouldn't get here, said it was primitive, but not one we understand				
		}
	}		
}
/**
 * Get the object at the specified multi-dimensional index.
 * The array must be at least the number of dimensions specified,
 * and each index along the way must exist.
 * The number of dimensions can't be greater than the number
 * of dimensions of the real object.
 */
public IBeanProxy get(int[] indexes) throws ThrowableProxy {
	if (indexes.length == 1)
		return get(indexes[0]);
	int dims = ((IArrayBeanTypeProxy) getTypeProxy()).getDimensions();
	if (dims < indexes.length)
		throw new IllegalArgumentException(); // Too many dimensions
	// Get up to the next to last dimension so that we can do the appropriate final get depending upon primitive or not.
	Object array = fBean;
	int lastArrayDim = indexes.length - 1;
	for (int i = 0; i < lastArrayDim; i++)
		array = Array.get(array, indexes[i]);

	int index = indexes[lastArrayDim];	// Final array dim to retrieve
	
	if (dims == indexes.length) {
		IBeanTypeProxy finalCompType = ((IArrayBeanTypeProxy) getTypeProxy()).getFinalComponentType();
		if (finalCompType.isPrimitive()) {
			// If the component type at the specified dimension is primitive, we need to use the correct getter so that a valid value is returned,
			// if we just used the standard get, if the type was "int" the value returned would be an java.lang.Integer.
			int id = ((IDEPrimitiveBeanTypeProxy) finalCompType).getPrimitiveType();
			switch (id) {
				case IDEPrimitiveBeanTypeProxy.BYTE :
					return fBeanTypeProxyFactory.byteType.createByteBeanProxy(Array.getByte(array, index));
				case IDEPrimitiveBeanTypeProxy.BOOLEAN :
					return fBeanTypeProxyFactory.booleanType.createBooleanBeanProxy(Array.getBoolean(array, index));
				case IDEPrimitiveBeanTypeProxy.CHAR :
					return fBeanTypeProxyFactory.charType.createCharBeanProxy(Array.getChar(array, index));
				case IDEPrimitiveBeanTypeProxy.DOUBLE :
					return fBeanTypeProxyFactory.doubleType.createDoubleBeanProxy(Array.getDouble(array, index));
				case IDEPrimitiveBeanTypeProxy.FLOAT :
					return fBeanTypeProxyFactory.floatType.createFloatBeanProxy(Array.getFloat(array, index));
				case IDEPrimitiveBeanTypeProxy.INTEGER :
					return fBeanTypeProxyFactory.intType.createIntegerBeanProxy(Array.getInt(array, index));
				case IDEPrimitiveBeanTypeProxy.LONG :
					return fBeanTypeProxyFactory.longType.createLongBeanProxy(Array.getLong(array, index));
				case IDEPrimitiveBeanTypeProxy.SHORT :
					return fBeanTypeProxyFactory.shortType.createShortBeanProxy(Array.getShort(array, index));
				default :
					return null; // Shouldn't get here, said it was primitive, but not one we understand
			}
		}
	}

	// Won't be returning a primitive, so use standard accessor
	Object result = Array.get(array, index);
	if (result == null)
		return null;
	return ((IDEBeanTypeProxy) fBeanTypeProxyFactory.getBeanTypeProxy(result.getClass())).newBeanProxy(
		result);
}

/**
 * Set the object at the specified index.
 */
public void set(IBeanProxy valueProxy, int index) throws ThrowableProxy {
	// If the component type is primitive, we need to use the correct getter so that a valid value is returned,
	// if we just used the standard get, if the type was "int" the value returned would be an java.lang.Integer.
	Object value = ((IIDEBeanProxy)valueProxy).getBean();
	Class valueClass = value.getClass();
	if (!valueClass.isPrimitive()) {
		// Use standard getter.
		Array.set(fBean,index,value);
	} else if (valueClass == Byte.TYPE ) {
		Array.setByte(fBean,index,((Byte)value).byteValue());
	} else if (valueClass == Boolean.TYPE ){
		Array.setBoolean(fBean,index,((Boolean)value).booleanValue());			
	} else if (valueClass == Character.TYPE) {
		Array.setChar(fBean,index,((Character)value).charValue());
	} else if (valueClass == Double.TYPE) {
		Array.setDouble(fBean,index,((Double)value).doubleValue());
	} else if (valueClass == Float.TYPE) {
		Array.setFloat(fBean,index,((Float)value).floatValue());		
	} else if (valueClass == Integer.TYPE) {
		Array.setInt(fBean,index,((Integer)value).intValue());		
	} else if (valueClass == Long.TYPE ) {
		Array.setLong(fBean,index,((Long)value).longValue());		
	} else if (valueClass == Short.TYPE ) {
		Array.setShort(fBean,index,((Short)value).shortValue());		
	}
}
/**
 * Set the object at the specified multi-dimensional index.
 * The array must be at least the number of dimensions specified,
 * and each index along the way must exist.
 * The number of dimensions can't be greater than the number
 * of dimensions of the real object.
 */
public void set(IBeanProxy valueProxy, int[] indexes) throws ThrowableProxy {

	Object subArray = fBean;
	int upTo = indexes.length - 1;
	for (int i = 0; i < upTo; i++)
		subArray = Array.get(subArray, indexes[i]);
	int index = indexes[upTo];

	// Now set the appropriate value in
	// If the component type is primitive, we need to use the correct getter so that a valid value is returned,
	// if we just used the standard get, if the type was "int" the value returned would be an java.lang.Integer.
	Object value = ((IIDEBeanProxy) valueProxy).getBean();
	Class valueClass = value.getClass();
	if (!valueClass.isPrimitive()) {
		// Use standard getter.
		Array.set(subArray, index, value);
	} else if (valueClass == Byte.TYPE) {
		Array.setByte(subArray, index, ((Byte) value).byteValue());
	} else if (valueClass == Boolean.TYPE) {
		Array.setBoolean(subArray, index, ((Boolean) value).booleanValue());
	} else if (valueClass == Character.TYPE) {
		Array.setChar(subArray, index, ((Character) value).charValue());
	} else if (valueClass == Double.TYPE) {
		Array.setDouble(subArray, index, ((Double) value).doubleValue());
	} else if (valueClass == Float.TYPE) {
		Array.setFloat(subArray, index, ((Float) value).floatValue());
	} else if (valueClass == Integer.TYPE) {
		Array.setInt(subArray, index, ((Integer) value).intValue());
	} else if (valueClass == Long.TYPE) {
		Array.setLong(subArray, index, ((Long) value).longValue());
	} else if (valueClass == Short.TYPE) {
		Array.setShort(subArray, index, ((Short) value).shortValue());
	}

}
/**
 * Get the length of the first dimension of this array.
 * If there are multi-dimensions, you must get the appropriate
 * dimension from the get method to see the size of that dimension.
 *
 * e.g.
 *    int [3] returns 3
 *    int [3][2] returns 3
 *
 *    ((IArrayBeanProxy) get(1)).getLength() returns 2
 *    Since arrays do not have to be homogenous, there could
 *    be a different length array for each of the arrays 
 *    returned from the first dimension, the returned length
 *    from get(2) and get(3) could result in a different value
 *    from get(1).
 */
public int getLength() {
	return Array.getLength(fBean);
}	
	/**
	 * @see org.eclipse.jem.internal.proxy.core.IArrayBeanProxy#getCatchThrowableException(int)
	 */
	public IBeanProxy getCatchThrowableException(int index) {
		try {
			return get(index);
		} catch ( ThrowableProxy exc ) {
			ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", exc));			 //$NON-NLS-1$
			return null;
		}
	}

	
	public IBeanProxy[] getSnapshot() throws ThrowableProxy {
		// If the component type is primitive, we need to use the correct getter so that a valid value is returned,
		// if we just used the standard get, if the type was "int" the value returned would be an java.lang.Integer.
		IBeanTypeProxy compType = ((IArrayBeanTypeProxy) getTypeProxy()).getComponentType();
		int id = compType.isPrimitive() ? ((IDEPrimitiveBeanTypeProxy)compType).getPrimitiveType() : -1;
		IBeanProxy[] result = new IBeanProxy[Array.getLength(fBean)];
		for (int i = 0; i < result.length; i++) {
			if (id == -1) {
				// Use standard getter.
				Object val = Array.get(fBean,i);
				if ( val != null )
					result[i] = ((IDEBeanTypeProxy)fBeanTypeProxyFactory.getBeanTypeProxy(val.getClass())).newBeanProxy(val);
			} else {
				// Use the correct primitive getter.
				switch (id) {
					case IDEPrimitiveBeanTypeProxy.BYTE:
						result[i] = fBeanTypeProxyFactory.byteType.createByteBeanProxy(Array.getByte(fBean,i));
						break;
					case IDEPrimitiveBeanTypeProxy.BOOLEAN:
						result[i] = fBeanTypeProxyFactory.booleanType.createBooleanBeanProxy(Array.getBoolean(fBean,i));
						break;
					case IDEPrimitiveBeanTypeProxy.CHAR:
						result[i] = fBeanTypeProxyFactory.charType.createCharBeanProxy(Array.getChar(fBean,i));
						break;
					case IDEPrimitiveBeanTypeProxy.DOUBLE:
						result[i] = fBeanTypeProxyFactory.doubleType.createDoubleBeanProxy(Array.getDouble(fBean,i));
						break;
					case IDEPrimitiveBeanTypeProxy.FLOAT:
						result[i] = fBeanTypeProxyFactory.floatType.createFloatBeanProxy(Array.getFloat(fBean,i));
						break;
					case IDEPrimitiveBeanTypeProxy.INTEGER:
						result[i] = fBeanTypeProxyFactory.intType.createIntegerBeanProxy(Array.getInt(fBean,i));
						break;
					case IDEPrimitiveBeanTypeProxy.LONG:
						result[i] = fBeanTypeProxyFactory.longType.createLongBeanProxy(Array.getLong(fBean,i));
						break;
					case IDEPrimitiveBeanTypeProxy.SHORT:
						result[i] = fBeanTypeProxyFactory.shortType.createShortBeanProxy(Array.getShort(fBean,i));
						break;
					default :
						break; // Shouldn't get here, said it was primitive, but not one we understand				
				}
			}		
		}
		return result;
	}

}
