package ckelling.baukasten;

/**
 * Editor_Description.java
 *
 * Diese Datenstruktur enthaelt zusaetzliche Angaben zu jeder RechnerKomponente/RechnerKomponentePanel
 * die mit dem Editor angelegt wurde; Superklasse fuer alle Editor_Description...
 *
 **/
 
import java.awt.Point;

public class Editor_Description
{
	private   int					numberOfCoordinates;
	
	protected String 				label;
	private   String				componentType;
	private   String				grabMode;
	private		String				program;  // Fuer Komponenten vom Typ EditableMemory/TagMemory
	
	protected boolean[]				isConstantOnly;
	protected Editor_Source[]		source;
	protected String[]				sourceQualifier;
	protected int[]					constant;
	
	
	public Editor_Description(int numberOfCoordinates)
	{
		this.numberOfCoordinates = numberOfCoordinates;
		
		label = "unnamed";
		componentType = new String("");
		grabMode = new String("");
		program = "zero";
		
		isConstantOnly = new boolean[numberOfCoordinates];
		source = new Editor_Source[numberOfCoordinates];
		sourceQualifier = new String[numberOfCoordinates];
		constant = new int[numberOfCoordinates];
		
		for (int i = 0; i < numberOfCoordinates; i++)
		{
			isConstantOnly[i] = true;
			source[i] = null;
			sourceQualifier[i] = new String("");
			constant[i] = 0;
		}
	}
	
	public int getNumberOfCoordinates()
	{
		return numberOfCoordinates;
	}

	
	public void setLabel(String name)
	{
		label = name;
	}
	
	public String getLabel()
	{
		return label;
	}
	
	public void setProgram(String prg)
	{
		program = prg;
	}
	
	public String getProgram()
	{
		return program;
	}
	
	public void setComponentType(String str)
	{
		componentType = str;
	}
	
	public String getComponentType()
	{
		return componentType;
	}
	
	public void setGrabMode(String str)
	{
		grabMode = str;
	}
	
	public String getGrabMode()
	{
		return grabMode;
	}
	
	
	public void setCoord (int which, int constant)
	{
		if (which < numberOfCoordinates)
		{
			isConstantOnly[which] = true;
			this.constant[which] = constant;
		}
	}
	
	public void setCoord (int which, Editor_Source source, String qualifier)
	{
		setCoord(which, source, qualifier, 0);
	}
	
	public void setCoord (int which, Editor_Source source, String qualifier, int constant)
	{
		if (which < numberOfCoordinates)
		{
			isConstantOnly[which] = false;
			this.source[which] = source;
			if (qualifier != null)
				this.sourceQualifier[which] = qualifier;
			else
				this.sourceQualifier[which] = new String("");
			this.constant[which] = constant;
		}
	}
	
	public boolean isConstantOnly(int which)
	{
		if (which < numberOfCoordinates)
			return isConstantOnly[which];
		else
			return true;
	}
	
	public boolean areConstantsOnly()
	{
		for (int i = 0; i < numberOfCoordinates; i++)
			if (! isConstantOnly(i))
				return false;
				
		return true;		
	}
	
	public int getOffset(int which)
	{
		if (which < numberOfCoordinates)
			return constant[which];
		else
			return 0;
	}
	
	public Editor_Source getSource(int which)
	{
		if (which < numberOfCoordinates)
			return source[which];
		else
			return null;
	}
	
	public String getQualifier(int which)
	{
		if (which < numberOfCoordinates)
			return sourceQualifier[which];
		else
			return new String("");
	}
	
	
	public boolean usesAsSource(Editor_Source changedComponent)
	{
		for (int i = 0; i < numberOfCoordinates; i++)
		{
			if ((source[i] != null) && source[i].equals(changedComponent))
				return true;
		}
				
		return false;
	}
	
	public void changeReferences(Editor_Source oldComponent, Editor_Source newComponent, String deletedEdge)
	{
		if (newComponent != null)
		// eine Komponente hat sich geaendert, alle Verweise mitaendern
		{
			for (int i = 0; i < numberOfCoordinates; i++)
			{
				if ((source[i] != null) && source[i].equals(oldComponent))
					source[i] = newComponent;
			}
		}
		else
		// eine Komponente ist geloescht worden,
		// alle Verweise auf diese muessen in konstante Werte umgewandelt werden
		{
			for (int i = 0; i < numberOfCoordinates; i++)
			{
				if ((source[i] != null) && source[i].equals(oldComponent))
				{
					if ( (source[i].getRK() instanceof SimpleBus) && (! deletedEdge.equals("")) )
					// Sonderfall: Bei einem Bus kann auch nur eine Kante geloescht worden sein
					{
						if (sourceQualifier[i].equals(deletedEdge))
							setCoord(i, evaluate(i));
					}
					else
						setCoord(i, evaluate(i));
				}
			}
		}
	}
	
	
	
//// Haeufig benoetigte Abkuerzungen ////


//// Instanzname ////
	public void setInstanceName(String name)
	{
		setLabel(name);
	}
	
	public String getInstanceName()
	{
		return getLabel();
	}
	
	public int evaluate(int which)
	{
		if (which < numberOfCoordinates)
		{
			if (which == 0)
				return evaluateX();
			else if (which == 1)
				return evaluateY();
			else if (which == 2)
				return evaluateWidth();
			else if (which == 3)
				return evaluateHeight();
			else
				return 0;
		}
		else
			return 0;
	}
	
	
//// X-Koordinate ////
	public void setX (int constant)
	{
		setCoord(0, constant);
	}
	
	public void setX (Editor_Source source, String qualifier)
	{
		setCoord(0, source, qualifier, 0);
	}
	
	public void setX (Editor_Source source, String qualifier, int constant)
	{
		setCoord(0, source, qualifier, constant);
	}
	
	public boolean isConstantOnlyX()
	{
		return isConstantOnly(0);
	}
	
	public int evaluateX()
	{
		if (isConstantOnly(0) || (source[0] == null))  // Komponente hat feste X-Koordinate
			return getOffset(0);
		else  // X-Koordinate haengt von anderer Komponente ab; diese muss nun ihre
		      // X-Koordinate berechnen.
		{
			if (contains(source[0].getPossibleQualifiers(), sourceQualifier[0]))
			{
				Point p = source[0].getCoordinates(sourceQualifier[0]);
				return p.x + constant[0];
			}
			else
				return getOffset(0);
		}
	}
	
	public int getOffsetX()
	{
		return getOffset(0);
	}
	
	public Editor_Source getSourceX()
	{
		return getSource(0);
	}

	public String getQualifierX()
	{
		return getQualifier(0);
	}

	
//// Y-Koordinate ////
	public void setY (int constant)
	{
		setCoord(1, constant);
	}
	
	public void setY (Editor_Source source, String qualifier)
	{
		setCoord(1, source, qualifier, 0);
	}
	
	public void setY (Editor_Source source, String qualifier, int constant)
	{
		setCoord(1, source, qualifier, constant);
	}
	
	public boolean isConstantOnlyY()
	{
		return isConstantOnly(1);
	}
	
	public int evaluateY()
	{
		if (isConstantOnly(1) || (source[1] == null))
			return getOffset(1);
		else
		{
			if (contains(source[1].getPossibleQualifiers(), sourceQualifier[1]))
			{
				Point p = source[1].getCoordinates(sourceQualifier[1]);
				return p.y + constant[1];
			}
			else
				return getOffset(1);
		}
	}
	
	public int getOffsetY()
	{
		return getOffset(1);
	}
	
	public Editor_Source getSourceY()
	{
		return getSource(1);
	}

	public String getQualifierY()
	{
		return getQualifier(1);
	}

	
//// Breite ////
	public void setWidth (int constant)
	{
		setCoord(2, constant);
	}
	
	public void setWidth (Editor_Source source, String qualifier)
	{
		setCoord(2, source, qualifier, 0);
	}
	
	public void setWidth (Editor_Source source, String qualifier, int constant)
	{
		setCoord(2, source, qualifier, constant);
	}
	
	public boolean isConstantOnlyWidth()
	{
		return isConstantOnly(2);
	}
	
	public int evaluateWidth()
	{
		if (isConstantOnly(2) || (source[2] == null))
			return getOffset(2);
		else
		{
			if (contains(source[2].getPossibleQualifiers(), sourceQualifier[2]))
			{
				Point p = source[2].getCoordinates(sourceQualifier[2]);
				return p.x - evaluateX() + constant[2];
			}
			else
				return getOffset(2);
		}
	}
	
	public int getOffsetWidth()
	{
		return getOffset(2);
	}
	
	public Editor_Source getSourceWidth()
	{
		return getSource(2);
	}

	public String getQualifierWidth()
	{
		return getQualifier(2);
	}

	
//// Hoehe ////
	public void setHeight (int constant)
	{
		setCoord(3, constant);
	}
	
	public void setHeight (Editor_Source source, String qualifier)
	{
		setCoord(3, source, qualifier, 0);
	}
	
	public void setHeight (Editor_Source source, String qualifier, int constant)
	{
		setCoord(3, source, qualifier, constant);
	}
	
	public boolean isConstantOnlyHeight()
	{
		return isConstantOnly(3);
	}
	
	public int evaluateHeight()
	{
		if (isConstantOnly(3) || (source[3] == null))
			return getOffset(3);
		else
		{
			if (contains(source[3].getPossibleQualifiers(), sourceQualifier[3]))
			{
				Point p = source[3].getCoordinates(sourceQualifier[3]);
				return p.y - evaluateY() + constant[3];
			}
			else
				return getOffset(3);
		}
	}
	
	public int getOffsetHeight()
	{
		return getOffset(3);
	}
	
	public Editor_Source getSourceHeight()
	{
		return getSource(3);
	}
	
	public String getQualifierHeight()
	{
		return getQualifier(3);
	}


	private boolean contains(String[] container, String content)
	{
		for (int i = 0; i < container.length; i++)
			if (container[i].equals(content))
				return true;
				
		return false;		
	} /* end contains */

} /* end Editor_Description */
