package kr.miditunemodel;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import kr.miditunemodel.MidiTuneModel.MessageType;
import kr.undo.Operation;
import kr.undo.Transaction;

/**
 * A Transaction of operations involving midi events
 */
public class MidiTransaction<T extends Event> extends Transaction
{
	private boolean containsLastEvent = false;
	protected EventGroup eventGroup;

	public MidiTransaction(EventGroup eventGroup)
	{
		this.eventGroup = eventGroup;
	}
	
	public void add(MidiOperation op)
	{
		super.add(op);
		if(op.getEvent().isTail()) containsLastEvent = true;
	}
	
	public void undo()
	{
		super.undo();
		if(!isValid()) 
			throw new IllegalStateException("uhoh");
		eventGroup.notifyChanged(containsLastEvent);
	}
	
	/**
	 * @return true if sucessful, false otherwise
	 */
	public boolean doIt()
	{
		//if we failed to perform the action 
		//revert it and do not notify the listeners
		if(super.doIt())
		{
			eventGroup.notifyChanged(containsLastEvent);
			return true;
		}
		return false;
	}

	protected Collection<T> getEvents() {
		List<T> events = new ArrayList<T>();
		
		for(Iterator<Operation> i = getOperations().iterator(); i.hasNext(); )
		{
			MidiOperation<T> mo = (MidiOperation<T>) i.next();
			events.add(mo.getEvent());
		}
		
		return events;
	}

	@Override
	protected boolean isValid() {
		return true;
	}

}
