package jp.sourceforge.asclipse.as3.internal.resolver;

import java.lang.ref.WeakReference;

import jp.sourceforge.asclipse.as3.element.AS3Package;
import jp.sourceforge.asclipse.as3.element.AS3Type;
import jp.sourceforge.asclipse.as3.resolver.AS3TypeRef;

import org.apache.commons.lang.StringUtils;

/**
 * {@link AS3TypeRef}の内部用の実装。
 * <p>とりあえず、ソースのOutline表示に必要な要素を揃えるための暫定実装。</p>
 * @author shin1ogawa
 */
@SuppressWarnings("serial")
public class DefaultAS3TypeRef implements AS3TypeRef {

	private String typeName;

	private String qualifiedName;

	private WeakReference<AS3Type> resolvedType;


	/**
	 * Constructor.
	 * @param typeName
	 * @category constructor
	 */
	DefaultAS3TypeRef(String typeName) {
		this.typeName = typeName;
		qualifiedName = typeName; // とりあえず。
	}

	/**
	 * Constructor.
	 * @param type
	 * @category constructor
	 */
	DefaultAS3TypeRef(AS3Type type) {
		this.resolvedType = new WeakReference<AS3Type>(type);
		this.typeName = type.getIdentifier();
		qualifiedName = type.getQualifiedName();
	}

	public String getTypeName() {
		return typeName;
	}

	public boolean isResolved() {
		return resolvedType != null && !resolvedType.isEnqueued() && resolvedType.get() != null;
	}

	public AS3Type getResolvedType() {
		return resolvedType.get();
	}

	public void setResolvedType(AS3Type element) throws IllegalArgumentException {
		if (element == null) {
			throw new IllegalArgumentException();
		}
		this.resolvedType = new WeakReference<AS3Type>(element);
		AS3Package enclosurePackage = element.getEnclosurePackage();
		if (enclosurePackage != null && !StringUtils.isEmpty(enclosurePackage.getIdentifier())) {
			qualifiedName = enclosurePackage.getIdentifier() + "." + typeName;
		}
	}

	public String getQualifiedName() {
		if (!isResolved()) {
			throw new IllegalStateException();
		}
		return qualifiedName;
	}

	public void unresolve() {
		resolvedType.clear();
		resolvedType = null;
	}

	@Override
	public String toString() {
		if (isResolved()) {
			return getQualifiedName() + "(resolved)";
		} else {
			return getTypeName() + "(unresolved)";
		}
	}
}
