Index: /issm/trunk-jpl/src/m/solve/solve.js
===================================================================
--- /issm/trunk-jpl/src/m/solve/solve.js	(revision 22830)
+++ /issm/trunk-jpl/src/m/solve/solve.js	(revision 22831)
@@ -1,67 +1,75 @@
-function solve(md,solutionstring){
-//SOLVE - apply solution sequence for this model
-//
-//   Usage:
-//      solve(md,solutionstring,varargin)
-//      where varargin is a lit of paired arguments of string OR enums
-//
-//   solution types available comprise:
-//		 - 'Stressbalance'      or 'sb'
-//		 - 'Masstransport'      or 'mt'
-//		 - 'Thermal'            or 'th'
-//		 - 'Steadystate'        or 'ss'
-//		 - 'Transient'          or 'tr'
-//		 - 'Balancethickness'   or 'mc'
-//      - 'Balancevelocity'   or 'bv'
-//		 - 'BedSlope'           or 'bsl'
-//		 - 'SurfaceSlope'       or 'ssl'
-//		 - 'Hydrology'          or 'hy'
-//      - 'DamageEvolution'   or 'da'
-//		 - 'Gia'                or 'gia'
-//		 - 'Sealevelrise'       or 'slr'
-//
-//  extra options:
-//      - loadonly    : does not solve. only load results
-//      - runtimename : true or false (default is true), makes name unique
-//      - checkconsistency : 'yes' or 'no' (default is 'yes'), ensures checks on consistency of model
-//      - restart: 'directory name (relative to the execution directory) where the restart file is located.
-//      - callback: callback function to be called upon receiving the results from the server, or local computations. 
-//
-//   Examples:
-//      md=solve(md,'Stressbalance');
-//      md=solve(md,'sb');
-
-	if(typeof solutionstring !== 'string') {
+function solve(md, solutionstring) { //{{{
+/**
+ * SOLVE - apply solution sequence for this model
+ *
+ *	Usage:
+ *		solve(md, solutionstring, varargin);
+ *		where varargin is a list of paired arguments of string OR enums
+ *
+ *	solution types available comprise:
+ *		- 'Stressbalance'		or 'sb'
+ *		- 'Masstransport'		or 'mt'
+ *		- 'Thermal'				or 'th'
+ *		- 'Steadystate'			or 'ss'
+ *		- 'Transient'			or 'tr'
+ *		- 'Balancethickness'	or 'mc'
+ *		- 'Balancevelocity'		or 'bv'
+ *		- 'BedSlope'			or 'bsl'
+ *		- 'SurfaceSlope'		or 'ssl'
+ *		- 'Hydrology'			or 'hy'
+ *		- 'DamageEvolution'		or 'da'
+ *		- 'Gia'					or 'gia'
+ *		- 'Sealevelrise'		or 'slr'
+ *
+ *	extra options:
+ *		- loadonly    		: do not solve, only load results
+ *		- runtimename 		: true or false (default is true), makes name unique
+ *		- checkconsistency 	: 'yes' or 'no' (default is 'yes'), ensures checks on consistency of model
+ *		- restart			: directory name (relative to the execution directory) where the restart file is located
+ *		- successCallback	: callback function to be called on success
+ *		- errorCallback		: callback function to be called on error
+ *
+ *	reporting:
+ *		With no optional arguments for reporting, progress and error reporting is written to the DOM element with ID 'solve-button'.
+ *		- solveButtonId		: overrides default solve button ID
+ *		- callout			: Callout to report progress/errors to; overrides reporting to solve button
+ *		- withProgressBar	: reports progress of certain solution stages with a progress bar; will not display if a Callout has not been provided
+ *
+ *	Examples:
+ *		md = solve(md, 'Stressbalance');
+ *		md = solve(md, 'sb');
+ */
+	if (typeof solutionstring !== 'string') {
 		throw Error(sprintf("%s\n", "ISSM's solve function only accepts strings for solution sequences. Type help solve to get a list of supported solutions."));
 	}
 
 	//recover and process solve options
-	if((solutionstring.toLowerCase() === 'sb') || (solutionstring.toLowerCase() === 'stressbalance')){
+	if ((solutionstring.toLowerCase() === 'sb') || (solutionstring.toLowerCase() === 'stressbalance')) {
 		solutionstring = 'StressbalanceSolution';
-	}else if((solutionstring.toLowerCase() === 'mt') || (solutionstring.toLowerCase() === 'masstransport')){
+	} else if ((solutionstring.toLowerCase() === 'mt') || (solutionstring.toLowerCase() === 'masstransport')) {
 		solutionstring = 'MasstransportSolution';	
-	}else if((solutionstring.toLowerCase() === 'th') || (solutionstring.toLowerCase() === 'thermal')){
+	} else if ((solutionstring.toLowerCase() === 'th') || (solutionstring.toLowerCase() === 'thermal')) {
 		solutionstring = 'ThermalSolution';
-	}else if((solutionstring.toLowerCase() === 'st') || (solutionstring.toLowerCase() === 'steadystate')){
+	} else if ((solutionstring.toLowerCase() === 'st') || (solutionstring.toLowerCase() === 'steadystate')) {
 		solutionstring = 'SteadystateSolution';
-	}else if((solutionstring.toLowerCase() === 'tr') || (solutionstring.toLowerCase() === 'transient')){
+	} else if ((solutionstring.toLowerCase() === 'tr') || (solutionstring.toLowerCase() === 'transient')) {
 		solutionstring = 'TransientSolution';
-	}else if((solutionstring.toLowerCase() === 'mc') || (solutionstring.toLowerCase() === 'balancethickness')){
+	} else if ((solutionstring.toLowerCase() === 'mc') || (solutionstring.toLowerCase() === 'balancethickness')) {
 		solutionstring = 'BalancethicknessSolution';
-	}else if((solutionstring.toLowerCase() === 'bv') || (solutionstring.toLowerCase() === 'balancevelocity')){
+	} else if ((solutionstring.toLowerCase() === 'bv') || (solutionstring.toLowerCase() === 'balancevelocity')) {
 		solutionstring = 'BalancevelocitySolution';
-	}else if((solutionstring.toLowerCase() === 'bsl') || (solutionstring.toLowerCase() === 'bedslope')){
+	} else if ((solutionstring.toLowerCase() === 'bsl') || (solutionstring.toLowerCase() === 'bedslope')) {
 		solutionstring = 'BedSlopeSolution';
-	}else if((solutionstring.toLowerCase() === 'ssl') || (solutionstring.toLowerCase() === 'surfaceslope')){
+	} else if ((solutionstring.toLowerCase() === 'ssl') || (solutionstring.toLowerCase() === 'surfaceslope')) {
 		solutionstring = 'SurfaceSlopeSolution';
-	}else if((solutionstring.toLowerCase() === 'hy') || (solutionstring.toLowerCase() === 'hydrology')){
+	} else if ((solutionstring.toLowerCase() === 'hy') || (solutionstring.toLowerCase() === 'hydrology')) {
 		solutionstring = 'HydrologySolution';
-	}else if((solutionstring.toLowerCase() === 'da') || (solutionstring.toLowerCase() === 'damageevolution')){
+	} else if ((solutionstring.toLowerCase() === 'da') || (solutionstring.toLowerCase() === 'damageevolution')) {
 		solutionstring = 'DamageEvolutionSolution';
-	}else if((solutionstring.toLowerCase() === 'gia') || (solutionstring.toLowerCase() === 'gia')){
+	} else if ((solutionstring.toLowerCase() === 'gia') || (solutionstring.toLowerCase() === 'gia')) {
 		solutionstring = 'GiaSolution';
-	}else if((solutionstring.toLowerCase() === 'slr') || (solutionstring.toLowerCase() === 'sealevelrise')){
+	} else if ((solutionstring.toLowerCase() === 'slr') || (solutionstring.toLowerCase() === 'sealevelrise')) {
 		solutionstring = 'SealevelriseSolution';
-	}else{
+	} else {
 		throw Error(sprintf("%s%s%s\n",'solutionstring ',solutionstring,' not supported!'));
 	}
@@ -131,11 +139,9 @@
 	
 	// Default: do nothing if no success callback function requested
-	function successCallback() {
+	function successCallbackDefault() {
 		solving = false;
 	}; 
 	
-	if (options.getfieldvalue('successCallback',false)){
-		successCallback = options.getfieldvalue('successCallback');
-	}
+	let successCallback = options.getfieldvalue('successCallback', successCallbackDefault);
 	//}}}
 	
@@ -147,11 +153,9 @@
 	
 	// Default: do nothing if no error callback function requested
-	function errorCallback() {
+	function errorCallbackDefault() {
 		solving = false;
 	}; 
 	
-	if (options.getfieldvalue('errorCallback',false)){
-		errorCallback = options.getfieldvalue('errorCallback');
-	}
+	let errorCallback = options.getfieldvalue('errorCallback', errorCallbackDefault);
 	//}}}
 	
@@ -163,12 +167,29 @@
 	
 	// Default: update #solve-button element with progress updates
-	var solveButtonId = '#solve-button';
-	
-	if (options.getfieldvalue('solveButtonId', false)){
-		solveButtonId = options.getfieldvalue('solveButtonId');
-	}
-	//}}}
-
-	if (cluster.classname() == 'local'){  //{{{
+	let solveButtonId = options.getfieldvalue('solveButtonId', '#solve-button');
+	//}}}
+	
+	
+	/*
+		Set Callout
+	*/
+	//{{{
+	var callout = {};
+	
+	// Default: Callout is an empty object
+	callout = options.getfieldvalue('callout', {});
+	//}}}
+	
+	
+	/*
+		Set progress bar display boolean
+	*/
+	//{{{
+	// Default: no progress bar; NOTE: must have supplied a callout for progress bar to display
+	let withProgressBar = options.getfieldvalue('withProgressBar', false);
+	//}}}
+
+
+	if (cluster.classname() == 'local'){ //{{{
 
 		/*We are running locally on the machine, using the issm module:*/
@@ -182,5 +203,5 @@
 			
 		//Load results: 
-		md = loadresultsfrombuffer(md,outputbuffer,outputbuffersize); 
+		md = loadresultsfrombuffer(md, outputbuffer, outputbuffersize); 
 		
 		// Call success callback 
@@ -188,14 +209,26 @@
 
 		return md;
-
-	} //}}}
-	else { //{{{
-
-		/*We are running somewhere else on a computational server. Send the buffer to that server and retrieve output: */
+	//}}}
+	} else { //{{{
+		// We are running somewhere else on a computational server. Send the buffer to that server and retrieve output.
 		console.log('running issm remotely');
-		cluster.UploadAndRun(md,successCallback,errorCallback,solveButtonId,fid,toolkitsstring,solutionstring,md.miscellaneous.name,md.priv.runtimename);
+		
+		cluster.UploadAndRun(
+			md, 
+			fid, 
+			toolkitsstring, 
+			solutionstring, 
+			md.miscellaneous.name, 
+			md.priv.runtimename,
+			successCallback, 
+			errorCallback, 
+			solveButtonId, 
+			callout, 
+			withProgressBar
+		);
 
 		return md;
-
-	} //}}}
+	//}}}
+	}
+//}}}
 }
