/*
 * Created on 26.10.2004 14:05:55
 *
 * Multimediale Algorithmen und Datenstrukturen Assessments
 */
package mauda.undoredo;

import java.util.Vector;
import java.util.Enumeration;
/**
 * Stores several UndoRedoElements as one unit. All this elements will be undoed or redoed
 * in one step.
 * 
 * @author Markus Krebs
 */
public class UndoRedoUnit {
	
	private Vector elements;
	
	/**
	 * Creates an UndoRedoUnit
	 */
	public UndoRedoUnit() {
		elements = new Vector();
	}
	
	/**
	 * Adds an UndoRedoElement to this UndoRedoUnit.
	 * @param ure UndoRedoElement to add
	 */
	public void addElement(UndoRedoElement ure) {
		elements.add(ure);
	}
	
	/**
	 * Returns all UndoRedoElements of this UndoRedoUnit
	 * @return UndoRedoElements.
	 */
	public Vector getElements() { return elements; }
	
	/**
	 * Performs this unit on the given object-vector
	 * @param v object-vector
	 */
	public void perform(Vector v) {
		int c = elements.size()-1;
		//for(int i=c; i>=0; i--) {
		for(int i=0; i<=c; i++) {
			UndoRedoElement unit = (UndoRedoElement)elements.elementAt(i);
			if(unit.getID() == UndoRedoElement.APPEND)
				v.insertElementAt(unit.getObj(), unit.getPos());
			else if(unit.getID() == UndoRedoElement.DELETE)
				v.removeElementAt(unit.getPos());
		}
	}
	/**
	 * Inverts this UndoRedoUnit. This means that all containing UndoRedoElements are
	 * inverted and the order of the UndoRedoElements will be reversed.
	 * @return inverted UndoRedoUnit
	 */
	public UndoRedoUnit invert() {
		UndoRedoUnit uru = new UndoRedoUnit();
		int c = elements.size()-1;
		for(int i=c; i>=0; i--) {
			UndoRedoElement element = (UndoRedoElement)elements.elementAt(i);
			uru.addElement(element.invert());
		}
		return uru;
	}
	// Position des höchsten APPEND zurückgeben.
	// Falls kein APPEND vorkommt, Position vor kleinstem DELETE zurückgeben
	/**
	 * Returns the maximum position of all APPEND-UndoRedoElements. If this UndoRedoUnit
	 * doesnt contain an APPEND-UndoRedoElement, than the minimum position minus 1 of all
	 * DELETE-UndoRedoElements will be returned.
	 * @return position
	 */
	public int getMaxAppendPos() {
		int maxpos = -1;
		int minpos = Integer.MAX_VALUE;
		Enumeration en = elements.elements();
		while(en.hasMoreElements()) {
			UndoRedoElement ure = (UndoRedoElement)en.nextElement();
			switch(ure.getID()) {
				case UndoRedoElement.APPEND :
					if(ure.getPos()>maxpos) maxpos = ure.getPos();
					break;
				case UndoRedoElement.DELETE :
					if(ure.getPos()<minpos) minpos = ure.getPos();
					break;
			}
		}
		if(maxpos == -1) return minpos-1;
		return maxpos;
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	public boolean equals(Object o) {
		UndoRedoUnit uru = (UndoRedoUnit)o;
		if(elements.equals(uru.getElements())) return true;
		return false;
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	public String toString() {
		String s = "  URUnit:\n";
		Enumeration en = elements.elements();
		while(en.hasMoreElements()) {
			s+="    "+en.nextElement()+"\n";
		}
		return s;
	}
}
