package edu.fiu.jtlex.data;

/**
 * Default implementation of {@code ILink}.
 * 
 * @author Pablo Maldonado
 */

public class Link implements ILink {

	private final int linkID;
	private final String syntax;
	private final INode eventInstance;  // mandatory, String for now, it may change to INode later
	private final ISignal signal;
	private final INode relatedToEvent; // mandatory, String for now, it may change to INode later
	private final Origintype orig;
	protected final LinkTag linktag;
	private final ILinkType relType;
	 
	/**
	 * This is the constructor for Tlink.
	 * 
	 * @param linkTag               linkTag is the type of Link: TLINK,SLINK, or
	 *                              ALINK
	 * @param linkID                Link ID gives each TimeML link an identification
	 *                              number
	 * @param syntax                syntax holds any syntactic pattern that was used
	 *                              in generating the link
	 * 
	 * @param eventInstanceOrTimeID Obligatory attribute (one or the other of these
	 *                              needs to be present). This is the ID of the
	 *                              eventInstance or the timeID involved in the
	 *                              temporal link.
	 * 
	 * @param signalID              Optional attribute. If the temporal relation
	 *                              holding between the entities is explicitly
	 *                              signaled in the text, then the ID of that signal
	 *                              needs to be supplied here.
	 * 
	 * @param relatedToEventOrTime  Obligatory attribute (one or the other of these
	 *                              needs to be present). This is the ID of the
	 *                              entity that is being related to the event
	 *                              instance with ID=eventInstanceID or time
	 *                              expression with ID=timeID.
	 * 
	 * @param relType               Obligatory attribute. This is the temporal
	 *                              relation holding between the entities.
	 * 
	 * @throws NullPointerException     if TLinkRelType argument is null
	 * 
	 * @throws IllegalArgumentException throw error if linktag != LinkTag.TLINK
	 */
	  
	 public Link(LinkTag linktag, int linkID, String syntax, INode eventInstance, ISignal signal, INode relatedToEvent,
			 ILinkType relType, Origintype orig) {

		if (linktag != LinkTag.TLINK) {
			String errorMessage = "Error: using wrong constructor, this is Tlink constructor)";
			throw new IllegalArgumentException(errorMessage);
		} else if (linktag == null) {
			throw new NullPointerException();
		}

		this.linktag = linktag; // this should ALWAYS be TLINK

		
		if (relType == null || eventInstance == null || relatedToEvent == null) {
			throw new NullPointerException();
		}

		this.linkID = linkID;
		this.syntax = syntax;
		this.eventInstance = eventInstance;
		this.signal = signal;
		this.relatedToEvent = relatedToEvent;
		this.relType = relType;
		this.orig = orig;


	}


	/**
	 * This is the constructor for Alink and SLink
	 * 
	 * @param linkTag                linkTag is the type of Link: TLINK,SLINK, or
	 *                               ALINK
	 * @param linkID                 Link ID gives each TimeML link an
	 *                               identification number
	 * @param syntax                 syntax holds any syntactic pattern that was
	 *                               used in generating the link
	 * 
	 * @param eventInstanceID        Obligatory attribute. This is the ID of the
	 *                               (aspectual) eventInstance involved in the
	 *                               aspectual link.
	 * 
	 * @param signalID               Optional attribute. If the aspectual relation
	 *                               holding between the events is explicitly
	 *                               signalled in the text, then the ID of that
	 *                               signal needs to be filled in here
	 * 
	 * @param relatedToEventInstance Obligatory attribute. This is the ID of the
	 *                               event instance related to the aspectual event.
	 * 
	 * @param relType                Obligatory attribute. This is the temporal
	 *                               relation holding between the entities for Alink
	 * 
	 * @throws NullPointerException     if ALinkRelType argument is null
	 * @throws IllegalArgumentException throw error if linktag == LinkTag.TLINK
	 */
	public Link(LinkTag linktag, int linkID, String syntax, INode eventInstance, ISignal signal, INode relatedToEvent,
			ILinkType relType) {
		if (linktag == LinkTag.TLINK) {
			String errorMessage = "Error: using wrong constructor, this is Alink or SLink constructor)";
			throw new IllegalArgumentException(errorMessage);
			
		} else if (linktag == null) {
			throw new NullPointerException();
		}
		this.linktag = linktag;// this should ALWAYS be SLINK or ALINK

		if (relType == null || eventInstance == null || relatedToEvent == null) {
			throw new NullPointerException();
		}

		this.linkID = linkID;
		this.syntax = syntax;
		this.eventInstance = eventInstance;
		this.signal = signal;
		this.relatedToEvent = relatedToEvent;
		this.relType = relType;

		// this variable is not used in Alink or Slink
		orig = null;
	
	}

	

	/*
	 * (non-Javadoc)
	 * 
	 * @see edu.fiu.jtlex.data.ILinkt#getLinkId()
	 */
	@Override
	public int getLinkID() {
		return linkID;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see edu.fiu.jtlex.data.ILinkt#getSyntax()
	 */
	@Override
	public String getSyntax() {
		return syntax;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see edu.fiu.jtlex.data.ILinkt#getEventInstance()
	 */
	@Override
	public INode getEventInstance() {
		return eventInstance;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see edu.fiu.jtlex.data.ILinkt#getSignalID()
	 */
	@Override
	public ISignal getSignal() {
		return signal;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see edu.fiu.jtlex.data.ILinkt#getOrigin()
	 */
	@Override
	public Origintype getOrigin() {
		if (linktag != LinkTag.TLINK) {
			String errorMessage = "Error: Origin only ussed in TLink)";
			throw new IllegalArgumentException(errorMessage);
		}
		return orig;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see edu.fiu.jtlex.data.ILinkt#getRelatedToEvent()
	 */
	@Override
	public INode getRelatedToEvent() {
		return relatedToEvent;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see edu.fiu.jtlex.data.ILinkt#getRelType()
	 */
	@Override
	public ILinkType getRelType() {
		return relType;
	}
	
	public int hashCode() {
		return (eventInstance.getIdStr() + relatedToEvent.getIdStr()).hashCode();
	}

}
