package analysis.dynamicsim;
import graph.Graph;

import java.awt.Dimension;
import java.io.IOException;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
import javax.swing.JTabbedPane;
import javax.xml.stream.XMLStreamException;

import main.Gui;


public class DynamicSimulation {
	
	//simulator type
	private String simulatorType;
	
	//the simulator object
	private Simulator simulator = null;
	
	private boolean cancelFlag = false;	
	private boolean statisticsFlag = false;
	
	/**
	 * constructor; sets the simulator type
	 */
	public DynamicSimulation(String type) {
		
		simulatorType = type;
	}	
	
	public void simulate(String SBMLFileName, String outputDirectory, double timeLimit, 
			double maxTimeStep, double minTimeStep, long randomSeed, JProgressBar progress, double printInterval, 
			int runs, JLabel progressLabel, JFrame running, double stoichAmpValue, 
			String[] interestingSpecies, int numSteps, double relError, double absError, 
			String quantityType, Boolean genStats, JTabbedPane simTab) {
		
		String progressText = progressLabel.getText();
		statisticsFlag = genStats;
		
		try {
			
			progressLabel.setText("Generating Model . . .");
			running.setMinimumSize(new Dimension((progressLabel.getText().length() * 10) + 20, 
					(int) running.getSize().getHeight()));
			
			if (simulatorType.equals("cr"))
				simulator = new SimulatorSSACR(SBMLFileName, outputDirectory, timeLimit, 
						maxTimeStep, minTimeStep, randomSeed, progress, printInterval, stoichAmpValue, running, 
						interestingSpecies, quantityType);
			else if (simulatorType.equals("direct"))
				simulator = new SimulatorSSADirect(SBMLFileName, outputDirectory, timeLimit, 
						maxTimeStep, minTimeStep, randomSeed, progress, printInterval, stoichAmpValue, running, 
						interestingSpecies, quantityType);
			else if (simulatorType.equals("rk"))
				simulator = new SimulatorODERK(SBMLFileName, outputDirectory, timeLimit, 
						maxTimeStep, randomSeed, progress, printInterval, stoichAmpValue, running, 
						interestingSpecies, numSteps, relError, absError, quantityType);
			else if (simulatorType.equals("ufdirect"))
				simulator = new SimulatorSSADirectUnflatten(SBMLFileName, outputDirectory, timeLimit, 
						maxTimeStep, minTimeStep, randomSeed, progress, printInterval, stoichAmpValue, running, 
						interestingSpecies, quantityType);
		}
		catch (IOException e) {
			e.printStackTrace();
			return;
		}
		catch (XMLStreamException e) {
			e.printStackTrace();
			return;
		}		
		for (int run = 1; run <= runs; ++run) {
			
			if (cancelFlag == true)
				break;
			
			progressLabel.setText(progressText.replace(" (" + (run - 1) + ")","") + " (" + run + ")");
			running.setMinimumSize(new Dimension((progressLabel.getText().length() * 10) + 20, 
					(int) running.getSize().getHeight()));
	
			simulator.simulate();
			simulator.clear();
			
			if ((runs - run) >= 1)
				simulator.setupForNewRun(run + 1);
			
//			//garbage collect every twenty-five runs
//			if ((run % 25) == 0)
//				System.gc();
		}
		
		if (cancelFlag == false && statisticsFlag == true) {
			
			progressLabel.setText("Generating Statistics . . .");
			running.setMinimumSize(new Dimension(200,100));
			
			try {
				simulator.printStatisticsTSD();
			} catch (IOException e) {
				e.printStackTrace();
				return;
			}
		}
		if (simTab!=null) {
			for (int i = 0; i < simTab.getComponentCount(); i++) {
				if (simTab.getComponentAt(i).getName().equals("TSD Graph")) {
					if (simTab.getComponentAt(i) instanceof Graph) {
						((Graph) simTab.getComponentAt(i)).refresh();
					}
				}
			}
		}
	}
	
	/**
	 * cancels the simulation on the next iteration
	 * called from outside the class when the user closes the progress bar dialog
	 */
	public void cancel() {
		
		if (simulator != null) {
			
			JOptionPane.showMessageDialog(Gui.frame, "Simulation Canceled",
					"Canceled", JOptionPane.ERROR_MESSAGE);
			
			simulator.cancel();
			
			cancelFlag = true;
		}
	}
}
@@ -461,16 +461,66 @@
 = null;%0A
+%09private HierarchicalSimulator hSimulator = null;%0A
 %09%0A%09priva
@@ -2234,10 +2234,17 @@
 ls(%22
-uf
+hierarchy
 dire
@@ -2245,33 +2245,34 @@
 hydirect%22))%0A%09%09%09%09
-s
+hS
 imulator = new S
@@ -2292,17 +2292,20 @@
 rect
-Unflatten
+Hierarchical
 (SBM
@@ -2937,16 +2937,44 @@
 t()));%0A%09
+%09%09if(simulator != null)%0A%09%09%09%7B
 %0A%09%09%09simu
@@ -3085,16 +3085,182 @@
  1);%0A%09%09%09
+%7D%0A%09%09%09else if(hSimulator != null)%0A%09%09%09%7B%0A%09%09%09%09hSimulator.simulate();%0A%09%09%09%09hSimulator.clear();%0A%09%09%09%09%0A%09%09%09%09if ((runs - run) %3E= 1)%0A%09%09%09%09%09hSimulator.setupForNewRun(run + 1);%0A%09%09%09%7D
 %0A//%09%09%09//
@@ -3530,25 +3530,122 @@
 %09%09try %7B%0A%09%09%09%09
-s
+if(simulator != null)%0A%09%09%09%09%09simulator.printStatisticsTSD();%0A%09%09%09%09else if(hSimulator != null)%0A%09%09%09%09%09hS
 imulator.pri

Add support for hierarchical simulator that uses libsbml.