/**
  *
  *                      OOAS Compiler
  *
  *       Copyright 2015, AIT Austrian Institute of Technology.
  * This code is based on the C# Version of the OOAS Compiler, which is
  * copyright 2015 by the Institute of Software Technology, Graz University
  * of Technology with portions copyright by the AIT Austrian Institute of
  * Technology. All rights reserved.
  *
  * SEE THE "LICENSE" FILE FOR THE TERMS UNDER WHICH THIS FILE IS PROVIDED.
  *
  * If you modify the file please update the list of contributors below to in-
  * clude your name. Please also stick to the coding convention of using TABs
  * to do the basic (block-level) indentation and spaces for anything after
  * that. (Enable the display of special chars and it should be pretty obvious
  * what this means.) Also, remove all trailing whitespace.
  *
  * Contributors:
  *               Willibald Krenn (AIT)
  *               Stephan Zimmerer (AIT)
  *               Markus Demetz (AIT)
  *               Christoph Czurda (AIT)
  *
  */


package org.momut.ooas.ast.identifiers;

import org.antlr.runtime.Token;
import org.momut.ooas.ast.AstNode;
import org.momut.ooas.ast.AstNodeTypeEnum;
import org.momut.ooas.ast.IAst;
import org.momut.ooas.ast.IAstVisitor;
import org.momut.ooas.ast.IScope;
import org.momut.ooas.ast.types.Type;
import org.momut.ooas.utils.exceptions.ArgumentException;
import org.momut.ooas.utils.exceptions.NotImplementedException;

/* ABSTRACT class Identifier.
 * */
public abstract class Identifier extends AstNode implements IAst, Comparable<Identifier>
{
	protected int m_line;
	protected int m_column;
	protected IScope m_definingScope;
	protected IdentifierKind m_identifierKind;
	protected String m_tokenText;
	protected Type m_Type;

	// basic attributes of an Identifier
	public final IdentifierKind kind() { return m_identifierKind; } // kind of identifier
	public final Type type() { return m_Type; }   // type of identifier
	public final IScope definingScope() { return m_definingScope; } // scope where it's defined

	// from lexer
	public final String tokenText() { return m_tokenText; }
	public final int line() { return m_line; }
	public final int column() { return m_column; }

	@Override
	public AstNodeTypeEnum nodeType() { return AstNodeTypeEnum.identifier; }


	public Identifier(Token aToken,
			Type aType,
			IdentifierKind aKind,
			IScope aDefiningScope)
	{
		m_tokenText = aToken.getText();
		m_line = aToken.getLine();
		m_column = aToken.getCharPositionInLine();
		m_Type = aType;
		m_identifierKind = aKind;
		m_definingScope = aDefiningScope;
	}

	public Identifier(String name, Type aType, IdentifierKind aKind, IScope aDefiningScope)
	{
		m_tokenText = name;
		m_line = 0;
		m_column = 0;
		m_Type = aType;
		m_identifierKind = aKind;
		m_definingScope = aDefiningScope;
	}

	public Identifier(Identifier toCopy)
	{
		m_tokenText = toCopy.m_tokenText;
		m_line = toCopy.m_line;
		m_column = toCopy.m_column;
		m_Type = toCopy.m_Type;
		m_identifierKind = toCopy.m_identifierKind;
		m_definingScope = toCopy.m_definingScope;
	}

	public /*virtual*/ Identifier Clone()
	{
		throw new NotImplementedException();
	}


	@Override
	public /*virtual*/ void Accept(IAstVisitor visitor)
	{
		throw new NotImplementedException();
	}

	public final void SetType(Type aType)
	{
		if (aType == null)
			throw new ArgumentException("New type can not be null.");

		m_Type = aType;
	}

	public final void SetTokenText(String aText)
	{
		m_tokenText = aText;
	}

	@Override
	public /*override*/ String toString()
	{
		return tokenText();
	}

	@Override
	public int compareTo(Identifier obj)
	{
		return tokenText().compareTo(obj.toString());
	}

	@Override
	public boolean equals(Object obj) {
		if (obj instanceof Identifier)
			return tokenText() == ((Identifier) obj).tokenText();
		else
			return false;
	}
}
