package ckelling.baukasten;

import java.awt.*;
import java.lang.*;
import java.util.*;


/**
 *	Ellipse mit
 *  beliebig vielen Zeilen Text als Symbol für
 *  "sonstige" Komponenten
 *
 *	@author		Carsten Kelling
 *	@version	0.2.0, 27.02.97
 */
public class Misc extends RechnerKomponente
{
    public final static int	DEFAULT_WIDTH	= 30;
    public final static int	DEFAULT_HEIGHT	= 40;
	private int			WIDTH;
	private int			HEIGHT;

	private String		label[];
	private Point		labelCoord[];
	private Point		start;
	private Point		leftPort;
	private Point		rightPort;
	private String		grabMode;

	private boolean		hasBeenActivated;
	private boolean		activatedAtLastPaint;

	private Rechner		parent;


	/**
	 *  Erzeugt eine "sonstige" Komponente mit Standardbreite- und höhe.
	 *
	 *  @param str1[] mehrzeiliger Titel der "sonstigen" Komponente
	 *  @param str2 Bestimmt, auf welchen Punkt der Komponente sich (x1, y1) bezieht.
	 *  @see #getPossibleQualifiers
	 */
	public Misc(String str1[], int x1, int y1, String str2, Rechner par)
	{
		this(str1, x1, y1, DEFAULT_WIDTH, DEFAULT_HEIGHT, str2, par);
	}

	/**
	 *  @param str1[] mehrzeiliger Titel der "sonstigen" Komponente
	 *  @param str2 Bestimmt, auf welchen Punkt der Komponente sich (x1, y1) bezieht.
	 *  @see #getPossibleQualifiers
	 */
	public Misc(String str1[], int x1, int y1, int width, int height, String str2, Rechner par)
	{
		parent = par;
		label = str1;
		if (label == null)
		{
			label = new String[1];
			label[0] = new String("");
		}

		reshape(x1, y1, width, height, str2);

		activated = false;
		hasBeenActivated = false;
		activatedAtLastPaint = !activated;
	} /* end Misc */


	public void paint(Graphics g)
	{
		activatedAtLastPaint = activated;

		// Hintergrund loeschen
		g.setColor(parent.BACKGROUND);
		g.fillRect(start.x, start.y, WIDTH, HEIGHT);

		if (activated == true)
			g.setColor(parent.REG_COLOR_ACTIVATED);
		else
			g.setColor(parent.REG_COLOR);

		g.drawOval(start.x    , start.y    , WIDTH-2, HEIGHT-2);
		g.drawOval(start.x + 1, start.y    , WIDTH-2, HEIGHT-2);
		g.drawOval(start.x    , start.y + 1, WIDTH-2, HEIGHT-2);

		g.setColor(Color.black);
		g.setFont(parent.DIALOGFONT);

		for (int i = 0; i < label.length; i++)
			g.drawString(label[i], labelCoord[i].x, labelCoord[i].y);
	} /* end paint */


	/**
	 *  Zeichnet die Komponente
	 *  genau einmal, wenn sie aktiviert wurde sowie ebenfalls
	 *  genau einmal, wenn sie deaktiviert wurde.
	 *
	 *  @see #activate
	 *  @see #deactivate
	 */
	public void paintActivated(Graphics g)
	{
		if (activated && !activatedAtLastPaint)
			paint(g);
		else if (!activated && hasBeenActivated)
		{
			hasBeenActivated = false;
			paint(g);
		}
	} /* end paintActivated */


	public void reshape(int x, int y, int width, int height)
	{
		reshape(x, y, width, height, grabMode);
	}

	/**
	 *  @param newGrabMode Bestimmt, auf welchen Punkt der Komponente sich (x, y) bezieht
	 *  @see #getPossibleQualifiers
	 */
	public void reshape(int x, int y, int width, int height, String newGrabMode)
	{
		WIDTH = width; HEIGHT = height;
		setCoordinates(x, y, newGrabMode);
	}

	/**
	 *  Verschiebt die Komponente an den Punkt (x1, y1);
	 *  (x1, y1) muß dabei nicht notwendigerweise von der linken, oberen
	 *  Ecke der Komponente eingenommen werden, sondern kann z.B. auch von der Mitte
	 *  ihres rechten Randes oder dem Ausgang (bei einer ALU) eingenommen werden.
	 *
	 *  @param newGrabMode Bestimmt, auf welchen Punkt der Komponente sich (x1, y1) bezieht.
	 *  @see #getPossibleQualifiers
	 *  @see #getCoordinates
	 */
	public void setCoordinates(int x1, int y1, String newGrabMode)
	{
		grabMode = newGrabMode;

		if (newGrabMode.equalsIgnoreCase("left"))
		{
			leftPort = new Point(x1, y1);
			rightPort = new Point(x1 + WIDTH, y1);
			start = new Point(x1, y1 - HEIGHT/2);
		}
		else if (newGrabMode.equalsIgnoreCase("right"))
		{
			leftPort = new Point(x1 - WIDTH, y1);
			rightPort = new Point(x1, y1);
			start = new Point(x1 - WIDTH, y1 - HEIGHT/2);
		}
		else if (newGrabMode.equalsIgnoreCase("top"))
		{
			leftPort = new Point(x1 - WIDTH/2, y1 + HEIGHT/2);
			rightPort = new Point(x1 + WIDTH/2, y1 + HEIGHT/2);
			start = new Point(x1 - WIDTH/2, y1);
		}
		else if (newGrabMode.equalsIgnoreCase("bottom"))
		{
			leftPort = new Point(x1 - WIDTH/2, y1 - HEIGHT/2);
			rightPort = new Point(x1 + WIDTH/2, y1 - HEIGHT/2);
			start = new Point(x1 - WIDTH/2, y1 - HEIGHT);
		}
		else  // "leftTop"
		{
			leftPort = new Point(x1, y1 + HEIGHT/2);
			rightPort = new Point(x1 + WIDTH, y1);
			start = new Point(x1, y1);
		}

		setLabelCoordinates();
	} /* end setCoordinates */

	private void setLabelCoordinates()
	{
		labelCoord = new Point[label.length];
		int lineWidth;
		int lineHeight = parent.getHeight(parent.DIALOGFONT);
		int y2 = start.y + lineHeight + (HEIGHT - lineHeight*label.length)/2 - 4;
		for (int i = 0; i < label.length; i++)
		{
			lineWidth = parent.stringWidth(parent.DIALOGFONT, label[i]);
			labelCoord[i] = new Point(start.x + (WIDTH - lineWidth)/2 + 2, y2);
			y2 = y2 + lineHeight;
		}
	}


	/**
	 *  Liefert die Koordinaten eines bestimmten Punktes der Komponente,
	 *  z.B. die der linken oberen Ecke, der Mitte des rechten Randes oder
	 *  des Ausganges (bei einer ALU).
	 *
	 *  @param str Beschreibung des gemeinten Punktes
	 *  @see #getPossibleQualifiers
	 *  @see #setCoordinates
	 */
	public Point getCoordinates(String str)
	{
		if (str.equalsIgnoreCase("left"))
			return leftPort;
		else if (str.equalsIgnoreCase("right"))
			return rightPort;
		else if (str.equalsIgnoreCase("top"))
			return new Point(start.x + WIDTH/2, start.y);
		else if (str.equalsIgnoreCase("bottom"))
			return new Point(start.x + WIDTH/2, start.y + HEIGHT);
		else  // "leftTop"
			return start;
	} /* end getCoordinates for Misc */


	public void activate()
	{
		if (! activationLocked)
		{
			activated = true;
			hasBeenActivated = true;
		}
	}

	public synchronized void deactivate()
	{
		if (! activationLocked)
		{
			activated = false;
		}
	}

	public synchronized void blink(boolean blinker)
	{
	}

	public String[] getPossibleQualifiers()
	{
		String[] q = {"left", "right", "top", "bottom", "leftTop"};
		return q;
	}

	public void setLabel(String[] newLabel)
	{
		if (newLabel != null)
		{
			label = newLabel;

			setLabelCoordinates();
		}
	}

	public String[] getLabel()
	{
		return label;
	}

	public boolean intersectsWith(Point p)
	{
		return ( (start.x <= p.x) && (start.x + WIDTH >= p.x) && (start.y <= p.y) && (start.y + HEIGHT >= p.y) );
	}

	public String getInfoTipText(Point p)
	{
		return new String("");
	}

	/**
	 * Ohne Funktion
	 */
	public void setValue(int foo) {}

	/**
	 * Ohne Funktion
	 */
	public int getValue() { return -1; }

	public long getMaxValue()
	{
		return Rechner.DEFAULT_MAXVALUE;
	}


} /* end Misc */

