package ckelling.baukasten;

import java.awt.*;
import java.lang.*;
import java.util.*;


/**
 *  2-auf-1-Multiplexer
 *
 *  Die Beschriftung der beiden Eingänge
 *  (Standard: "1"/"0") läßt sich ändern.
 *
 *	@author		Carsten Kelling
 *	@version	0.1.0, 27.02.97
 */
public class Mux extends RechnerKomponente
{
    public final static int	DEFAULT_WIDTH	= 30;
    public final static int	DEFAULT_HEIGHT	= 40;
	private int			WIDTH;
	private int			HEIGHT;
    public final static int	CORNER_RADIUS	= 10;

	private String		label[];
	private Point		labelCoord[];
	private Point		start;
	private Point		upperInput;
	private Point		lowerInput;
	private Point		output;
	private String		grabMode;

	private boolean		hasBeenActivated;
	private boolean		activatedAtLastPaint;

	private Rechner		parent;

	public Mux(String label1, int x1, int y1, String str2, Rechner par)
	{
		String[] arrayLabel = {label1};
		initialize(arrayLabel, x1, y1, DEFAULT_WIDTH, DEFAULT_HEIGHT, str2, par);
	}

	public Mux(String[] arrayLabel1, int x1, int y1, String str2, Rechner par)
	{
		initialize(arrayLabel1, x1, y1, DEFAULT_WIDTH, DEFAULT_HEIGHT, str2, par);
	}

	public Mux(String label1, int x1, int y1, int width, int height, String str2, Rechner par)
	{
		String[] arrayLabel = {label1};
		initialize(arrayLabel, x1, y1, width, height, str2, par);
	}

	public Mux(String[] arrayLabel1, int x1, int y1, int width, int height, String str2, Rechner par)
	{
		initialize(arrayLabel1, x1, y1, width, height, str2, par);
	}

	private void initialize(String[] arrayLabel1, int x1, int y1, int width, int height, String str2, Rechner par)
	{
		parent = par;
		label = new String[3];
		label[0] = "";
		label[1] = new String("0");
		label[2] = new String("1");
		if (arrayLabel1 != null)
			for (int i = 0; i < Math.min(label.length, arrayLabel1.length); i++)
				label[i] = arrayLabel1[i];

		reshape(x1, y1, width, height, str2);

		activated = false;
		hasBeenActivated = false;
		activatedAtLastPaint = !activated;
	} /* end Mux */


	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.drawRoundRect(start.x    , start.y    , WIDTH    , HEIGHT    , CORNER_RADIUS, CORNER_RADIUS);
		g.drawRoundRect(start.x + 1, start.y + 1, WIDTH - 2, HEIGHT - 2, CORNER_RADIUS-1, CORNER_RADIUS-1);

		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 */


	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);
	}

	public void reshape(int x, int y, int width, int height, String newGrabMode)
	{
		WIDTH = width; HEIGHT = height;
		setCoordinates(x, y, newGrabMode);
	}

	public void setCoordinates(int x1, int y1, String grabMode)
	{
		this.grabMode = grabMode;

		if ( grabMode.equalsIgnoreCase("upperInput") || grabMode.equalsIgnoreCase("upper") )
		{
			upperInput = new Point(x1, y1);
			lowerInput = new Point(x1, y1 + HEIGHT - 2*CORNER_RADIUS);
			start = new Point(x1, y1 - CORNER_RADIUS);
			output = new Point(x1 + WIDTH, start.y + HEIGHT/2);
		}
		else if ( grabMode.equalsIgnoreCase("lowerInput") || grabMode.equalsIgnoreCase("lower") )
		{
			upperInput = new Point(x1, y1 - HEIGHT + 2*CORNER_RADIUS);
			lowerInput = new Point(x1, y1);
			start = new Point(x1, y1 - HEIGHT + CORNER_RADIUS);
			output = new Point(x1 + WIDTH, start.y + HEIGHT/2);
		}
		else if (grabMode.equalsIgnoreCase("top"))
		{
			start = new Point(x1 - WIDTH/2, y1);
			upperInput = new Point(start.x, y1 + CORNER_RADIUS);
			lowerInput = new Point(start.x, y1 + HEIGHT - CORNER_RADIUS);
			output = new Point(start.x + WIDTH, start.y + HEIGHT/2);
		}
		else if (grabMode.equalsIgnoreCase("bottom"))
		{
			start = new Point(x1 - WIDTH/2, y1 - HEIGHT);
			upperInput = new Point(start.x, y1 - HEIGHT + CORNER_RADIUS);
			lowerInput = new Point(start.x, y1 - CORNER_RADIUS);
			output = new Point(start.x + WIDTH, start.y + HEIGHT/2);
		}
		else if (grabMode.equalsIgnoreCase("output"))
		{
			output = new Point(x1, y1);
			start = new Point(x1 - WIDTH, y1 - HEIGHT/2);
			upperInput = new Point(start.x, start.y + CORNER_RADIUS);
			lowerInput = new Point(start.x, start.y + HEIGHT - CORNER_RADIUS);
		}
		else  // "leftTop"
		{
			start = new Point(x1, y1);
			upperInput = new Point(x1, y1 + CORNER_RADIUS);
			lowerInput = new Point(x1, y1 + HEIGHT - CORNER_RADIUS);
			output = new Point(x1 + WIDTH, y1 + HEIGHT/2);
		}

		setLabelCoordinates();
	} /* end setCoordinates */

	private void setLabelCoordinates()
	{
		labelCoord = new Point[3];
		labelCoord[0] = new Point(start.x, start.y - 4);
		labelCoord[1] = new Point(start.x + 5, upperInput.y + 6);
		labelCoord[2] = new Point(start.x + 5, lowerInput.y + 6);
	}


	public Point getCoordinates(String str)
	{
		if ( str.equalsIgnoreCase("upperInput") || str.equalsIgnoreCase("upper") )
			return new Point(upperInput.x, upperInput.y);
		else if ( str.equalsIgnoreCase("lowerInput") || str.equalsIgnoreCase("lower") )
			return new Point(lowerInput.x, lowerInput.y);
		else if (str.equalsIgnoreCase("output"))
			return new Point(output.x, output.y);
		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 new Point(start.x, start.y);

	} /* end getCoordinates for Mux */


	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 = {"upperInput", "lowerInput", "output", "top", "bottom", "leftTop"};
		return q;
	}

	public void setLabel(String[] newLabel)
	{
		if (newLabel != null)
		{
			for (int i = 0; i < Math.min(label.length, newLabel.length); i++)
				label[i] = newLabel[i];

			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 Mux */

