/*  Monte-Carlo simulation code for statistical physics
    Copyright (C) 2001-2005  Sylvain Reynal
    
    Département de Physique
    Ecole Nationale Supérieure de l'Electronique et de ses Applications (ENSEA)
    6, avenue du Ponceau,    
    F-95014 CERGY CEDEX

    et
    
    Laboratoire de Physique Théorique et Modélisation (LPTM)
    Université de Cergy-Pontoise - Site de Neuville
    F-95031 CERGY CEDEX
    
	
    Tel : 00 +33 130 736 245
    Fax : 00 +33 130 736 667
    e-mail : reynal@ensea.fr
    web page : http://www.ensea.fr/staff/reynal/
*/

package fr.ensea.montecarlo.canonical;

import fr.ensea.Version;
import fr.ensea.Localizer;
import fr.ensea.chart.*;
import fr.ensea.montecarlo.*;
import fr.ensea.montecarlo.data.*;
import fr.ensea.montecarlo.model.*;
import fr.ensea.montecarlo.canonical.*;
import fr.ensea.montecarlo.misc.*;

import java.awt.*; import javax.swing.*;
import java.awt.event.*;
import java.applet.Applet;
import java.util.Locale;

/**
 * Pop-up window that allows the user to configure quite every simulation parameters, including
 * eg sweep mode, temperature range, mcs wait steps, ...
 */
public class MCSimulationCustomizer extends JFrame implements ActionListener, ItemListener {

	private MCSimulationThread algoThread; 
	private MCApplet controller;
	
	private JTextField kTSingleTF, kTStartTF, kTEndTF, kTStepsTF, mcsWaitTF, mcsThermTF,nbMeasTF;
	private JButton okTempBUT, okStatsBUT;
	private GridBagLayout gridbag;
	private GridBagConstraints c;
	private JComboBox modeCH;
	private JButton unlimitedNbMeasBUT;
	private JCheckBox autoComputeMCSWaitCB;
	private JLabel lbl1, lbl2; // for modeCH

	public MCSimulationCustomizer(MCApplet controller, MCSimulationThread algoThread, double defKT){
		super(Localizer.get("ConfigPanel"));
		this.algoThread = algoThread;
		this.controller = controller;
		
		//this.setSize(600,300);
		this.getContentPane().setLayout(new BorderLayout(5,5));
		addWindowListener(new WindowAdapter(){public void windowClosing(WindowEvent evt){
				                  setVisible(false);
				                  //[test]System.exit(0);
			                  }});


		JPanel p = new JPanel();
		gridbag = new GridBagLayout();
		p.setLayout(gridbag);
		c = new GridBagConstraints();

		c.fill = GridBagConstraints.BOTH;
		c.weightx = 1.0;	c.weighty = 1.0;

		c.gridwidth = GridBagConstraints.REMAINDER;
		modeCH = new JComboBox();
		modeCH.addItem(Localizer.get("FixedTemp"));
		modeCH.addItem(Localizer.get("TempSweep"));
		int mode=0;
		if (algoThread.isTemperatureSweep()) mode=1;
		modeCH.setSelectedIndex(mode);
		addComp(p, modeCH);

		c.gridwidth = 1;
		addComp(p, lbl1=new JLabel("  "));
		addComp(p,new JLabel("kT ("+Localizer.get("fixed")+")="));
		addComp(p,kTSingleTF=new JTextField(AbstractApplet.format(algoThread.getSingleTemperature()),4));
		c.gridwidth = GridBagConstraints.REMAINDER;
		addComp(p, new JLabel());


		c.gridwidth = 1;
		addComp(p, lbl2=new JLabel("  "));
		addComp(p,new JLabel(Localizer.get("From")+" kT="));
		addComp(p,kTStartTF = new JTextField(AbstractApplet.format(algoThread.getKTStart()),4));
		addComp(p,new JLabel(" "+Localizer.get("to")+" kT="));
		addComp(p,kTEndTF = new JTextField(AbstractApplet.format(algoThread.getKTEnd()),4));
		addComp(p,new JLabel(" "+Localizer.get("in")+" n="));
		addComp(p,kTStepsTF = new JTextField(Integer.toString(algoThread.getKTSteps()),4));
		c.gridwidth = GridBagConstraints.REMAINDER;
		addComp(p,new JLabel(Localizer.get("steps")+"."));

		c.gridwidth = 2;
		addComp(p,okTempBUT=new JButton(Localizer.get("Apply")));
		c.gridwidth = GridBagConstraints.REMAINDER;
		addComp(p,new JLabel());

		addComp(p,new JLabel(Localizer.get("Statistics")+" :"));

		c.gridwidth = 2;
		addComp(p,new JLabel(Localizer.get("SimulationSteps")+"="));
		c.gridwidth = 1;
		addComp(p,nbMeasTF = new JTextField(Integer.toString(algoThread.getNumberMCSSteps()),4));
		addComp(p,unlimitedNbMeasBUT = new JButton(Localizer.get("unlimited")));
		c.gridwidth = GridBagConstraints.REMAINDER;
		addComp(p, new JLabel());

		c.gridwidth = 2;
		addComp(p,new JLabel(Localizer.get("SampleEvery")));
		c.gridwidth = 1;
		addComp(p,mcsWaitTF = new JTextField(Integer.toString(controller.getSamplesBag().getMCSWait()),4));
		addComp(p,new JLabel(" "+Localizer.get("steps")+"."));
		c.gridwidth = GridBagConstraints.REMAINDER;;
		addComp(p,autoComputeMCSWaitCB=new JCheckBox(Localizer.get("Automatic")));
		if (controller.getSamplesBag().getMCSWait()<0) autoComputeMCSWaitCB.setSelected(true);
		mcsWaitTF.setEnabled(!autoComputeMCSWaitCB.isSelected());
		//c.gridwidth = GridBagConstraints.REMAINDER;addComp(p, new JLabel());

		c.gridwidth = 2;
		addComp(p,new JLabel(Localizer.get("Thermalization")+" :"));
		c.gridwidth = 1;
		addComp(p, mcsThermTF=new JTextField(Integer.toString(controller.getSamplesBag().getThermalizationTime()),6));
		addComp(p,new JLabel(" "+Localizer.get("steps")+"."));
		c.gridwidth = GridBagConstraints.REMAINDER;
		addComp(p, new JLabel());

		c.gridwidth = 2;
		addComp(p, okStatsBUT=new JButton(Localizer.get("Apply")));

		// listeners:
		modeCH.addItemListener(this);
		okTempBUT.addActionListener(this);
		okStatsBUT.addActionListener(this);
		autoComputeMCSWaitCB.addItemListener(this);
		unlimitedNbMeasBUT.addActionListener(this);

		updateControls(mode); // see "modeCH"
		this.getContentPane().add(p, BorderLayout.NORTH);
		pack();
	}

	private void addComp(JPanel p, Component comp){
		gridbag.setConstraints(comp,c);
		p.add(comp);
	}
	public void actionPerformed(ActionEvent evt){
		if (evt.getSource() == okTempBUT){
			okTemp();
		}
		else if (evt.getSource() == okStatsBUT){
			okStats();
		}
		else if (evt.getSource() == unlimitedNbMeasBUT){
			nbMeasTF.setText("-1");
		}
	}

	public void itemStateChanged(ItemEvent evt){
		if (evt.getSource() == modeCH){
			updateControls(modeCH.getSelectedIndex());
		}
		else if (evt.getSource() == autoComputeMCSWaitCB){
			mcsWaitTF.setEnabled(!autoComputeMCSWaitCB.isSelected());
		}
	}

	// enable/de-enable controls related to modeCH selected index
	private void updateControls(int mode){
		boolean b = (mode==1);
		kTSingleTF.setEnabled(!b);
		kTStartTF.setEnabled(b);
		kTEndTF.setEnabled(b);
		kTStepsTF.setEnabled(b);
		if (b){
			lbl1.setText("  ");
			lbl2.setText("=>");
		}
		else {
			lbl1.setText("=>");
			lbl2.setText("  ");
		}
	}

	private void okTemp(){
		if (modeCH.getSelectedIndex()==0){ // single kT
			algoThread.setSingleTemperature(Double.valueOf(kTSingleTF.getText()).doubleValue());
			controller.showStatus("kT ("+Localizer.get("fixed")+")="+kTSingleTF.getText());
		}
		else { // kT sweep
			// check nbmeas:
			int nbmeas = algoThread.getNumberMCSSteps();
			if (nbmeas == Integer.MAX_VALUE) {
				nbMeasTF.setText("1000");
				algoThread.setNumberMCSteps(1000);
			}
			algoThread.setTemperatureRange(
			    Double.valueOf(kTStartTF.getText()).doubleValue(),
			    Double.valueOf(kTEndTF.getText()).doubleValue(),
			    Integer.parseInt(kTStepsTF.getText()));
			controller.showStatus("kT ("+Localizer.get("sweep")+") : "+Localizer.get("From")+" "+kTStartTF.getText()+" "+Localizer.get("to")+" "+kTEndTF.getText() + " "+Localizer.get("in")+" " +
			           kTStepsTF.getText() + " "+Localizer.get("steps"));
		}
	}

	private void okStats(){
		String s=Localizer.get("Update")+" : ";
		// nbMeas:
		int nbmeas = Integer.parseInt(nbMeasTF.getText());
		algoThread.setNumberMCSteps(nbmeas);
		s += Localizer.get("stepCount")+" = " + (nbmeas < 1 ? Localizer.get("unlimited") : nbMeasTF.getText());
		// mcs wait:
		if (autoComputeMCSWaitCB.isSelected()){
			controller.getSamplesBag().setMCSWait(-1); // auto mode
			s += " ; "+Localizer.get("decorrelTime")+" = "+Localizer.get("Automatic");
		}
		else {
			controller.getSamplesBag().setMCSWait(Integer.parseInt(mcsWaitTF.getText()));
			s += " ; "+Localizer.get("decorrelTime")+" = " + mcsWaitTF.getText();
		}
		// mcTherm:
		controller.getSamplesBag().setThermalizationTime(Integer.parseInt(mcsThermTF.getText()));
		s += " ; "+Localizer.get("thermTime")+" = " + mcsThermTF.getText();
		controller.showStatus(s);
	}
	
	//[test] public static void main(String[] args){new ConfigurationPanel(1.0).show();}

}

