package jp.sourceforge.asclipse.as3.util;

import jp.sourceforge.asclipse.as3.AS3Parser;
import jp.sourceforge.asclipse.as3.AS3Parser.memberModifiers_return;
import jp.sourceforge.asclipse.as3.util.CommonTreeUtil.SerializableToken;

import org.antlr.runtime.Token;

/**
 * {@link memberModifiers_return}用のユーティリティクラス。
 * @author shin1ogawa
 */
public class ModifiersUtil {

	private ModifiersUtil() {
	}

	/**
	 * modifiersの中にnamespaceの修飾があるかどうか。
	 * @param modifiers
	 * @return namespaceの修飾があるなら{@code true}
	 */
	public static boolean hasNamespaceModifier(SerializableToken[] modifiers) {
		return getNamespaceModifier(modifiers) != null;
	}

	/**
	 * @param token
	 * @return tokenがmodifierなら{@code true}
	 */
	public static boolean isModifier(Token token) {
		int type = token.getType();
		return type == AS3Parser.DYNAMIC || type == AS3Parser.FINAL || type == AS3Parser.INTERNAL
				|| type == AS3Parser.NATIVE || type == AS3Parser.OVERRIDE
				|| type == AS3Parser.PRIVATE || type == AS3Parser.PROTECTED
				|| type == AS3Parser.PUBLIC || type == AS3Parser.STATIC;
	}

	/**
	 * modifiersの中に含まれるnamespaceの修飾Tokenを返す。
	 * @param modifiers
	 * @return modifiersの中に含まれるnamespaceの修飾Token。無ければ{@code null}を返す。
	 */
	public static Token getNamespaceModifier(SerializableToken[] modifiers) {
		for (SerializableToken token : modifiers) {
			if (token.getType() != AS3Parser.DYNAMIC && token.getType() != AS3Parser.FINAL
					&& token.getType() != AS3Parser.INTERNAL && token.getType() != AS3Parser.NATIVE
					&& token.getType() != AS3Parser.OVERRIDE
					&& token.getType() != AS3Parser.PRIVATE
					&& token.getType() != AS3Parser.PROTECTED
					&& token.getType() != AS3Parser.PUBLIC && token.getType() != AS3Parser.STATIC
					&& token.getType() != AS3Parser.SET && token.getType() != AS3Parser.GET
					&& token.getType() != AS3Parser.CONST && token.getType() != AS3Parser.VAR) {
				return token;
			}
		}
		return null;
	}

	/**
	 * @param modifiers 
	 * @return {@literal dynamic} modifierを持つなら{@code true}。
	 */
	public static boolean isDynamic(SerializableToken[] modifiers) {
		return contain(modifiers, AS3Parser.DYNAMIC);
	}

	/**
	 * @param modifiers 
	 * @return {@literal dynamic} modifierを持つなら{@code true}。
	 */
	public static boolean isFinal(SerializableToken[] modifiers) {
		return contain(modifiers, AS3Parser.FINAL);
	}

	/**
	 * @param modifiers 
	 * @return {@literal internal} modifierを持つなら{@code true}。
	 */
	public static boolean isInternal(SerializableToken[] modifiers) {
		return contain(modifiers, AS3Parser.INTERNAL);
	}

	/**
	 * @param modifiers 
	 * @return {@literal native} modifierを持つなら{@code true}。
	 */
	public static boolean isNative(SerializableToken[] modifiers) {
		return contain(modifiers, AS3Parser.NATIVE);
	}

	/**
	 * @param modifiers 
	 * @return {@literal override} modifierを持つなら{@code true}。
	 */
	public static boolean isOverride(SerializableToken[] modifiers) {
		return contain(modifiers, AS3Parser.OVERRIDE);
	}

	/**
	 * @param modifiers 
	 * @return {@literal private} modifierを持つなら{@code true}。
	 */
	public static boolean isPrivate(SerializableToken[] modifiers) {
		return contain(modifiers, AS3Parser.PRIVATE);
	}

	/**
	 * @param modifiers 
	 * @return {@literal protected} modifierを持つなら{@code true}。
	 */
	public static boolean isProtected(SerializableToken[] modifiers) {
		return contain(modifiers, AS3Parser.PROTECTED);
	}

	/**
	 * @param modifiers 
	 * @return {@literal public} modifierを持つなら{@code true}。
	 */
	public static boolean isPublic(SerializableToken[] modifiers) {
		return contain(modifiers, AS3Parser.PUBLIC);
	}

	/**
	 * @param modifiers 
	 * @return {@literal public} modifierを持つなら{@code true}。
	 */
	public static boolean isStatic(SerializableToken[] modifiers) {
		return contain(modifiers, AS3Parser.STATIC);
	}

	private static boolean contain(SerializableToken[] modifiers, int type) {
		if (modifiers == null) {
			return false;
		}
		for (SerializableToken modifier : modifiers) {
			if (modifier.getType() == type) {
				return true;
			}
		}
		return false;
	}

	/**
	 * @param modifiers
	 * @return 人間が読みやすい表現の文字列。
	 */
	public static String getTitle(SerializableToken[] modifiers) {
		if (modifiers == null) {
			return "";
		}
		StringBuilder b = new StringBuilder();
		boolean first = true;
		for (SerializableToken modifier : modifiers) {
			Token token = modifier;
			if (!first) {
				b.append(" ");
			} else {
				first = false;
			}
			b.append(token.getText());
		}
		return b.toString();
	}
}
