package jp.sourceforge.asclipse.as3.resolver;

import java.io.Serializable;

import jp.sourceforge.asclipse.as3.element.AS3Class;
import jp.sourceforge.asclipse.as3.element.AS3Interface;
import jp.sourceforge.asclipse.as3.element.AS3Type;

/**
 * 型への参照を表すインターフェース。
 * 
 * @author shin1ogawa
 */
public interface AS3TypeRef extends Serializable {

	/**
	 * @return ソースコードに記述されている型の名称
	 */
	String getTypeName();

	/**
	 * @return 参照を解決できているなら{@code true}
	 */
	boolean isResolved();

	/**
	 * 解決できている参照の実体を返す。
	 * <p>具体的には{@link AS3Class}や{@link AS3Interface}など。</p>
	 * @return 解決できている参照の実体
	 */
	AS3Type getResolvedType();

	/**
	 * 参照を解決して、実体を設定する。
	 * @param element 
	 * @throws IllegalArgumentException {@literal element}が{@code null}の場合 
	 */
	void setResolvedType(AS3Type element) throws IllegalArgumentException;

	/**
	 * 解決済みの{@AS3Type}への参照を削除し、未解決の状態にする。
	 */
	void unresolve();

	/**
	 * 正確な型名称を返す。
	 * <p>型の解決ができている状態で使用できる。</p>
	 * @return 正確な型名称
	 */
	String getQualifiedName();


	/** 型の指定が無い、等の理由で何も参照していない{@link AS3TypeRef}。いわゆるワイルドカード型 */
	@SuppressWarnings("serial")
	AS3TypeRef NULL_TYPE_REF = new AS3TypeRef() {

		public String getTypeName() {
			return null;
		}

		public boolean isResolved() {
			return false;
		}

		public AS3Type getResolvedType() {
			return null;
		}

		public void setResolvedType(AS3Type element) {
		}

		public String getQualifiedName() {
			return null;
		}

		public void unresolve() {
		}

		@Override
		public String toString() {
			return "*";
		}
	};

	/** Object型への参照 */
	@SuppressWarnings("serial")
	AS3TypeRef OBJECT_TYPE_REF = new AS3TypeRef() {

		private AS3Type element;


		public String getTypeName() {
			return "Object";
		}

		public boolean isResolved() {
			return element != null;
		}

		public AS3Type getResolvedType() {
			return element;
		}

		public void setResolvedType(AS3Type element) {
			this.element = element;
		}

		public String getQualifiedName() {
			return "Object";
		}

		public void unresolve() {
		}

		@Override
		public String toString() {
			return getQualifiedName();
		}
	};
}
