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

import java.util.ArrayList;
import java.util.List;

import jp.sourceforge.asclipse.as3.element.AS3Element;
import jp.sourceforge.asclipse.as3.element.AS3Import;
import jp.sourceforge.asclipse.as3.element.AS3Package;
import jp.sourceforge.asclipse.as3.element.AS3Type;

import org.antlr.runtime.tree.CommonTree;
import org.apache.commons.lang.StringUtils;

/**
 * {@link AS3Type}の内部用の抽象クラス。
 * @author shin1ogawa
 */
@SuppressWarnings("serial")
public abstract class AbstractAS3Type extends AbstractAS3ElementWithModifiers implements AS3Type {

	protected final String identifier;

	private String qualifiedName = null;


	/**
	 * Constructor.
	 * @param tree
	 * @param modifiers
	 * @param identifier
	 * @category constructor
	 */
	public AbstractAS3Type(CommonTree tree, CommonTree[] modifiers, String identifier) {
		super(tree, modifiers);
		if (modifiers == null) {
			throw new NullPointerException("modifiers");
		}
		if (identifier == null) {
			throw new NullPointerException("identifier");
		}
		this.identifier = identifier;
	}

	public String getIdentifier() {
		return identifier;
	}

	public String getQualifiedName() {
		if (qualifiedName != null) {
			return qualifiedName;
		}
		String packageIdentifier = null;
		AS3Element parent = getParent();
		if (parent instanceof AS3Package) {
			packageIdentifier = ((AS3Package) parent).getIdentifier();
		} else {
			// ファイル直下にパッケージと並列で定義されたクラスの場合。
			List<AS3Element> children = parent.getChildren();
			for (AS3Element element : children) {
				if (element instanceof AS3Package) {
					packageIdentifier = ((AS3Package) parent).getIdentifier();
					break;
				}
			}
		}
		qualifiedName =
				StringUtils.isEmpty(packageIdentifier) ? identifier : packageIdentifier + "."
						+ identifier;
		return qualifiedName;
	}

	public List<AS3Import> getImportDeclarations() {
		List<AS3Import> importDecls = new ArrayList<AS3Import>();
		List<AS3Element> children = null;
		if (getParent() != null) {
			children = getParent().getChildren();
			for (AS3Element child : children) {
				if (child instanceof AS3Import) {
					importDecls.add((AS3Import) child);
				}
			}
		}
		children = getChildren();
		for (AS3Element child : children) {
			if (child instanceof AS3Import) {
				importDecls.add((AS3Import) child);
			}
		}
		return importDecls;
	}

	@Override
	public AS3Type getEnclosureType() {
		return this;
	}
}
