package edu.fiu.jtlex.data;

import java.util.HashSet;
import java.util.Set;

import edu.fiu.jtlex.data.IEvent.EventClass;

/**
 * Default implementation of {@code IMakeInstance}.
 * 
 * @author arada002
 */

public class Instance implements IInstance {
	
	private final int eventInstanceID;
	private final IEvent event;
	private final Tense tense;
	private final Aspect aspect;
	private final Pos pos;
	private final Polarity polarity;
	private final String modality;
	private final ISignal signal;
	private final String cardinality; 

	private Set<ILink> inLinks; // Set of links that have this node as a target.
	private Set<ILink> outLinks; // Set of links that have this node as an origin.


	/**
	 * Creates a new event Instance object. 
	 * @param eventInstanceID	a unique ID number 
	 * 							may not be less than 1
	 * @param event				the even to which event instance is related 
	 * @param tense				phrase tense
	 * 							may not be <code>null</code>
	 * @param aspect			phrase aspect
	 * 							may not be <code>null</code>
	 * @param pos				part of speech, syntactic category of phrase 
	 * 							may not be <code>null</code>
	 * @param polarity			indicates whether the eventInstance phrase is negated
	 * 							may not be <code>null</code>
	 * @param modality			modal word that modifies the instance	
	 * 							may be <code>null</code>
	 * @param signal			the signal object, present if multiple event instances are created
	 * 							<code>null</code> if not defined
	 * 							may not be less than 0
	 * @param cardinality		only present if there is a signal that provides its value
	 * 							0 if not defined 
	 * 							may not be less than 0
	 * 
	 */
	public Instance(int eventInstanceID, IEvent event, Tense tense, Aspect aspect, Pos pos,
			Polarity polarity, String modality, ISignal signal, String cardinality) {
		
		if (eventInstanceID < 1) {
			throw new IllegalArgumentException("Event instance ID can not be less than 1.");
		}


		if (event == null) {
			throw new NullPointerException("Event can not be null");
		}

		if(tense == null) {
			throw new NullPointerException("Tense has to be defined.");
		}
		
		if(aspect == null) {
			throw new NullPointerException("Aspect has to be defined.");
		}
		
		if(pos == null) {
			throw new NullPointerException("Part of speech has to be defined.");
		}
		
		if(polarity == null) {
			throw new NullPointerException("Polarity has to be defined.");
		}
		
		if (modality != null) {
			modality = modality.trim();
			if (modality.length() == 0) {
				throw new IllegalArgumentException("Modality can not be empty string or "
						+ "all whitespace");
			}
		}
		
		this.eventInstanceID = eventInstanceID;
		this.event = event;
		this.tense = tense;
		this.aspect = aspect;
		this.pos = pos;
		this.polarity = polarity;
		this.modality = modality;
		this.signal = signal;
		this.cardinality = cardinality;
		
		this.inLinks = new HashSet<>();
		this.outLinks = new HashSet<>();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see edu.fiu.jtlex.data.IInstance#getEventInstanceID()
	 */
	public int getId() {
		return eventInstanceID;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see edu.fiu.jtlex.data.IInstance#getEventId()
	 */
	public IEvent getEvent() {
		
		return event;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see edu.fiu.jtlex.data.IInstance#getTense()
	 */
	public Tense getTense() {
		return tense;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see edu.fiu.jtlex.data.IInstance#getAspect()
	 */
	public Aspect getAspect() {
		return aspect;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see edu.fiu.jtlex.data.IInstance#getPos()
	 */
	public Pos getPos() {
		return pos;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see edu.fiu.jtlex.data.IInstance#getModality()
	 */
	public String getModality() {
		return modality;
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see edu.fiu.jtlex.data.IInstance#getPolarity()
	 */
	public Polarity getPolarity() {
		return polarity;
	}

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

	/*
	 * (non-Javadoc)
	 * 
	 * @see edu.fiu.jtlex.data.IInstance#getCardinality()
	 */
	public String getCardinality() {
		return cardinality;
	}
	/*
	 * (non-Javadoc)
	 * 
	 * @see edu.fiu.jtlex.data.IInstance#getType()
	 */
	public EventClass getType() {
		return this.getEvent().getEventClass();
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see edu.fiu.jtlex.data.IInstance#getIdStr()
	 */
	public String getIdStr() {
		return "eiid" + eventInstanceID; 
	}
	
	/**
	 * 
	 */
	public void addOutLink(ILink link){
		outLinks.add(link);
	}
	
	public void addInLink(ILink link){
		inLinks.add(link);
	}
	

	public Set<ILink> getOutLinks() {
		return outLinks;
	}
	
	public Set<ILink> getInLinks() {
		return inLinks;
	}

	
	public void removeOutLink(ILink link) {
		outLinks.remove(link);
	}

	
	public void removeInLink(ILink link) {
		inLinks.remove(link);
		
	}
	
}

