/*******************************************************************************
 * Copyright (c) 2004-2010 Abel Hegedus and Daniel Varro
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Abel Hegedus - initial API and implementation
 *******************************************************************************/
package org.eclipse.viatra2.core.tracebased.tracetree;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.viatra2.core.IModelSpace;
import org.eclipse.viatra2.core.notification.ICoreNotificationObject;
import org.eclipse.viatra2.core.tracebased.TraceException;
import org.eclipse.viatra2.core.tracebased.TraceModelSpace;
import org.eclipse.viatra2.core.tracebased.TraceNotificationManager;
import org.eclipse.viatra2.core.tracebased.TraceTreeManager;
import org.eclipse.viatra2.framework.IFramework;

/**
 * @author Abel Hegedus
 *
 */
public class CompositeTraceTreeNode extends AbstractTraceTreeNode {

	private List<ICoreNotificationObject> events;
	
	/**
	 * @param parent
	 * @param id
	 * @param startEvent
	 */
	public CompositeTraceTreeNode(ITraceTreeNode parent, String id, ICoreNotificationObject startEvent) {
		super(parent, id);
		events = new ArrayList<ICoreNotificationObject>();
		events.add(startEvent);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.viatra2.trace.trace.ITraceTreeNode#doExecute(org.eclipse.viatra2.framework.IFramework)
	 */
	@Override
	public void doExecute(IFramework framework) throws TraceException {
		IModelSpace ms = framework.getTopmodel();
		if(ms instanceof TraceModelSpace){
			// get trace tree manager
			TraceTreeManager ttm = ((TraceModelSpace) ms).getTraceManager();
			if(events.size() > 0){
				// notifications are not registered
				((TraceNotificationManager)ms.getNotificationManager()).setEnabled(false);
				ms.getTransactionManager().beginTransaction(Boolean.TRUE);
				// execute events one-by-one
				try{
					for (ICoreNotificationObject event : events) {
						ttm.getTraceProcessor().doExecuteEvent(event);
					}
					((TraceNotificationManager)ms.getNotificationManager()).setEnabled(true);
				} catch (TraceException e) {
					((TraceNotificationManager)ms.getNotificationManager()).setEnabled(true);
					throw e;
				}
				ms.getTransactionManager().commitTransaction();
				
			}
			// update current node of trace tree manager
			ttm.setCurrent(this);
		} else {
			throw (TraceException) new TraceException("doExecute not possible, model-space is not trace-based!").fillInStackTrace();
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.viatra2.trace.trace.ITraceTreeNode#undo(org.eclipse.viatra2.framework.IFramework)
	 */
	@Override
	public void undo(IFramework framework) throws TraceException {
		IModelSpace ms = framework.getTopmodel();
		if(ms instanceof TraceModelSpace){
			// get trace tree manager
			TraceTreeManager ttm = ((TraceModelSpace) ms).getTraceManager();
			if(events.size() > 0){
				// undo all events one-by-one (in reverse order)
//				List<ICoreNotificationObject> reversedEventList = new ArrayList<ICoreNotificationObject>(events);
//				Collections.reverse(reversedEventList);
//				for (ICoreNotificationObject event : reversedEventList) {
//					ttm.getTraceProcessor().undoEvent(event);
//				}
				for(int i = events.size()-1; i >= 0; i--){
					ttm.getTraceProcessor().undoEvent(events.get(i));
				}
			}
			// update current node in trace tree (except if TraceException was thrown during the undo of an event)
			ttm.setCurrent(getParent());
		} else {
			throw (TraceException) new TraceException("Undo not possible, model-space is not trace-based!").fillInStackTrace();
		}
	}

	/**
	 * @return the events
	 */
	public List<ICoreNotificationObject> getEvents() {
		return events;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.viatra2.trace.trace.AbstractTraceTreeNode#toString()
	 */
	@Override
	public String toString() {
		String superString = super.toString();
		StringBuilder sb = new StringBuilder();
		sb.append(superString);
		if(events.isEmpty()){
			sb.append("; No events");
		} else {
			int i = 0;
			sb.append("; Events (").append(events.size()).append(")");
			for (ICoreNotificationObject event : events) {
				sb.append(" ").append(i).append(": ");
				sb.append(event.toString());
				i++;
			}
		}
		return sb.toString();
	}
}
