package de.unidortmund.dependencies;

import java.util.*;

public class Memory {

	private static Vector<Slot> slotsAtLevel1 = new Vector<Slot>();
	private static Vector<Slot> slotsAtLevel2 = new Vector<Slot>();
	private static Vector<Slot> slotsAtLevel3 = new Vector<Slot>();

	public static void registerSlot(Slot slot) {
		switch (slot.getLevel()) {
		case 1:
			addSlotToMemory(slotsAtLevel1, slot);
			break;
		case 2:
			addSlotToMemory(slotsAtLevel2, slot);
			break;
		case 3:
			addSlotToMemory(slotsAtLevel3, slot);
			break;
		default:
			assert false;	
		}
	}
	
	private static void addSlotToMemory(Vector<Slot> slots, Slot slot) {
		slots.add(slot);
		slot.setIndex(slots.indexOf(slot));
	}
	
	// Braucht man das für level ungleich 2?
	public static Slot getSlot(int level, int index) {
		switch (level) {
		case 1:
			return slotsAtLevel1.elementAt(index);
		case 2:
			return slotsAtLevel2.elementAt(index);
		case 3:
			return slotsAtLevel3.elementAt(index);
		default:
			assert false;
			return null;
		}	
	}
	
	private static void mij(Variable v1, Variable v2, int i, int j) {
		Slot rightSlot = v2.getFirstSlotAtLevel(j);
		Content right =  rightSlot.getContent(); 
		Slot left =  v1.getFirstSlotAtLevel(i);
		left.setContent(right);	
		left.setNumberOfElements(rightSlot.getNumberOfElements());
	}
	
	public static void m33(Variable v1, Variable v2)  {
		mij(v1, v2,3,3);
	}

	public static void m22(Variable v1, Variable v2)  {
		mij(v1,v2, 2, 2);
	}

	public static void m23(Variable v1, Variable v2)  {
		mij(v1,v2, 2, 3);
	}
	
	public static void m11(Variable v1, Variable v2) {
		if (!v1.isComposite()) {
			assert !v2.isComposite();
			mij(v1, v2, 1, 1);
		} else {
			assert v2.isComposite();
			Variable[] variables1 = v1.getAllIndexVariables();
			Variable[] variables2 = v2.getAllIndexVariables();
			assert variables1.length == variables2.length;
			for (int i = 0; i < variables1.length; i ++ ) {
				m22(variables1[i], variables2[i]);
			}
		}
	}

	public static void clear() {
		slotsAtLevel1 = new Vector<Slot>();
		slotsAtLevel2 = new Vector<Slot>();
		slotsAtLevel3 = new Vector<Slot>();
	}

}
