/*******************************************************************************
 * Copyright (c) 2000, 2011 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.jdt.internal.debug.core.model;

import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IVariable;
import org.eclipse.jdt.debug.core.IJavaFieldVariable;
import org.eclipse.jdt.debug.core.IJavaModifiers;
import org.eclipse.jdt.debug.core.IJavaObject;
import org.eclipse.jdt.debug.core.IJavaReferenceType;
import org.eclipse.jdt.debug.core.IJavaType;
import org.eclipse.jdt.debug.core.IJavaValue;
import org.eclipse.jdt.debug.core.IJavaVariable;

import com.ibm.icu.text.MessageFormat;
import com.sun.jdi.ClassNotLoadedException;
import com.sun.jdi.ClassType;
import com.sun.jdi.Field;
import com.sun.jdi.InterfaceType;
import com.sun.jdi.InvalidTypeException;
import com.sun.jdi.ObjectReference;
import com.sun.jdi.ReferenceType;
import com.sun.jdi.Type;
import com.sun.jdi.Value;

/**
 * A field member.
 */
public class JDIFieldVariable extends JDIModificationVariable implements
		IJavaFieldVariable {
	/**
	 * The underlying field
	 */
	private Field fField;
	/**
	 * The object containing the field, or <code>null</code> for a static field.
	 */
	private ObjectReference fObject;
	/**
	 * The type containing the field.
	 */
	private ReferenceType fType;

	/**
	 * When created for a logical structure we hold onto the original
	 * non-logical value for purposes of equality. This way a logical
	 * structure's children remain more stable in the variables view.
	 * 
	 * This is <code>null</code> when not created for a logical structure.
	 */
	private IJavaValue fLogicalParent;

	/**
	 * Constructs a field for the given field.
	 */
	public JDIFieldVariable(JDIDebugTarget target, Field field,
			ObjectReference objectRef, IJavaValue logicalParent) {
		super(target);
		fField = field;
		if (!field.isStatic()) {
			fObject = objectRef;
		}
		fType = (ReferenceType) objectRef.type();
		fLogicalParent = logicalParent;
	}

	/**
	 * Constructs a field to wrap the given field.
	 */
	public JDIFieldVariable(JDIDebugTarget target, Field field,
			ReferenceType refType) {
		super(target);
		fField = field;
		fType = refType;
	}

	/**
	 * Returns this variable's current <code>Value</code>.
	 */
	@Override
	protected Value retrieveValue() {
		if (getField().isStatic()) {
			return (getField().declaringType().getValue(getField()));
		}
		return getObjectReference().getValue(getField());
	}

	/**
	 * @see IJavaFieldVariable#getDeclaringType()
	 */
	@Override
	public IJavaType getDeclaringType() {
		return JDIType.createType((JDIDebugTarget) getDebugTarget(),
				fField.declaringType());
	}

	/**
	 * @see IVariable#getName()
	 */
	@Override
	public String getName() throws DebugException {
		try {
			return getField().name();
		} catch (RuntimeException e) {
			targetRequestFailed(
					MessageFormat.format(
							JDIDebugModelMessages.JDIFieldVariable_exception_retrieving_field_name,
							e.toString()), e);
			// execution will not reach this line, as
			// #targetRequestFailed will thrown an exception
			return null;
		}
	}

	@Override
	protected void setJDIValue(Value value) throws DebugException {
		try {
			if (isStatic()) {
				ReferenceType declaringType = getField().declaringType();
				if (declaringType instanceof InterfaceType) {
					requestFailed(JDIDebugModelMessages.JDIFieldVariable_0,
							null);
				}
				((ClassType) declaringType).setValue(getField(), value);
			} else {
				getObjectReference().setValue(getField(), value);
			}
			fireChangeEvent(DebugEvent.CONTENT);
		} catch (ClassNotLoadedException e) {
			targetRequestFailed(
					MessageFormat.format(
							JDIDebugModelMessages.JDIFieldVariable_exception_modifying_value,
							e.toString()), e);
		} catch (InvalidTypeException e) {
			targetRequestFailed(
					MessageFormat.format(
							JDIDebugModelMessages.JDIFieldVariable_exception_modifying_value,
							e.toString()), e);
		} catch (RuntimeException e) {
			targetRequestFailed(
					MessageFormat.format(
							JDIDebugModelMessages.JDIFieldVariable_exception_modifying_value,
							e.toString()), e);
		}

	}

	/**
	 * @see IJavaVariable#isVolatile()
	 */
	@Override
	public boolean isVolatile() {
		return getField().isVolatile();
	}

	/**
	 * @see IJavaVariable#isTransient()
	 */
	@Override
	public boolean isTransient() {
		return getField().isTransient();
	}

	/**
	 * @see IJavaModifiers#isSynthetic()
	 */
	@Override
	public boolean isSynthetic() {
		return getField().isSynthetic();
	}

	/**
	 * @see IJavaModifiers#isPublic()
	 */
	@Override
	public boolean isPublic() {
		return getField().isPublic();
	}

	/**
	 * @see IJavaModifiers#isPrivate()
	 */
	@Override
	public boolean isPrivate() {
		return getField().isPrivate();
	}

	/**
	 * @see IJavaModifiers#isProtected()
	 */
	@Override
	public boolean isProtected() {
		return getField().isProtected();
	}

	/**
	 * @see IJavaModifiers#isPackagePrivate()
	 */
	@Override
	public boolean isPackagePrivate() {
		return getField().isPackagePrivate();
	}

	/**
	 * @see IJavaModifiers#isStatic()
	 */
	@Override
	public boolean isStatic() {
		return getField().isStatic();
	}

	/**
	 * @see IJavaModifiers#isFinal()
	 */
	@Override
	public boolean isFinal() {
		return getField().isFinal();
	}

	/**
	 * @see IVariable#getReferenceTypeName()
	 */
	@Override
	public String getReferenceTypeName() throws DebugException {
		String genericSignature = getField().genericSignature();
		if (genericSignature != null) {
			return JDIReferenceType.getTypeName(genericSignature);
		}
		Type underlyingType = getUnderlyingType();
		if (underlyingType instanceof ReferenceType) {
			return JDIReferenceType
					.getGenericName((ReferenceType) underlyingType);
		}
		return getField().typeName();
	}

	/**
	 * @see IJavaVariable#getSignature()
	 */
	@Override
	public String getSignature() throws DebugException {
		try {
			return getField().signature();
		} catch (RuntimeException e) {
			targetRequestFailed(
					MessageFormat.format(
							JDIDebugModelMessages.JDIFieldVariable_exception_retrieving_field_signature,
							e.toString()), e);
			// execution will not reach this line, as
			// #targetRequestFailed will thrown an exception
			return null;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jdt.debug.core.IJavaVariable#getGenericSignature()
	 */
	@Override
	public String getGenericSignature() throws DebugException {
		try {
			String genericSignature = fField.genericSignature();
			if (genericSignature != null) {
				return genericSignature;
			}
			return fField.signature();
		} catch (RuntimeException e) {
			targetRequestFailed(
					MessageFormat.format(
							JDIDebugModelMessages.JDIFieldVariable_exception_retrieving_field_signature,
							e.toString()), e);
			// execution will not reach this line, as
			// #targetRequestFailed will thrown an exception
			return null;
		}
	}

	public Field getField() {
		return fField;
	}

	public ObjectReference getObjectReference() {
		return fObject;
	}

	public ReferenceType getReferenceType() {
		return fType;
	}

	@Override
	public boolean supportsValueModification() {
		if (getField().declaringType() instanceof InterfaceType) {
			return false;
		}
		return super.supportsValueModification();
	}

	/**
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return getField().toString();
	}

	/**
	 * @see JDIVariable#getUnderlyingType()
	 */
	@Override
	protected Type getUnderlyingType() throws DebugException {
		try {
			return getField().type();
		} catch (ClassNotLoadedException e) {
			targetRequestFailed(
					MessageFormat.format(
							JDIDebugModelMessages.JDIFieldVariable_exception_while_retrieving_type_of_field,
							e.toString()), e);
		} catch (RuntimeException e) {
			targetRequestFailed(
					MessageFormat.format(
							JDIDebugModelMessages.JDIFieldVariable_exception_while_retrieving_type_of_field,
							e.toString()), e);
		}
		// this line will not be executed as an exception
		// will be throw in type retrieval fails
		return null;
	}

	/**
	 * @see java.lang.Object#equals(Object)
	 */
	@Override
	public boolean equals(Object o) {
		if (o instanceof JDIFieldVariable) {
			JDIFieldVariable f = (JDIFieldVariable) o;
			if (fLogicalParent != null) {
				return fLogicalParent.equals(f.fLogicalParent)
						&& f.fField.equals(fField);
			}
			if (fObject != null) {
				return fObject.equals(f.fObject) && f.fField.equals(fField);
			}
			return f.fField.equals(fField);
		}
		return false;
	}

	/**
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		if (fLogicalParent != null) {
			return fLogicalParent.hashCode() + fField.hashCode();
		}
		if (fObject != null) {
			return fField.hashCode() + fObject.hashCode();
		}
		return fField.hashCode();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jdt.debug.core.IJavaFieldVariable#getObject()
	 */
	@Override
	public IJavaObject getReceiver() {
		ObjectReference objectReference = getObjectReference();
		if (objectReference == null) {
			return null;
		}
		return (IJavaObject) JDIValue.createValue(getJavaDebugTarget(),
				objectReference);
	}

	@Override
	public IJavaReferenceType getReceivingType() {
		return (IJavaReferenceType) JDIType.createType(getJavaDebugTarget(),
				getReferenceType());
	}

}
