package ckelling.baukasten;

import java.awt.*;


/**
 *	CacheControl.java
 *
 *	Dialogfenster zum Einstellen von Cache-Parametern:
 *	- Groesse (Cache-Daten)
 *	- line size => Groesse des Tag-Speichers
 *	- Assoziativitaet
 *	- Schreibmodus (write back/through)
 *	- Ersetzungsverhalten (least recently used, zufaellig)
 *
 *	@author		Carsten Kelling
 *	@version	0.2.0, 25.10.96
 */
public class CacheControl extends Frame {

    public final static int	WIDTH	= 290;
    public final static int	HEIGHT	= 220;

	private Speicherhierarchie	parent;

    public CacheControl(Speicherhierarchie parent) {

        super("CacheControl window");

        this.parent = parent;

       	Font choiceFont;
       	if (parent.SMALLFONTSIZE <= 10)
       		choiceFont = new Font("Dialog", Font.PLAIN, 10);
       	else
       		choiceFont = parent.DIALOGFONT;


        //{{INIT_CONTROLS
		GridBagLayout gridBagLayout;
		gridBagLayout = new GridBagLayout();
		setLayout(gridBagLayout);
		addNotify();
		resize(insets().left + insets().right + 259,insets().top + insets().bottom + 214);
		setFont(new Font("Helvetica", Font.PLAIN, 12));
		setBackground(new Color(12632256));
		labelPanel = new java.awt.Panel();
		labelPanel.setLayout(new GridLayout(0,1,5,5));
		labelPanel.reshape(insets().left + 24,insets().top + 10,124,194);
		GridBagConstraints gbc;
		gbc = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 0;
		gbc.weightx = 1.0;
		gbc.weighty = 1.0;
		gbc.fill = GridBagConstraints.VERTICAL;
		gbc.insets = new Insets(10,0,10,0);
		gridBagLayout.setConstraints(labelPanel, gbc);
		add(labelPanel);
		cacheSizeLabel = new java.awt.Label("Größe",Label.RIGHT);
		cacheSizeLabel.reshape(0,0,124,34);
		cacheSizeLabel.setFont(new Font("Helvetica", Font.PLAIN, 12));
		labelPanel.add(cacheSizeLabel);
		lineSizeLabel = new java.awt.Label("Größe der 'lines'",Label.RIGHT);
		lineSizeLabel.reshape(0,39,124,34);
		lineSizeLabel.setFont(new Font("Helvetica", Font.PLAIN, 12));
		labelPanel.add(lineSizeLabel);
		associativityLabel = new java.awt.Label("Assoziativität",Label.RIGHT);
		associativityLabel.reshape(0,78,124,34);
		associativityLabel.setFont(new Font("Helvetica", Font.PLAIN, 12));
		labelPanel.add(associativityLabel);
		writeModeLabel = new java.awt.Label("Schreibmodus",Label.RIGHT);
		writeModeLabel.reshape(0,117,124,34);
		writeModeLabel.setFont(new Font("Helvetica", Font.PLAIN, 12));
		labelPanel.add(writeModeLabel);
		replaceModeLabel = new java.awt.Label("Ersetzungsstrategie",Label.RIGHT);
		replaceModeLabel.reshape(0,156,124,34);
		replaceModeLabel.setFont(new Font("Helvetica", Font.PLAIN, 12));
		labelPanel.add(replaceModeLabel);
		choicePanel = new java.awt.Panel();
		choicePanel.setLayout(new GridLayout(0,1,5,5));
		choicePanel.reshape(insets().left + 172,insets().top + 18,76,186);
		gbc = new GridBagConstraints();
		gbc.gridx = 1;
		gbc.gridy = 0;
		gbc.weightx = 1.0;
		gbc.weighty = 1.0;
		gbc.fill = GridBagConstraints.BOTH;
		gbc.insets = new Insets(18,0,10,10);
		gridBagLayout.setConstraints(choicePanel, gbc);
		add(choicePanel);
		cacheSizeChoice = new java.awt.Choice();
		cacheSizeChoice.addItem("(deaktiviert)");
		cacheSizeChoice.addItem("8");
		cacheSizeChoice.addItem("16");
		cacheSizeChoice.addItem("32");
		try {
			cacheSizeChoice.select(1);
		} catch (IllegalArgumentException e) {
		}
		cacheSizeChoice.reshape(0,0,76,23);
		choicePanel.add(cacheSizeChoice);
		lineSizeChoice = new java.awt.Choice();
		lineSizeChoice.addItem("1");
		lineSizeChoice.addItem("2");
		lineSizeChoice.addItem("4");
		lineSizeChoice.reshape(0,38,76,23);
		choicePanel.add(lineSizeChoice);
		associativityChoice = new java.awt.Choice();
		associativityChoice.addItem("direct mapped");
		associativityChoice.addItem("zweifach");
		associativityChoice.addItem("vierfach");
		associativityChoice.addItem("voll");
		associativityChoice.reshape(0,76,76,23);
		choicePanel.add(associativityChoice);
		writeModeChoice = new java.awt.Choice();
		writeModeChoice.addItem("write through");
		writeModeChoice.addItem("write back");
		writeModeChoice.reshape(0,114,76,23);
		choicePanel.add(writeModeChoice);
		replaceModeChoice = new java.awt.Choice();
		replaceModeChoice.addItem("zufällig");
		replaceModeChoice.addItem("least recently used");
		replaceModeChoice.reshape(0,152,76,23);
		choicePanel.add(replaceModeChoice);
		setTitle("Untitled");
		//}}

        cacheSizeChoice.setFont(choiceFont);
        lineSizeChoice.setFont(choiceFont);
        associativityChoice.setFont(choiceFont);
        writeModeLabel.setFont(new Font("Helvetica",Font.PLAIN,parent.SMALLFONTSIZE));
        writeModeChoice.setFont(choiceFont);
        replaceModeLabel.setFont(new Font("Helvetica",Font.PLAIN,parent.SMALLFONTSIZE));
        replaceModeChoice.setFont(choiceFont);

        setBackground(parent.BACKGROUND);


        //{{INIT_MENUS
		//}}
    }

    public synchronized void show() {
    	super.show();
    }

	public Insets insets()	//	leave some space around the edges
	{
		Insets r = super.insets();
		return new Insets (r.top + 5, r.left+ 5, r.bottom + 10, r.right + 5);
        //format: top, left, bottom, right
	} /* end Insets */

	public Dimension preferredSize()
	{
		double psX = WIDTH; double psY = 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 synchronized boolean handleEvent(Event event) {
    	if (event.id == Event.ACTION_EVENT && event.target == replaceModeChoice) {
    	    	selectedReplaceModeChoice();
    	    	return true;
    	}
    	else
    	if (event.id == Event.ACTION_EVENT && event.target == writeModeChoice) {
    	    	selectedWriteModeChoice();
    	    	return true;
    	}
    	else
    	if (event.id == Event.ACTION_EVENT && event.target == associativityChoice) {
    	    	selectedAssociativityChoice();
    	    	return true;
    	}
    	else
    	if (event.id == Event.ACTION_EVENT && event.target == lineSizeChoice) {
    	    	selectedLineSizeChoice();
    	    	return true;
    	}
    	else
    	if (event.id == Event.ACTION_EVENT && event.target == cacheSizeChoice) {
    	    	selectedcacheSizeChoice();
    	    	return true;
    	}
    	else

    	if (event.id == Event.WINDOW_DESTROY) {
    	    //hide();
    	    return true;
    	}
    	return super.handleEvent(event);
    }

    //{{DECLARE_MENUS
	//}}

    //{{DECLARE_CONTROLS
	java.awt.Panel labelPanel;
	java.awt.Label cacheSizeLabel;
	java.awt.Label lineSizeLabel;
	java.awt.Label associativityLabel;
	java.awt.Label writeModeLabel;
	java.awt.Label replaceModeLabel;
	java.awt.Panel choicePanel;
	java.awt.Choice cacheSizeChoice;
	java.awt.Choice lineSizeChoice;
	java.awt.Choice associativityChoice;
	java.awt.Choice writeModeChoice;
	java.awt.Choice replaceModeChoice;
	//}}
    public synchronized void selectedcacheSizeChoice() {
    	String str = cacheSizeChoice.getSelectedItem();
    	if (str.equals("(deaktiviert)"))
    		parent.tag.disableCache();
    	else
    	{
	    	int cacheSize = Integer.valueOf(cacheSizeChoice.getSelectedItem()).intValue();
	    	int lineSize = parent.tag.getLineSize();
	    	int assoc = parent.tag.getAssociativity();

			parent.tag.enableCache();
			
	    	if (cacheSize < lineSize * assoc)
	    	{
	    		assoc = cacheSize / lineSize;
	    		parent.tag.setAssociativity(assoc);
	    	}

	        parent.tag.setCacheSize(cacheSize);
	        setChoices(cacheSize, lineSize, assoc);
	    }
    }
    public synchronized void selectedLineSizeChoice() {
    	int cacheSize;
    	if (cacheSizeChoice.getSelectedItem().equals("(deaktiviert)"))
    		cacheSize = parent.cache.getMemorySize();
    	else	
    		cacheSize = Integer.valueOf(cacheSizeChoice.getSelectedItem()).intValue();
    	int lineSize = Integer.valueOf(lineSizeChoice.getSelectedItem()).intValue();
    	int assoc = parent.tag.getAssociativity();

    	if (cacheSize < lineSize * assoc)
    	{
    		assoc = cacheSize / lineSize;
    		if (assoc == 1)
	    		parent.tag.setAssociativity(TagMemory.DIRECT_MAPPED);
	    	else if (assoc == cacheSize)
	    		parent.tag.setAssociativity(TagMemory.FULL);
	    	else
	    		parent.tag.setAssociativity(assoc);
    	}

        parent.tag.setLineSize(lineSize);
        setChoices(cacheSize, lineSize, assoc);
    }
    public synchronized void selectedAssociativityChoice() {
    	int cacheSize;
    	if (cacheSizeChoice.getSelectedItem().equals("(deaktiviert)"))
    		cacheSize = parent.cache.getMemorySize();
    	else	
    		cacheSize = Integer.valueOf(cacheSizeChoice.getSelectedItem()).intValue();
    	int lineSize = parent.tag.getLineSize();
    	int assoc;
        String str = associativityChoice.getSelectedItem();
        if (str.equals("direct mapped"))
        	assoc = 1;
        else if (str.equals("zweifach"))
        	assoc = 2;
        else if (str.equals("vierfach"))
        	assoc = 4;
        else  // "voll"
        	assoc = cacheSize;

        if (cacheSize < lineSize * assoc)
        {
    		lineSize = cacheSize / assoc;
    		parent.tag.setLineSize(lineSize);
    	}

		if (assoc == 1)
    		parent.tag.setAssociativity(TagMemory.DIRECT_MAPPED);
    	else if (assoc == cacheSize)
    		parent.tag.setAssociativity(TagMemory.FULL);
    	else
    		parent.tag.setAssociativity(assoc);
        setChoices(cacheSize, lineSize, assoc);
    }
    public synchronized void selectedWriteModeChoice() {
        String str = writeModeChoice.getSelectedItem();
        if (str.equals("write through"))
        	parent.tag.setWriteMode(TagMemory.WRITE_THROUGH);
        else if (str.equals("write back"))
        	parent.tag.setWriteMode(TagMemory.WRITE_BACK);
    }
    public synchronized void selectedReplaceModeChoice() {
        String str = replaceModeChoice.getSelectedItem();
        if (str.equals("zufällig"))
        	parent.tag.setReplaceMode(TagMemory.RANDOM);
        else if (str.equals("least recently used"))
        	parent.tag.setReplaceMode(TagMemory.LRU);
    }

    private synchronized void setChoices(int cacheSize, int lineSize, int assoc)
    {
    	if (parent.tag.isCacheDisabled())
    		cacheSizeChoice.select(0);
    	else	
	    	cacheSizeChoice.select(Integer.toString(cacheSize));

    	lineSizeChoice.select(Integer.toString(lineSize));

    	if (assoc == 1)
    		associativityChoice.select("direct mapped");
    	else if (assoc == 2)
    		associativityChoice.select("zweifach");
    	else if (assoc == 4)
    		associativityChoice.select("vierfach");
    	else if (assoc == cacheSize)
    		associativityChoice.select("voll");
    }
}


