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

import jp.sourceforge.asclipse.as3.element.AS3Variable;
import jp.sourceforge.asclipse.as3.resolver.AS3TypeRef;
import jp.sourceforge.asclipse.as3.util.CommonTreeUtil.SerializableToken;

import org.antlr.runtime.tree.CommonTree;

/**
 * {@link AS3Variable}の内部用の実装。
 * <p>
 * VarDecl=variableIdentifierDecl (A=ASSIGN AssignExpr=assignmentExpression)?
 * </p>
 * <p>無理矢理typeを抽出している。マズイかもしれん。</p>
 * @author shin1ogawa
 */
@SuppressWarnings("serial")
public class DefaultAS3Variable extends AbstractAS3Element implements AS3Variable {

	private final String identifier;

	private final boolean hasType;

	private final AS3TypeRef typeRef;

	private final boolean hasAssignment;

	private final SerializableToken[] assignmentExpressions;

	private boolean hasEllipsis = false;


	/**
	 * Constructor.
	 * @param tree
	 * @param identifier
	 * @param typeRef
	 * @param assignmentExpressions
	 * @category constructor
	 */
	public DefaultAS3Variable(CommonTree tree, String identifier, AS3TypeRef typeRef,
			CommonTree[] assignmentExpressions) {
		super(tree);
		this.identifier = identifier;
		this.typeRef = typeRef;
		this.hasType = typeRef != AS3TypeRef.NULL_TYPE_REF;
		this.assignmentExpressions = new SerializableToken[assignmentExpressions.length];
		for (int i = 0; i < assignmentExpressions.length; i++) {
			this.assignmentExpressions[i] =
					new SerializableToken(assignmentExpressions[i].getToken());
		}
		this.hasAssignment = assignmentExpressions.length > 0;
	}

	public String getOutlineTitle() {
		StringBuilder b = new StringBuilder();
		b.append(identifier);
		if (hasType) {
			b.append(":").append(typeRef.getTypeName());
		}
		return b.toString();
	}

	public String getTitle() {
		StringBuilder b = new StringBuilder();
		if (hasEllipsis) {
			b.append("...");
		}
		b.append(identifier);
		if (hasType) {
			b.append(":").append(typeRef.getTypeName());
		}
		if (hasAssignment) {
			b.append(" = ");
			appendAssignmentExpressionTitle(b);
		}
		return b.toString();
	}

	private void appendAssignmentExpressionTitle(StringBuilder b) {
		for (SerializableToken child : assignmentExpressions) {
			b.append(child.getText());
		}
	}

	public boolean hasAssigment() {
		return hasAssignment;
	}

	public AS3TypeRef getTypeRef() {
		return typeRef;
	}

	public String getIdentifier() {
		return identifier;
	}

	public boolean hasEllipsis() {
		return hasEllipsis;
	}

	/**
	 * 可変長引数であるという設定をする。
	 * @param hasEllipsis 
	 */
	public void setEllipsis(boolean hasEllipsis) {
		this.hasEllipsis = hasEllipsis;
	}
}
