/*
 * Created on 14.11.2003 18:40:31
 *
 * Multimediale Algorithmen und Datenstrukturen Assessments
 */
package mauda.plugin.fibheap;

/**
 * Extends the FibHeapDS-class by fast direct access to nodes.
 * 
 * @author Markus Krebs
 */
public class FibHeapDSExt extends FibHeapDS implements FibHeapOperations,
											FibHeapSubOperations {

	private static final int maxKey = 100;

	public FibNodeDS[] nodes = new FibNodeDS[maxKey];
	
	public FibHeapDSExt() {
		// Nothing to do
	}

	// === Operations ==========================================
	/*
	public FibNodeDS insert(int k) {
		if(nodes[k]!=null) return null;	// Doppelte Schlüssel vermeiden
		nodes[k] = super.insert(k);
		return nodes[k];
	}*/
	public void insertOp(int k) {
		if(nodes[k]!=null) return;	// Doppelte Schlüssel vermeiden
		nodes[k] = super.insert(k);
	}
	public int deleteminOp() {
		if(isEmpty()) return -1;
		
		int k = super.deletemin();
		nodes[k] = null;
		return k;
	}
	public void decreasekeyOp(int key, int k) {
		if(nodes[key]==null) return;
		
		if(nodes[k]!=null) return;	// Doppelte Schlüssel vermeiden
		decreasekey(nodes[key], k);
		nodes[k] = nodes[key];
		nodes[key] = null;
	}
	public int deleteOp(int key) {
		if(nodes[key]==null) return -1;

		delete(nodes[key]);
		nodes[key] = null;
		return key;
	}

	// === SubOperations =======================================
	public void setKeyOp(int node, int key) {
		if(nodes[key]!=null) return;	// Doppelte Schlüssel vermeiden
		nodes[node].setKey(key);		
		FibNodeDS temp = nodes[node];
		nodes[node] = null;
		nodes[key] = temp;
		//if(scheduler!=null) Jedas.updateDisplay();
	}
	public void cutOp(int node) {
		nodes[node].cut(min.getRoot());
		//if(scheduler!=null) scheduler.start();
	}
	public void markOp(int node) {
		nodes[node].mark();
		//if(scheduler!=null) scheduler.start();
	}
	public void unmarkOp(int node) {
		nodes[node].unmark();
		//if(scheduler!=null) scheduler.start();
	}
	public void linkOp(int node1, int node2) {
		nodes[node1].getRoot().addChild(nodes[node2].getRoot());
		//if(scheduler!=null) scheduler.start();
	}
	public void updateMinOp(int node) {
		updateMin(nodes[node]);
		// Scheduler wird bereits in updateMin gestartet
	}
	public void newFHeapMeldOp(int node) {
		if(nodes[node]!=null) return;
		//insertOp(node);	// nicht verwendbar da updateMin
		FibHeapDS q = new FibHeapDS(node);
		nodes[node] = q.min;
		/*if(scheduler!=null) {
			//System.out.println("Insert " + q.min.getKey()); // debug
			transferItem(q.min);
			DPair pos;
			if (isEmpty()) {
				pos = initialNodePos;
			} else {
				pos = new DPair(min.getPos().get(0) +
								min.getTreeWidth()*FibNode.DISTANCE,
								nodePosY-FibNode.DISTANCE);
			}
			q.min.setPos(pos);
			q.min.fPos = pos;
			q.min.appear();
			if (!isEmpty()) {
				min.makeRoomFor(q.min);
			}
			if (!quickAnim)
				animate();
		}
		if(scheduler!=null) {
			if (textMode > 2)
				showText("Merging F-heaps",1);
		}*/
		
		if (!this.isEmpty() && !q.isEmpty()) {
			this.min.getRoot().join(q.min, false);
		} else {
			// Bei leerem Heap muss auf jeden Fall das Minimum
			// gesetzt werden, da nachfolgende Inserts sonst
			// nicht funktionieren würden!!!
			if (this.isEmpty()) updateMin(q.min);			
		}

		this.size += q.getHeapSize();
		this.potential += q.potential;
		count++;	// cost = 1 unit

		// this.transferItem();	Transfer ALL root nodes of other!!!!!!!

		//if(scheduler!=null) animate();
	}
	public void removeOp(int node) {
		if(nodes[node].isRoot()) {
			remove(nodes[node]);
			nodes[node] = null;
		} else {
			// Delete ausführen, aber keine SubOperationen vermerken
			mauda.operation.SubOperationQueue soq = 
				(mauda.operation.SubOperationQueue)FibHeapDS.subOperations.clone();
			deleteOp(node);
			FibHeapDS.subOperations = soq;
		}
	}
	

	// Alle Knoten des FHs zurückgeben
	public FibNodeDS[] getAllNodes() {
		return nodes;
	}

	// Kopieren
	public Object clone() {
		FibHeapDSExt fibHeapCopy = (FibHeapDSExt)super.clone();
		for(int i=0; i<maxKey; i++) {
			if(nodes[i]!=null) fibHeapCopy.nodes[i] = (FibNodeDS)fibNodes.get(nodes[i]);
		}
		return fibHeapCopy;
	}

}
