/*  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;

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

import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;
import java.text.NumberFormat;
import java.util.Locale;

/**
 * UI controller for Wang-Landau algorithms. This is the hub that holds together several classes involved in the simulation, including
 * the algorithm thread, graphs and widgets, event listeners, and data bags.
 */
public class WLApplet extends AbstractApplet  {

	private WLSimulationCustomizer configurationPanelFR;
	
	////////////////////////////////////////////////////////

	public WLApplet(){
		super();
	}
	
	public WLApplet(String[] args){
		super(args);
	}

	/**
	 * Returns information about the parameters that are understood by this applet.
	 */
	public String[][] getParameterInfo(){
		String pinfo[][] = {
			//{"algorithm", "\"metropolis\"|\"wolff\"", Localizer.get("paramInfo1")},
			{"Q",	"2-11",		Localizer.get("paramInfo2")},
			{"L", 	"int", 	Localizer.get("paramInfo3")},
			{"MCTherm", 	"int", 	Localizer.get("paramInfo4")},
			{"MCMeas", 	"int", 	Localizer.get("paramInfo5")},
			{"WLweight", "double", Localizer.get("paramInfo13")},
			{"maxFlatness", "double", Localizer.get("paramInfo14")},
			//{"binWidth", "double", Localizer.get("paramInfo15")},
			{"kTstart",  "double",   Localizer.get("paramInfo8")}, // reweighting
			{"kTend",  "double",   Localizer.get("paramInfo9")},
			{"kTsteps",  "int",   Localizer.get("paramInfo10")},
			{"lang",  "en|fr",   Localizer.get("paramInfo11")},
			{"model",  "Potts|AFIsing",   Localizer.get("paramInfo12")}
		};
		return pinfo;
	}

	/**
	 * Called by the browser or applet viewer to inform this applet that it has been loaded into the system.
	 */
	public void init(){
		//System.out.println("init");
		String lang=getParameter("lang");
		if (lang==null || lang.equals("")) lang="en";
		Localizer.init(new Locale(lang));

		//this.graphPreferredSize = new Dimension(getSize().width/4, getSize().height/4);

		String paramQ, paramL;
		String paramMCTherm,paramMCMeas, paramModel,paramKTstart, paramKTend, paramKTsteps;
		String paramWeight, paramMaxFlatness;
		// String paramBinWidth;
		paramQ = getParameter("Q");
		paramL = getParameter("L");
		paramKTstart=getParameter("kTstart");
		paramKTend=getParameter("kTend");
		paramKTsteps=getParameter("kTsteps");
		paramWeight=getParameter("WLweight");
		paramMaxFlatness=getParameter("maxFlatness");
		//paramBinWidth=getParameter("binWidth");
		paramMCTherm=getParameter("MCTherm");
		paramMCMeas=getParameter("MCMeas");
		paramModel=getParameter("model");
		
		int defQ=5, defL=10,defMCTherm=100,defMCMeas=10000,defKTsteps=10;
		double defKTstart=0.2, defKTend=1.0, defWeight=10.0, defMaxFlatness=0.5;
		//double defBinWidth=1.0;
		try {
			if (paramQ!=null) defQ = Integer.parseInt(paramQ);
			if (paramL!=null) defL = Integer.parseInt(paramL);
			if (paramKTstart!=null) defKTstart = Double.valueOf(paramKTstart).doubleValue();
			if (paramKTend!=null) defKTend = Double.valueOf(paramKTend).doubleValue();
			if (paramKTsteps!=null) defKTsteps = (int)Double.valueOf(paramKTsteps).doubleValue();
			if (paramMCTherm!=null) defMCTherm = (int)Double.valueOf(paramMCTherm).doubleValue();
			if (paramMCMeas!=null) defMCMeas = (int)Double.valueOf(paramMCMeas).doubleValue() + defMCTherm;
			if (paramWeight!=null) defWeight = Double.valueOf(paramWeight).doubleValue();
			if (paramMaxFlatness!=null) defMaxFlatness = Double.valueOf(paramMaxFlatness).doubleValue();
			//if (paramBinWidth!=null) defBinWidth = Double.valueOf(paramBinWidth).doubleValue();
		}
		catch (NumberFormatException nfe){
			showStatus(nfe.toString());
		}
		if (paramModel!=null) {
			if (paramModel.equals("AFIsing")) lattice = new AFIsingLattice(defL);
			else lattice = new PottsLattice(defQ, defL); // "Potts" by default
		}
		if (lattice==null) lattice = new PottsLattice(defQ, defL);

		// init data bags:
		samplesBag = new SamplesBag(defMCTherm);
		// init algo thread:
		//algoThread = new WLSimulationThread(this,defKTstart, defKTend, defKTsteps,defBinWidth,defWeight,defMaxFlatness);
		algoThread = new WLSimulationThread(this,defKTstart, defKTend, defKTsteps,defWeight,defMaxFlatness);
		algoThread.setNumberMCSteps(defMCMeas);

		configurationPanelFR = new WLSimulationCustomizer(this, (WLSimulationThread)algoThread);
		initUI();
	}

	////////////////////////////////////////////////////
	//// UI
	////////////////////////////////////////////////////

	
	public void toggleConfigurationPanel(){
		configurationPanelFR.setVisible(!configurationPanelFR.isVisible());
	}
	
	public WLSimulationCustomizer getSimulationCustomizer(){
		return configurationPanelFR;
	}
	
	///////////////////////////////////////////////////////////////
	//// Accessors
	///////////////////////////////////////////////////////////////

	public boolean isRGActive(){
		return false;
	}
	
	////////////////////////////////////////
	/// stand-alone mode
	////////////////////////////////////////
	public static void main(String[] args){
		WLApplet a = new WLApplet(args);
	}
}

