import JSim.util.*;
import JSim.gui.plugin.GModelEasel;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class MyEasel extends GModelEasel {
	private int ncomp; // # compartments
	private JPanel panel, figure; 

	// constructor
	public MyEasel(Callbacks cb) throws Exception {
	    super(cb);
	    ncomp = 2; // 2 compartments to start
	    
	    // initialize graphics
	    panel = new JPanel();
	    MyAction a_more = new MyAction("MORE", 1);
	    JButton b_more = new JButton(a_more);
	    panel.add(b_more);
	    MyAction a_less = new MyAction("FEWER", -1);
	    JButton b_less = new JButton(a_less);
	    panel.add(b_less);
	    MyAction a_comp = new MyAction("Compile!", 0);
	    JButton b_comp = new JButton(a_comp);
	    panel.add(b_comp);
	    figure = new JPanel(null) {
	    	public void paint(Graphics g) {
		    int w = getSize().width;
		    int h = getSize().height;
		    g.setColor(Color.white);
		    g.fillRect(0,0,w,h);
		    int b = 10;
		    int l = w/2-b*(ncomp-1)-b/2;
		    g.setColor(Color.black);
		    for (int x=0; x<ncomp; x++) 
		        g.fillRect(l+x*b*2,h/2,b,b);
		    g.drawLine(l,h/2+b/2,l+(ncomp-1)*b*2,h/2+b/2);
		}
	    };
	    figure.setPreferredSize(new Dimension(180,50));
	    panel.add(figure);
	}

	// button action
	public class MyAction extends AbstractAction {
	    private int which;
	    
	    public MyAction(String n, int w) {
	        super(n);
		which = w;
	    }
	    
	    public void actionPerformed(ActionEvent e) {

		// compile model?
	        if (which == 0) {
		    if (callbacks != null)
		    	callbacks.easelCompile();
		    return;
	  	}

		// adjust # components
	        ncomp += which;
		if (ncomp<1) ncomp = 1;
		if (ncomp>9) ncomp = 9;
		figure.repaint();
		if (callbacks != null)
		    callbacks.easelStateChanged(EASEL | MML);
	    }
	}
	
	// query 
	public JComponent getJComponent() { return panel; }
	
	// query MML
	public String getMML() {
	    StringBuffer buf = new StringBuffer();
	    buf.append("// MML text automatically generated by MyEasel plugin\n");
	    buf.append("math main {\n");
	    buf.append("  realDomain t; t.min=0; t.max=10; t.delta=0.1;\n");
	    for (int i=0; i<ncomp; i++) 
	    	buf.append("  real v" + i + "(t); when (t=t.min) v" 
		    + i + "=" + i + ";\n"); 
	    for (int i=0; i<ncomp; i++) {
	    	buf.append("  v" + i + ":t=0");
		if (i>0) buf.append("+(v" + (i-1) + "-v" + i + ")");
		if (i<ncomp-1) buf.append("+(v" + (i+1) + "-v" + i + ")");
		buf.append(";\n");
	    }
	    buf.append("}");
	    return buf.toString();
	}

	//// TEST HARNESS (not part of plugin)
	static MyEasel easel;

	// callback context
	public static class MyCallbacks implements Callbacks {
	    public void easelCompile() {
		String text = easel.getMML();
	    	System.out.println("Compiling...\n" + text);
		System.exit(0);
	    }
	    public void easelStateChanged(int flags) { }
	}

	// test mainline
	public static void main(String[] args) throws Exception {
	    JFrame frame = new JFrame("MyEasel");
	    JRootPane root = frame.getRootPane();
	    root.setPreferredSize(new Dimension(200,150));
	    MyCallbacks cb = new MyCallbacks();
	    easel = new MyEasel(cb);
	    root.setContentPane(easel.getJComponent());
	    frame.pack();
	    frame.setVisible(true);
	}
}

		    
