/*
 * Created on 01.02.2004 18:43:21
 *
 * Multimediale Algorithmen und Datenstrukturen Assessments
 */
package mauda.plugin.fibheap;

import mauda.*;
import mauda.plugin.*;
import mauda.undoredo.UndoRedo;

import java.util.*;
/**
 * Evaluates special constants in formulas in the Knowledge-
 * Base.
 * 
 * @author Markus Krebs
 */
public class FibHeapKBFormulaEvaluator extends KBFormulaEvaluator {

	/**
	 * Creates a FibHeap-Knowledge-Base Formual Evaluator
	 * @param exercise
	 */
	public FibHeapKBFormulaEvaluator(Exercise exercise) {
		super(exercise);
	}
	/* (non-Javadoc)
	 * @see mauda.plugin.KBFormulaEvaluator#getSpecialConstant(java.lang.String)
	 */
	public String getSpecialConstant(String sc) {
		StringTokenizer st = new StringTokenizer(sc, ".");
		String[] tokens = new String[st.countTokens()];
		int counter=0;
		while(st.hasMoreTokens()) tokens[counter++] = st.nextToken();
		
		UndoRedo ur = exercise.getUndoRedo();
		String filledConstant = "";
		int i=0;
		String token = tokens[i];
		if(token.matches("\\d+\\[\\d+\\]")) {
			int nodenr = Integer.parseInt(token.substring(0,token.indexOf("[")));
			int offset = getPositionNr(0,token);
			Object dsObject = ur.getEntry(offset);
			FibHeapExt fibHeap = (FibHeapExt)dsObject;
			FibNode[] fibNodes = fibHeap.getAllNodes();
			
			while(true) {
				i++;
				if(i>=tokens.length) return nodenr+"";
				String command = tokens[i].toLowerCase();
				FibNode node = fibNodes[nodenr];
				//System.out.println("FibNode["+nodenr+"]="+node);
				if(node == null) return null;
				if(command.equals("pre")) {
					offset--; if(offset<0) return null;
					dsObject = ur.getEntry(offset);
					fibHeap = (FibHeapExt)dsObject;
					fibNodes = fibHeap.getAllNodes();
				} else if(command.equals("parent")) {
					if(node.isRoot()) return null;
					nodenr = node.parent.getKey();
				} else if(command.equals("child")) {
					// ACHTUNG: es gibt mehrere Kinder. Hier wird nur 1 zurückgegeben
					if(node.getRank()==0) return null;
					nodenr = node.child.getKey();
				} else if(command.equals("left")) {
					if(node.getSibling() == node) return null;
					nodenr = node.left.getKey();
				} else if(command.equals("right")) {
					if(node.getSibling() == node) return null;
					nodenr = node.right.getKey();
				} else if(command.equals("ismarked")) {
					if(node.isMarked()) return "TRUE";
					else return "FALSE";
				// Folgendes wird nicht benötigt, da sowieso der key zurückgegeben wird
				//} else if(command.equals("key")) {
				//	return nodenr+"";
				} else if(command.equals("rank")) {
					return node.getRank()+"";
				} else if(command.equals("isroot")) {
					if(node.isRoot()) return "TRUE";
					else return "FALSE";
				}
			}
		} else if(token.equals("min")) {
			Object dsObject = ur.getDSObject();
			FibHeapExt fibHeap = (FibHeapExt)dsObject;
			FibNode[] fibNodes = fibHeap.getAllNodes();
			int j=0;
			while(j<fibNodes.length&&fibNodes[j]==null) j++;
			//System.out.println("MIN = "+j);
			return j+"";
		}
		return sc;
	}
}
