# name=ResSimUtils
# displaytouser=false
from hec.script import *
from hec.heclib.util import HecTime
import time, types
#==============================================================================
def hms(secs) :
  '''
  returns timespan in iih jjm kks format
  '''
  s = round(secs)
  h = s / 3600
  m = (s % 3600) / 60
  s %= 60
  return "%2.2dh %2.2dm %2.2ds" % (h, m, s)

#==============================================================================
def isWatershedOpened() :
	'''
	returns whether any watershed is opened
	'''
	return ResSim.isWatershedOpened()
	
#==============================================================================
def getWatershed() :
	'''
	returns hec.client.ClientWorkspace object or None
	'''
	return ResSim.getWatershed()
	
#==============================================================================
def getWatershedName() :
	'''
	returns string or None
	'''
	return ResSim.getWatershedName()
	
#==============================================================================
def openWatershed(watershedName) :
	'''
	returns hec.client.ClientWorkspace object or None
	'''
	return ResSim.openWatershed(watershedName)
	
#==============================================================================
def closeWatershed() :
	'''
	returns True or False
	'''
	return ResSim.closeWatershed()
	
#==============================================================================
def getCurrentModule() :
	'''
	returns hec.client.ClientMode object
	'''
	return ResSim.getCurrentModule()
	
#==============================================================================
def selectModule(moduleName) :
	'''
	returns hec.client.ClientMode object
	'''
	oldModule = getCurrentModule()
	oldModuleName = oldModule.getName()
	if oldModuleName == moduleName : 
		module = oldModule
	else :
		ResSim.selectModule(moduleName)
		module = ResSim.getCurrentModule()
		if not module or module.getName() != moduleName :
			ResSim.selectModule(oldModuleName)
			raise ValueError, "Invalid Module Name: %s" % moduleName
		
	return module
	
#==============================================================================
def getTimeWindow() :
	'''
	returns hec.heclib.util.HecTime objects for start and end time
	'''
	startTime = HecTime()
	endTime = HecTime()
	getCurrentModule().getTimeWindow(startTime, endTime)
	return startTime, endTime
	
#==============================================================================
def getTimeWindowString() :
	'''
	returns time window as a string
	'''
	return getCurrentModule().getTimeWindowString()
	
#==============================================================================
def getSimulation() :
	'''
	returns the current simulation
	'''
	simulation = selectModule("Simulation").getSimulation()
	if not simulation :
		raise Exception, "No simulation is currently open."
		
	return simulation
	
#==============================================================================
def getSimulationName() :
	'''
	returns the name of the current simulation
	'''
	return getSimulation().getName()
	
#==============================================================================
def openSimulation(simulationName) :
	'''
	causes the simulation module to open the specified simulation
	'''
	if not selectModule("Simulation").openSimulation(simulationName) :
		raise ValueError, "Simulation Not Found: %s" % simulationName
		
#==============================================================================
def getSimulationRun(alternativeName) :
	'''
	returns an hec.model.SimulationRun object
	'''
	run = selectModule("Simulation").getSimulationRun(alternativeName)
	if not run :
		raise ValueError, "Alternative Not Found: %s" % alternativeName
		
	return run 
	
#==============================================================================
def getSimulationRuns() :
	'''
	returns an array of hec.model.SimulationRun objects
	'''
	return selectModule("Simulation").getSimulationRuns()
	
#==============================================================================
def getSelectedSimulationRuns() :
	'''
	returns an array of hec.model.SimulationRun objects
	'''
	return selectModule("Simulation").getSelectedSimulationRuns()
	
#==============================================================================
def getAlternativeNames() :
	'''
	returns an array of strings
	'''
	names = []
	for run in getSimulationRuns() : names.append(run.getUserName())
	return names
	
#==============================================================================
def getSelectedAlternativeNames() :
	'''
	returns an array of strings
	'''
	names = []
	for run in getSelectedSimulationRuns() : names.append(run.getUserName())
	return names
	
#==============================================================================
def extractSimulationData() :
	'''
	performs new extract for the current simulation
	'''
	getSimulation().runExtract(getSimulation().getSimulationExtract())
	
#==============================================================================
def computeSimulationRun(simulationRun) :
	'''
	computes one alternative of a simulation
	'''
	selectModule("Simulation").computeRun(simulationRun, -1, True, True)
	
#==============================================================================
def getSimulationDSSFileName() :
	'''
	returns the full name of the DSS file for the current simulation
	'''
	return getSimulation().getOutputDSSFilePath()
	
#==============================================================================
def getFParts() :
	'''
	returns the F Parts for each alternative name
	'''
	fparts = {}
	for run in getSimulationRuns() :
		fparts[str(run)] = run.getKey()
	return fparts
	
#==============================================================================
def getFPart(alternativeName) :
	'''
	returns the F Part for the specified alternative name
	'''
	for run in getSimulationRuns() :
		if str(run) == alternativeName : 
			fpart = run.getKey()
			break
	else :
		raise ValueError, "Alternative Not Found: %s" % alternativeName
	return fpart
	
#==============================================================================
def runSimulation(simulationName, newExtract=False, *alternativeNames) :
	'''
	returns True if all (possibly specified)  simulations are executed
	
	if no alternativenames are specified, all alternatives are executed
	'''
	
	#---------------------#
	# open the simulation #
	#---------------------#
	openSimulation(simulationName)

	#-----------------------------------#
	# get the runs for the alternatives #
	#-----------------------------------#
	if not alternativeNames :
		#------------------#
		# all alternatives #
		#------------------#
		runs = getSimulationRuns()
	else :
		#------------------------#
		# specified alternatives #
		#------------------------#
		runs = []
		for alternativeName in alternativeNames :
			runs.append(getSimulationRun(str(alternativeName).strip()))

	if newExtract :
		print("===========================================")
		start = time.time()
		print(time.ctime(start))
		print("Extracting data for %s" % str(getSimulation()))
		print("===========================================")
	 	extractSimulationData()
		print("===========================================")
		end = time.time()
		print(time.ctime(end))
		print("%s extract finished in %s" % (str(getSimulation()), hms(end - start)))
		print("===========================================")
	#----------------------#
	# run the alternatives #
	#----------------------#
	for run in runs : 
		print
		print("===========================================")
		start = time.time()
		print(time.ctime(start))
		print("Computing %s" % run)
		print("===========================================")
	 	computeSimulationRun(run)
		print("===========================================")
		end = time.time()
		print(time.ctime(end))
		print("%s compute finished in %s" % (run, hms(end - start)))
		print("===========================================")

  	return True
  	
#==============================================================================
