package ckelling.baukasten;

import java.awt.*;

/**
 *	EditableMemory_ProgramChange.java
 *
 *	Fenster, in dem der aktuelle Inhalt des zugehörigen EditableMemory
 *  erscheint, sich editieren oder Einfügen läßt.
 *  Mit Voreinstellungen bekannter Programme.
 *
 *	@author		Carsten Kelling
 *	@version	1.0.0, 29.06.97
 */
public class EditableMemory_ProgramChange extends Frame {
	
	private EditableMemory	parent;

	public EditableMemory_ProgramChange(EditableMemory parent) {

		this.parent = parent;

		//{{INIT_CONTROLS
		GridBagLayout gridBagLayout;
		gridBagLayout = new GridBagLayout();
		setLayout(gridBagLayout);
		addNotify();
		resize(insets().left + insets().right + 245,insets().top + insets().bottom + 332);
		setFont(new Font("Helvetica", Font.PLAIN, 12));
		setBackground(new Color(12632256));
		textArea1 = new java.awt.TextArea();
		textArea1.reshape(insets().left + 10,insets().top + 10,225,247);
		textArea1.setFont(new Font("Courier", Font.BOLD, 12));
		GridBagConstraints gbc;
		gbc = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 0;
		gbc.weightx = 1.0;
		gbc.weighty = 1.0;
		gbc.fill = GridBagConstraints.BOTH;
		gbc.insets = new Insets(10,10,0,10);
		gridBagLayout.setConstraints(textArea1, gbc);
		add(textArea1);
		buttonPanel = new java.awt.Panel();
		buttonPanel.setLayout(new GridLayout(0,2,20,10));
		buttonPanel.reshape(insets().left + 10,insets().top + 267,225,54);
		gbc = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 1;
		gbc.weightx = 1.0;
		gbc.weighty = 0.2;
		gbc.fill = GridBagConstraints.BOTH;
		gbc.insets = new Insets(10,10,10,10);
		gridBagLayout.setConstraints(buttonPanel, gbc);
		add(buttonPanel);
		buttonOK = new java.awt.Button("OK");
		buttonOK.reshape(0,0,102,22);
		buttonPanel.add(buttonOK);
		buttonCancel = new java.awt.Button("Abbrechen");
		buttonCancel.reshape(122,0,102,22);
		buttonPanel.add(buttonCancel);
		buttonClear = new java.awt.Button("Löschen");
		buttonClear.reshape(0,32,102,22);
		buttonPanel.add(buttonClear);
		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.reshape(122,32,102,23);
		progChoice.setFont(new Font("Helvetica", Font.PLAIN, 12));
		progChoice.setBackground(new Color(16777215));
		buttonPanel.add(progChoice);
		setTitle("Programm eingeben");
		//}}

		//{{INIT_MENUS
		//}}

		displayProgram(parent.getAllValues());

		if (parent.parent.PROGRAM.equals(""))
			progChoice.select(1);
		else if (parent.parent.PROGRAM.equalsIgnoreCase("bubblesort"))
			progChoice.select(12);

		show();
	}

	public EditableMemory_ProgramChange(String title, EditableMemory parent) {
	    this(parent);
	    setTitle(title);
	}

    public synchronized void show() {
    	super.show();
    }

	public boolean handleEvent(Event event) {
    	if (event.id == Event.WINDOW_DESTROY) {
            hide();         // hide the Frame
            dispose();
            return true;
    	}
    	else if ( (event.id == Event.ACTION_EVENT) && (event.target == buttonCancel) )
    	{
    		hide();
    		dispose();
    		return true;
    	}
    	else if ( (event.id == Event.ACTION_EVENT) && (event.target == buttonOK) )
    	{
    		parent.initRam(textArea1.getText());
    		parent.paint(parent.parent.onScreenGC);
    		hide();
    		dispose();
    		return true;
    	}
    	else if ( (event.id == Event.ACTION_EVENT) && (event.target == buttonClear) )
    	{
    		textArea1.setText("");
    		return true;
    	}
    	else if ( (event.id == Event.ACTION_EVENT) && (event.target == progChoice) )
    	{
			String label = "";
			if (progChoice.getSelectedItem() != null)
				label = progChoice.getSelectedItem();
			else
				return super.handleEvent(event);
			String program = "";

			if (label.equals("Alles 0000"))
				program = "zero";
			else if (label.equals("Alles 00ff"))
				program = "";
			else if (label.equals("Nur LDA abs."))
				program = "vnr_loadabs";
			else if (label.equals("Alle Lade-/Speicherbefehle"))
				program = "vnr_loadstore";
			else if (label.equals("Einfaches Rechnen"))
				program = "vnr_calculate";
			else if (label.equals("Sprungbefehle"))
				program = "vnr_jump";
			else if (label.equals("Alle Befehle"))
				program = "allcommands";
			else if (label.equals("Cachetest 1"))
				program = "cachetest";
			else if (label.equals("Cachetest 2"))
				program = "cachetest2";
			else if (label.equals("Verdrängungstest"))
				program = "replacetest";
			else if (label.equals("Bubble Sort"))
				program = "bubblesort";
			else if (label.equals("Laden/Speichern"))
				program = "loadstore";
			else if (label.equals("Laden/Speichern 2"))
				program = "loadstore2";

			int[] oldSpeicher = parent.getAllValues();
			
			parent.initRam(program);
			int[] speicher = parent.getAllValues();
			displayProgram(speicher);
			
			parent.setValue(oldSpeicher);
			parent.updateAll();
    	}
    		
    		
		return super.handleEvent(event);
	}
	
	private void displayProgram(int[] speicher)
	{
		textArea1.setText(commentProgram(speicher, parent));
	}
	
	public static String commentProgram(int[] speicher, EditableMemory parent)
	{
		String[] lines = new String[speicher.length];
		StringBuffer s = new StringBuffer();
		int loopCount = 1;
		
		for (int i = 0; i < speicher.length; i++)
		{
			lines[i] = Rechner.expandToString(i, parent.memorySize, 16, true) + "    " + parent.toLongerOpcode(speicher[i], parent.zwei_hoch_bitWidth);
			
			if (parent.getOpcodesSupported())
			// Kommentare einfügen
			{
				int cmd   = speicher[i] / 256;
				int prevCmd = -1;
				if (i > 0)
					prevCmd = speicher[i - 1] / 256;
				int param = speicher[i] & 255;
				
				// Schleifenanfang und -ende beschriften, Zeilen einrücken
				if ( ((cmd == Rechner.JMP_ABSOL) || (cmd == Rechner.JZE_ABSOL) || (cmd == Rechner.JNZ_ABSOL) || (cmd == Rechner.JLE_ABSOL)) &&
				     (param < i) && (param >= 0))
				{
					lines[param] = lines[param] + "  ; Anfang Schleife " + loopCount;
					lines[i] = lines[i] + "  ; Ende Schleife " + loopCount;
					for (int j = param+1; j < i; j++)
						lines[j] = "  " + lines[j];
					loopCount++;
				}
				
				// Aufeinanderfolgendes Laden und Speichern als "MOVE" kennzeichnen
				if ( ((cmd == Rechner.STA_ABSOL) || (cmd == Rechner.STA_MEM)) &&
				     ((prevCmd == Rechner.LDA_ABSOL) || (prevCmd == Rechner.LDA_MEM) || (prevCmd == Rechner.LDA_MEM_INDIR)) )
				{
					String dst, src;
					int prevParam = speicher[i - 1] & 255;
					
					if (cmd == Rechner.STA_ABSOL)
						dst = "#" + Integer.toString(param, 16);
					else
						dst = Integer.toString(param, 16);
						
					if (prevCmd == Rechner.LDA_ABSOL)
						src = "#" + Integer.toString(prevParam, 16);
					else if (prevCmd == Rechner.LDA_MEM)
						src = Integer.toString(prevParam, 16);
					else
						src = "(" + Integer.toString(prevParam, 16) + ")";
						
					lines[i] = lines[i] + "  ; MOVE " + dst + ", " + src;
				}
			}
		
			//s.append(Rechner.expandToString(i, parent.memorySize, 16, true) + "    ");
			//s.append(parent.toLongerOpcode(speicher[i], parent.zwei_hoch_bitWidth) + "\n");
		}
		
		for (int i = 0; i < speicher.length; i++)
			s.append(lines[i] + "\n");

		return s.toString();
    }		

	//{{DECLARE_CONTROLS
	java.awt.TextArea textArea1;
	java.awt.Panel buttonPanel;
	java.awt.Button buttonOK;
	java.awt.Button buttonCancel;
	java.awt.Button buttonClear;
	java.awt.Choice progChoice;
	//}}

	//{{DECLARE_MENUS
	//}}
}
