package ckelling.baukasten;

import java.awt.*;

// Versionsgeschichte
// 1.3.0, 20.04.97
// 1.4.0, 11.06.97

/**
 *	ScrollControl.java
 *
 *	Stellt fuer den Von-Neumann-Rechner und seine Subklassen
 *	grundlegende Bedienfunktionen (<<, <, >, >>) und
 *	Zusaetze bereit.
 *
 *	@author		Carsten Kelling
 *	@version	1.4.0, 11.06.97
 */
public class ScrollControl extends Frame
{
	void miUeber_Action(Event event) {


		//{{CONNECTION
		// Create and show as modal
		(new AboutRechnerDialog(parent, this)).show();
		//}}
	}

	private int	WIDTH;
	private int	HEIGHT;

	protected	Rechner parent;

	protected ColorControl	colorControl;


	public ScrollControl (Rechner parent)
	{
		//System.out.println("ScrollControl.init()");
		this.parent = parent;
		colorControl = null;

		setFont(parent.SMALLFONT);

            //{{INIT_CONTROLS
		GridBagLayout gridBagLayout;
		gridBagLayout = new GridBagLayout();
		setLayout(gridBagLayout);
		addNotify();
		resize(insets().left + insets().right + 215,insets().top + insets().bottom + 263);
		setFont(new Font("Helvetica", Font.PLAIN, 12));
		setBackground(new Color(12632256));
		buttonRestart = new java.awt.Button("Simulation neu starten");
		buttonRestart.reshape(insets().left + 20,insets().top + 78,175,23);
		buttonRestart.setFont(new Font("Helvetica", Font.PLAIN, 12));
		GridBagConstraints gbc;
		gbc = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 1;
		gbc.weightx = 1.0;
		gbc.weighty = 1.0;
		gbc.fill = GridBagConstraints.HORIZONTAL;
		gbc.insets = new Insets(20,20,0,20);
		gridBagLayout.setConstraints(buttonRestart, gbc);
		add(buttonRestart);
		mrPanel = new java.awt.Panel();
		mrPanel.setLayout(new GridLayout(1,1,10,0));
		mrPanel.reshape(insets().left + 20,insets().top + 111,175,23);
		gbc = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 2;
		gbc.weightx = 1.0;
		gbc.weighty = 1.0;
		gbc.fill = GridBagConstraints.HORIZONTAL;
		gbc.insets = new Insets(0,20,0,20);
		gridBagLayout.setConstraints(mrPanel, gbc);
		add(mrPanel);
		buttonRepaint = new java.awt.Button("Repaint");
		buttonRepaint.reshape(0,0,82,23);
		buttonRepaint.setFont(new Font("Helvetica", Font.PLAIN, 12));
		mrPanel.add(buttonRepaint);
		buttonUpdate = new java.awt.Button("Update");
		buttonUpdate.reshape(92,0,82,23);
		buttonUpdate.setFont(new Font("Helvetica", Font.PLAIN, 12));
		mrPanel.add(buttonUpdate);
		progChoice = new java.awt.Choice();
		progChoice.addItem("Alles 0000");
		progChoice.addItem("Alles 00ff");
		progChoice.addItem("-----------------------------------");
		progChoice.addItem("Nur LDA abs.");
		progChoice.addItem("Alle Lade-/Speicherbefehle");
		progChoice.addItem("Einfaches Rechnen");
		progChoice.addItem("Sprungbefehle");
		progChoice.addItem("Alle Befehle");
		progChoice.addItem("-----------------------------------");
		progChoice.addItem("Laden/Speichern");
		progChoice.addItem("Laden/Speichern 2");
		progChoice.addItem("-----------------------------------");
		progChoice.addItem("Bubble Sort");
		progChoice.addItem("Bubble Sort (gleiche Daten)");
		progChoice.reshape(insets().left + 20,insets().top + 144,175,23);
		progChoice.setFont(new Font("Helvetica", Font.PLAIN, 12));
		progChoice.setBackground(new Color(16777215));
		gbc = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 3;
		gbc.weightx = 1.0;
		gbc.weighty = 1.0;
		gbc.fill = GridBagConstraints.HORIZONTAL;
		gbc.insets = new Insets(0,20,0,20);
		gridBagLayout.setConstraints(progChoice, gbc);
		add(progChoice);
		checkboxOpcodes = new java.awt.Checkbox("Opcodes anzeigen");
		checkboxOpcodes.reshape(insets().left + 20,insets().top + 233,195,23);
		gbc = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 5;
		gbc.weightx = 1.0;
		gbc.weighty = 1.0;
		gbc.anchor = GridBagConstraints.WEST;
		gbc.fill = GridBagConstraints.HORIZONTAL;
		gbc.insets = new Insets(0,20,0,0);
		gridBagLayout.setConstraints(checkboxOpcodes, gbc);
		add(checkboxOpcodes);
		checkboxDecode = new java.awt.Checkbox("DECODE-Phase zeigen");
		checkboxDecode.reshape(insets().left + 20,insets().top + 200,195,23);
		gbc = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 4;
		gbc.weightx = 1.0;
		gbc.weighty = 1.0;
		gbc.anchor = GridBagConstraints.WEST;
		gbc.fill = GridBagConstraints.HORIZONTAL;
		gbc.insets = new Insets(20,20,0,0);
		gridBagLayout.setConstraints(checkboxDecode, gbc);
		add(checkboxDecode);
		panel1 = new java.awt.Panel();
		panel1.setLayout(new FlowLayout(FlowLayout.CENTER,0,0));
		panel1.reshape(insets().left + 20,insets().top + 6,175,42);
		gbc = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 0;
		gbc.weightx = 1.0;
		gbc.weighty = 1.0;
		gbc.fill = GridBagConstraints.HORIZONTAL;
		gbc.insets = new Insets(0,20,0,20);
		gridBagLayout.setConstraints(panel1, gbc);
		add(panel1);
		directionRewind = new symantec.itools.awt.ImageButton();
		directionRewind.reshape(3,5,30,32);
		panel1.add(directionRewind);
		directionRewind.setCenterMode(false);
		directionReverse = new symantec.itools.awt.ImageButton();
		directionReverse.reshape(38,5,30,32);
		panel1.add(directionReverse);
		directionReverse.setCenterMode(false);
		directionPlay = new symantec.itools.awt.ImageButton();
		directionPlay.reshape(73,5,30,32);
		panel1.add(directionPlay);
		directionPlay.setCenterMode(false);
		directionFast = new symantec.itools.awt.ImageButton();
		directionFast.reshape(108,5,30,32);
		panel1.add(directionFast);
		directionFast.setCenterMode(false);
		directionBreakpoint = new symantec.itools.awt.ImageButton();
		directionBreakpoint.reshape(143,5,30,32);
		panel1.add(directionBreakpoint);
		directionBreakpoint.setCenterMode(false);
		setTitle("Rechner steuern");
		//}}

		try {
			//System.out.println("getDocumentBase() liefert: " + parent.getDocumentBase());
			//directionRewind.setImageURL(symantec.itools.net.RelativeURL.getURL("../Bilder/Pfeile/doppellinks.gif"));
			directionRewind.setImageURL(new java.net.URL(parent.getDocumentBase(), "Bilder/Pfeile/doppellinks.gif"));
		} catch (java.net.MalformedURLException error) {
		}
		try {
			//directionReverse.setImageURL(symantec.itools.net.RelativeURL.getURL("../Bilder/pfeile/links.gif"));
			directionReverse.setImageURL(new java.net.URL(parent.getDocumentBase(), "Bilder/Pfeile/links.gif"));
		} catch (java.net.MalformedURLException error) {
		}
		try {
			//directionPlay.setImageURL(symantec.itools.net.RelativeURL.getURL("../Bilder/Pfeile/rechts.gif"));
			directionPlay.setImageURL(new java.net.URL(parent.getDocumentBase(), "Bilder/Pfeile/rechts.gif"));
		} catch (java.net.MalformedURLException error) {
		}
		try {
			//directionFast.setImageURL(symantec.itools.net.RelativeURL.getURL("../Bilder/Pfeile/doppelrechts.gif"));
			directionFast.setImageURL(new java.net.URL(parent.getDocumentBase(), "Bilder/Pfeile/doppelrechts.gif"));
		} catch (java.net.MalformedURLException error) {
		}
		try {
			//directionBreakpoint.setImageURL(symantec.itools.net.RelativeURL.getURL("../Bilder/Pfeile/breakpoint.gif"));
			directionBreakpoint.setImageURL(new java.net.URL(parent.getDocumentBase(), "Bilder/Pfeile/breakpoint.gif"));
		} catch (java.net.MalformedURLException error) {
		}

            //{{INIT_MENUS
		menubar = new java.awt.MenuBar();

		preferencesMenu = new java.awt.Menu("Einstellungen");
		cbmiErweitern = new java.awt.CheckboxMenuItem("Auf n Stellen erweitern");
		cbmiErweitern.setState(false);
		preferencesMenu.add(cbmiErweitern);
		cbmiDezimal = new java.awt.CheckboxMenuItem("Dezimalzahlen");
		cbmiDezimal.setState(false);
		preferencesMenu.add(cbmiDezimal);
		preferencesMenu.addSeparator();
		miStandard = new java.awt.MenuItem("Standardwerte benutzen");
		preferencesMenu.add(miStandard);
		preferencesMenu.addSeparator();
		cbmiShowTrace = new java.awt.CheckboxMenuItem("Befehlsgeschichte anzeigen");
		cbmiShowTrace.setState(false);
		preferencesMenu.add(cbmiShowTrace);
		menubar.add(preferencesMenu);

		helpMenu = new java.awt.Menu("Hilfe");
		menubar.setHelpMenu(helpMenu);
		miUeber = new java.awt.MenuItem("Info");
		helpMenu.add(miUeber);
		menubar.add(helpMenu);
		setMenuBar(menubar);
		//$$ menubar.move(0,0);
		//}}


		WIDTH = bounds().width;
		HEIGHT = bounds().height;

		//cbmiZweifarbig.setState(parent.blackAndWhite);
		cbmiErweitern.setState(parent.expandNumbers);
		cbmiDezimal.setState(parent.NUMBERBASE == 10);


		if (! parent.buttonFast)
		{
			panel1.remove (directionRewind);
			panel1.remove (directionFast);
			panel1.remove (directionBreakpoint);
		}

		if (! parent.manualRedraw)
			remove(mrPanel);

		if (parent.PROGRAM.equals(""))
			progChoice.select(1);
		else if (parent.PROGRAM.equalsIgnoreCase("bubblesort"))
			progChoice.select(12);
		if (! parent.programChoice)
			remove(progChoice);

		checkboxDecode.setState(parent.showDecodeCycle);
		if (! parent.buttonDecode)
			remove(checkboxDecode);

		checkboxOpcodes.setState(parent.showOpcodes);
		if (! parent.buttonOpcodes)
			remove(checkboxOpcodes);


		resize(preferredSize().width, preferredSize().height);

		//setBackground(parent.BACKGROUND);

		show();
	} /* end ScrollControl */


	public void show()
	{
		Rectangle bounds = bounds();
		Rectangle pbounds = parent.bounds();
		int x = Math.min(pbounds.x + pbounds.width, parent.getScreenSize().width - bounds.width);
		move (x, pbounds.y);

		super.show();
	}


	public Insets insets()	//	leave some space around the edges
	{
		Insets r = super.insets();
		return new Insets (r.top, r.left, r.bottom + 40, r.right);
        //format: top, left, bottom, right
	} // end Insets

	public Dimension preferredSize()
	{
		double psX = WIDTH; double psY = HEIGHT;
		if (parent.manualRedraw == false)
			psY = psY - mrPanel.bounds().height;
		if (parent.programChoice == false)
			psY = psY - progChoice.bounds().height;
		if (parent.buttonDecode == false)
			psY = psY - checkboxDecode.bounds().height;
		if (parent.buttonOpcodes == false)
			psY = psY - checkboxDecode.bounds().height;

		//double faktor = parent.SMALLFONTSIZE / (double) parent.NORMALFONTSIZE;
		//psX = psX * faktor; psY = psY * faktor;

		return new Dimension((int) psX, (int) psY);
	}

	public Dimension minimumSize()
	{
		return preferredSize();
	}

	public boolean handleEvent(Event e)
	{
		if (e.id == Event.WINDOW_DESTROY)
			return true;

    	return super.handleEvent(e);

	} /* end handleEvent */


	public boolean action(Event e, Object arg)
	{
		if (e.target instanceof symantec.itools.awt.ImageButton)
		{
			if (e.target.equals(directionPlay))  // ">"
			{
				if (parent.firstTime == true)
				{
					parent.firstTime = false;
					parent.demonstrate(false);
					parent.demonstrate(true);
				}
				else
				{
					//noSpeedTest long startTime, endTime;
					//noSpeedTest startTime = System.currentTimeMillis();
					parent.demonstrate(true);
					//noSpeedTest endTime = System.currentTimeMillis();
					//noSpeedTest System.out.println("'>': " + (endTime - startTime));
				}

				parent.paintActivated(parent.onScreenGC);
			}
			else if (e.target.equals(directionReverse))  // "<"
			{
				parent.firstTime = false;
				parent.demonstrateBack();
			}
			else if (e.target.equals(directionFast))  //">>"
			{
				if (parent.firstTime == true)
				{
					parent.firstTime = false;
					parent.demonstrate(true);
				}
				parent.singleInstruction();
			}
			else if (e.target.equals(directionRewind))  //"<<"
			{
				parent.firstTime = false;
				parent.singleInstructionBack();
			}
			else if (e.target.equals(directionBreakpoint))  //">> BP"
			{
				if (parent.firstTime == true)
				{
					parent.firstTime = false;
					parent.demonstrate(true);
				}
				parent.goUntilBreakpoint();
			}
			return true;
		}
		else if (e.target instanceof Button)
		{
			String label = ((Button) e.target).getLabel();

			if (label.equals("Simulation neu starten"))
			{
				parent.stopSimulation();
    		    parent.updateAll();
	        	parent.deactivateAll();
		        parent.paint(parent.onScreenGC);
			}
			else if (label.equals("Repaint") || label.equals("Update"))
			{
				if ((parent.scrollThread == (TimerThread) null) || (parent.scrollThread.isAlive() == false))
				{
					parent.scrollThread = new TimerThread(Rechner.SCROLLTIME, "scrolltimer", parent);
					parent.scrollThread.start();
				}
				if (label.equals("Update"))
				{
					parent.updateAll();
					parent.deactivateAll();
				}
				parent.paint(parent.onScreenGC);
			}
			else if (label.equals("Einmal"))
			{
				if (parent.scrollThread != (TimerThread) null)
					parent.scrollThread.stop();
				parent.scrollAll();
			}
			else if (label.equals("Permanent"))
			{
				if ((parent.scrollThread == (TimerThread) null) || (parent.scrollThread.isAlive() == false))
				{
					parent.scrollThread = new TimerThread(Rechner.SCROLLTIME, "scrolltimer", parent);
					parent.scrollThread.start();
				}
			}
			else if (label.equals("Aus"))
			{
				if (parent.scrollThread != (TimerThread) null)
					parent.scrollThread.stop();
			}
			return true;
		}
		else if (e.target instanceof Checkbox)
		{
			Checkbox cb = (Checkbox)(e.target);
			String label = cb.getLabel();

			if (label.equals("DECODE-Phase zeigen"))
				parent.showDecodeCycle = cb.getState();
			else if (label.equals("Opcodes anzeigen"))
				parent.showAllOpcodes(cb.getState());
			return true;
		}
		else if (e.target instanceof CheckboxMenuItem)
		{
			CheckboxMenuItem cbmi = (CheckboxMenuItem)(e.target);
			String label = cbmi.getLabel();

			if (label.equals("Zweifarbig"))
			{
				parent.blackAndWhite = cbmi.getState();
				if (parent.blackAndWhite == false)
				{
					if (parent.blinkThread != (TimerThread) null)
						parent.blinkThread.stop();
				}
				else
				{
					if ((parent.blinkThread == (TimerThread) null) || (parent.blinkThread.isAlive() == false))
					{
						parent.blinkThread = new TimerThread(Rechner.BLINKTIME, "blinktimer", parent);
						parent.blinkThread.start();
					}
				}

				parent.chooseColors();
				parent.invalidateAllImageCaches();
				java.lang.System.gc(); // den Garbage Collector aufrufen
				parent.paint(parent.onScreenGC);
			}
			else if (label.equals("Auf n Stellen erweitern"))
			{
				parent.expandNumbers = cbmi.getState();
				parent.updateAll();
				//parent.demonstrateBack();
				//parent.demonstrate(true);
				parent.paint(parent.onScreenGC);
			}
			else if (label.equals("Dezimalzahlen"))
			{
				if (cbmi.getState() == true)
					parent.NUMBERBASE = 10;
				else
					parent.NUMBERBASE = 16;
				parent.updateAll();
				//parent.demonstrateBack();
				//parent.demonstrate(true);
				parent.paint(parent.onScreenGC);
			}
			else if (label.equals("Farblegende"))
			{
				if (cbmi.getState() == true)
				{
					if (colorControl == null)
						colorControl = new ColorControl(parent);
					colorControl.show();
				}
				else if (colorControl != null)
					colorControl.hide();
			}
			else if (e.target == cbmiShowTrace)
			{
				if (cbmiShowTrace.getState() == true)
				{
					if (Rechner.traceWindow == null)
						Rechner.traceWindow = new ConsoleWindow();
					Rechner.traceWindow.show();
				}
				else if (Rechner.traceWindow != null)
					Rechner.traceWindow.hide();
			}
			return true;
		}
		else if (e.target instanceof MenuItem)
		{
			MenuItem mi = (MenuItem)(e.target);
			String label = mi.getLabel();

			if (e.target == miUeber)
			{
				miUeber_Action(e);
				return true;
			}
			else if (label.equals("Standardwerte benutzen"))
			{
				parent.blackAndWhite = false;
				if (parent.blinkThread != (TimerThread) null)
					parent.blinkThread.stop();
				parent.chooseColors();
				parent.expandNumbers = true;
				parent.NUMBERBASE = 16;
				//cbmiZweifarbig.setState(parent.blackAndWhite);
				cbmiErweitern.setState(parent.expandNumbers);
				if (parent.NUMBERBASE == 10)
					cbmiDezimal.setState(true);
				else
					cbmiDezimal.setState(false);

				parent.updateAll();
				parent.paint(parent.onScreenGC);
			}
			return true;
		}
		else if (e.target instanceof Choice)
		{
			Choice c = (Choice)(e.target);
			String label = c.getSelectedItem();

			parent.stopSimulation();

			if (label.equals("Alles 0000"))
				parent.PROGRAM = "zero";
			else if (label.equals("Alles 00ff"))
				parent.PROGRAM = "";
			else if (label.equals("Nur LDA abs."))
				parent.PROGRAM = "vnr_loadabs";
			else if (label.equals("Alle Lade-/Speicherbefehle"))
				parent.PROGRAM = "vnr_loadstore";
			else if (label.equals("Einfaches Rechnen"))
				parent.PROGRAM = "vnr_calculate";
			else if (label.equals("Sprungbefehle"))
				parent.PROGRAM = "vnr_jump";
			else if (label.equals("Alle Befehle"))
				parent.PROGRAM = "allcommands";
			else if (label.equals("Cachetest 1"))
				parent.PROGRAM = "cachetest";
			else if (label.equals("Cachetest 2"))
				parent.PROGRAM = "cachetest2";
			else if (label.equals("Verdrängungstest"))
				parent.PROGRAM = "replacetest";
			else if (label.equals("Bubble Sort"))
				parent.PROGRAM = "bubblesort";
			else if (label.equals("Bubble Sort (gleiche Daten)"))
				parent.PROGRAM = "bubblesort_s";
			else if (label.equals("Laden/Speichern"))
				parent.PROGRAM = "loadstore";
			else if (label.equals("Laden/Speichern 2"))
				parent.PROGRAM = "loadstore2";

			parent.initRam(parent.PROGRAM);
			parent.paint(parent.onScreenGC);

			return true;
		}
		return super.action(e, arg);

	} /* end action */

        //{{DECLARE_CONTROLS
	java.awt.Button buttonRestart;
	java.awt.Panel mrPanel;
	java.awt.Button buttonRepaint;
	java.awt.Button buttonUpdate;
	java.awt.Choice progChoice;
	java.awt.Checkbox checkboxOpcodes;
	java.awt.Checkbox checkboxDecode;
	java.awt.Panel panel1;
	symantec.itools.awt.ImageButton directionRewind;
	symantec.itools.awt.ImageButton directionReverse;
	symantec.itools.awt.ImageButton directionPlay;
	symantec.itools.awt.ImageButton directionFast;
	symantec.itools.awt.ImageButton directionBreakpoint;
	//}}

        //{{DECLARE_MENUS
	java.awt.MenuBar menubar;
	java.awt.Menu preferencesMenu;
	java.awt.CheckboxMenuItem cbmiErweitern;
	java.awt.CheckboxMenuItem cbmiDezimal;
	java.awt.MenuItem miStandard;
	java.awt.CheckboxMenuItem cbmiShowTrace;
	java.awt.Menu helpMenu;
	java.awt.MenuItem miUeber;
	//}}

} /* end ScrollControl */
