from hec.heclib.dss import HecDss
from hec.heclib.util import HecTime
from hec.hecmath import TimeSeriesMath
from hec.lang import DSSPathString
from hec.io import TimeSeriesContainer

#Import for bonus part 3
from hec.script import Plot

### Functions ###
def getTimeSeriesFromDssFile(dssFileName):
	'''
	Gets all TimeSeriesContainers from the given DSS file name
	:param dssFileName: absolute path of the DSS file
	:type dssFileName: string
	:return tscList: list of all of the TimeSeriesContainers from the DSS file located at dssFileName
	:rtype tscList: list
	'''
	#Initialize a list object that will be populated with TimeSeriesContainers
	tscList = []
	
	## Open the DSS file using the HecDss class
	dssFile = HecDss.open(dssFileName)

	## Get condensed catalog from the DSS file
	catalog = dssFile.getCondensedCatalog()

	## Iterate through the catalog and add each TimeSeriesContainer to tscList
	for condensedReference in catalog:
		## Getting the string that represents the condensed catalog record
		pathName = condensedReference.toString()
		pathString = DSSPathString(pathName)
		pathString.setDPart("")
		pathNameMinusDPart = pathString.getPathname()
		## Using pathNameMinusDPart to get a TimeSeriesContainer from dssFile
		tsc = dssFile.get(pathNameMinusDPart)
		## Add tsc to tscList
		if isinstance(tsc, TimeSeriesContainer):
			tscList.append(tsc)
	dssFile.close()

	return tscList

def printMinValsFromTimeSeries(tscList):
	'''
	Iterates through a list of TimeSeriesContainers and prints out the minimum value data and pathname from each TimeSeriesContainer
	:param tscList: list of TimeSeriesContainers
	:type tscList: list
	:return None
	:rtype None
	'''
	### Step 2 ###
	## Iterate through tscList and print out minimum value and pathname
	for tsc in tscList:
		### Step 2a ###
		## Initialize TimeSeriesMath object
		#tsm = 
		### Step 2b ###
		## Get minimum value from TimeSeriesMath object
		#minValue = 
		### Step 2c ###
		## Get date of minimum value from TimeSeriesMath object
		#dateOfMinValue = 
		## Convert to HecTime
		htDateOfMinValue = HecTime()
		#htDateOfMinValue.set(dateOfMinValue)
		## Print date, value, and pathname
		#print(htDateOfMinValue, minValue, tsc)
		
	return None

def printMaxValsFromTimeSeries(tscList):
	'''
	Iterates through a list of TimeSeriesContainers and prints out the maximum value data and pathname from each TimeSeriesContainer
	:param tscList: list of TimeSeriesContainers
	:type tscList: list
	:return None
	:rtype None
	'''
	### Step 3 ###
	## Iterate through tscList and print out maximum value and pathname
	#for tsc in tscList:
		### Step 3a ###
		## Initialize TimeSeriesMath object
		#tsm = 
		### Step 3b ###
		## Get maximum value from TimeSeriesMath object
		#maxValue = 
		### Step 3c ###
		## Get date of minimum value from TimeSeriesMath object
		#dateOfMaxValue = 
		## Convert to HecTime
		#htDateOfMaxValue = HecTime()
		#htDateOfMaxValue.set(dateOfMaxValue)
		## Print date, value, and pathname
		#print(htDateOfMaxValue, maxValue, tsc)
		
	return None

def convertToPeriodAverageDailyTimeSeries(tscList):
	'''
	Iterates through a list of TimeSeriesContainers and converts them to period-average daily timeseries.
	Returns a list of period-average daily TimeSeriesContainers.
	:param tscList: list of TimeSeriesContainers
	:type tscList: list
	:return dailyTscList: list of TimeSeriesContainers with interval of 1DAY
	:rtype dailyTscList: list
	'''
	dailyTscList = []
	### Step 4 ###
	## Iterate through tscList and convert each tsc to period-average daily
	#for tsc in tscList:
		### Step 4a ###
		## Initialize TimeSeriesMath object
		#tsm = 
		### Step 4b ###
		## Convert tsm to a period-average daily timeseries. Use the transformTimeSeries function
		#dailyTsm = 
		### Step 4c ###
		## Get the TimeSeriesContainer from the TimeSeriesMath object
		#dailyTsc = 
		## Append to output list
		#dailyTscList.append(dailyTsc)
		
	return dailyTscList

def convertTimeSeries(tscList, interval, offset, functionType):
	'''
	Iterates through a list of TimeSeriesContainers and converts them according to the interval, offset, and functionType.
	Returns a list of converted TimeSeriesContainers.
	:param tscList: list of TimeSeriesContainers
	:param interval: new interval between timesteps
	:param offset: amount to offset, relative to original timeseries
	:param functionType: type of transform that will be applied to the timeseries
	:type tscList: list
	:type interval: string
	:type offset: string
	:type functionType: string
	:return convertedTscList: list of converted TimeSeriesContainers
	:rtype convertedTscList: list
	'''
	convertedTscList = []
	### Step 5 ###
	## Iterate through tscList and convert each tsc
	#for tsc in tscList:
		### Step 5a ###
		## Initialize TimeSeriesMath object
		#tsm = 
		### Step 5b ###
		## Convert tsm using the arguments: interval, offset, and functionType. Use the transformTimeSeries function
		#convertedTsm = 
		### Step 5c ###
		## Get the TimeSeriesContainer from the TimeSeriesMath object
		#convertedTsc = 
		## Append to output list
		#convertedTscList.append(convertedTsc)
		
	return convertedTscList

def getGreenRiverTimeSeriesFromDssFile(dssFileName):
	'''
	Gets filtered TimeSeriesContainers from the given DSS file name
	MUST contain "GREEN RIVER" in the A part
	:param dssFileName: absolute path of the DSS file
	:type dssFileName: string
	:return greenRiverTscList: list of all of the TimeSeriesContainers with A part of "GREEN RIVER"
	 from the DSS file located at dssFileName
	:rtype greenRiverTscList: list
	'''
	## Initialize a list object that will be populated with TimeSeriesContainers
	greenRiverTscList = []
	
	## Open the DSS file using the HecDss class
	dssFile = HecDss.open(dssFileName)

	## Get condensed catalog from the DSS file
	catalog = dssFile.getCondensedCatalog()

	## Iterate through the catalog and add each TimeSeriesContainer to tscList
	for condensedReference in catalog:
		## Getting the string that represents the condensed catalog record
		pathName = condensedReference.toString()
		pathString = DSSPathString(pathName)
		pathString.setDPart("")
		pathNameMinusDPart = pathString.getPathname()
		### BONUS Part 2 ###
		## Design an if statement that will be true if the A part of the pathString contains "GREEN RIVER"
		#if 
			## Using pathNameMinusDPart to get a TimeSeriesContainer from dssFile
			#tsc = dssFile.get(pathNameMinusDPart)
			## Add tsc to tscList
			#if isinstance(tsc, TimeSeriesContainer):
				#greenRiverTscList.append(tsc)
	dssFile.close()

	return greenRiverTscList

def cyclicAnalysisExample(dssFileName):
	'''
	Cyclic analysis example - analyzes The Dalles timeseries in the file provided and plots the data
	:param dssFileName: absolute path of the DSS file
	:type dssFileName: string
	:return None
	:rtype None
	'''
	### BONUS Part 3 ###
	## Open the DSS file
	dssFile = HecDss.open(dssFileName)
	
	## Create pathname of the timeseries that we want to analyze
	theDallesPathname = "//THE DALLES/FLOW-UNREG//1DAY/FLOODMODEL/"
	
	### BONUS Part 3a ###
	## Get the TimeSeriesContainer from the DSS file
	#theDallesTsc = 
	
	### BONUS Part 3b ###
	## Convert to a TimeSeriesMath object
	#theDallesTsm = 
	
	### BONUS Part 3c ###
	## Cyclic analysis
	#theDallesStats = 
	
	### BONUS Part 3d ###
	## Get the average, maximum, minimum, 25th percentile, and 75th percentile TimeSeriesMath objects
	#theDallesAverageTsm = 
	#theDallesMaxTsm = 
	#theDallesMinTsm = 
	#theDallesp25Tsm = 
	#theDallesp75Tsm = 
	
	### BONUS Part 3e ###
	## Convert TimeSeriesMath to TimeSeriesContainer
	#theDallesAverageTsc = 
	#theDallesMaxTsc = 
	#theDallesMinTsc = 
	#theDallesp25Tsc = 
	#theDallesp75Tsc = 
	
	### Plotting
	## Initialize plot with title
	#theDallesPlot = Plot.newPlot("The Dalles Outflow")
	## Add data to plot
	#theDallesPlot.addData(theDallesTsc)
	## Show the plot
	#theDallesPlot.showPlot()
	
	## Initialize statistics plot with title
	#theDallesStatsPlot = Plot.newPlot("The Dalles Outflow Cyclic Analysis")
	## Add data to plot
	#theDallesStatsPlot.addData(theDallesAverageTsc)
	#theDallesStatsPlot.addData(theDallesMaxTsc)
	#theDallesStatsPlot.addData(theDallesMinTsc)
	#theDallesStatsPlot.addData(theDallesp25Tsc)
	#theDallesStatsPlot.addData(theDallesp75Tsc)
	## Show the plot
	#theDallesStatsPlot.showPlot()
	
	## Close the DSS file
	dssFile.close()
	
	return None

### End Functions ###

### Main Code ###
print("Running script")

##Define workingDirectory (folder that the workshop was unzipped to)
workingDirectory = r'C:\Class\HEC API Scripting Basics\Workshop 2'"\\"

##Define DSS file name
dssFileName = workingDirectory + r'Workshop_2_Input.dss'

##Get all timeseries from DSS file and put into a list of TimeSeriesContainers
### Step 1 ###
## Use getTimeSeriesFromDssFile function to get a list of TimeSeriesContainers
#tscList = 

### TEST Step 1 ###
#print("\n---TEST Step 1---")
#for tsc in tscList:
#	print(tsc)
#print("---End TEST Step 1---")
### End TEST Step 1 ###

##Get the minimum value in each timeseries
### TEST Step 2 ###
#print("\n---TEST Step 2---")
#print("-Minimum values from instantaneous 15-minute timeseries-")
#printMinValsFromTimeSeries(tscList)
#print("---End TEST Step 2---")
### End TEST Step 2 ###

##Get the maximum value in each timeseries
### TEST Step 3 ###
#print("\n---TEST Step 3---")
#print("-Maximum values from instantaneous 15-minute timeseries-")
#printMaxValsFromTimeSeries(tscList)
#print("---End TEST Step 3---")
### End TEST Step 3 ###

##Convert to daily
### TEST Step 4 ###
#print("\n---TEST Step 4---")
#dailyTscList = convertToPeriodAverageDailyTimeSeries(tscList)
#print("Interval of period-average daily timeseries is: %s" %(dailyTscList[0].interval))
#print("Type of period-average daily timeseries is: %s" %(dailyTscList[0].type))
#print("---End TEST Step 4---")
### End TEST Step 4 ###

### TEST Step 5 ###
#print("\n---TEST Step 5---")
#print("-Minimum values from period-average daily timeseries-")
#printMinValsFromTimeSeries(dailyTscList)
#print("-Maximum values from period-average daily timeseries-")
#printMaxValsFromTimeSeries(dailyTscList)
#print("---End TEST Step 5---")
### End TEST Step 5 ###

##Find daily minimums and maximums
### TEST Step 6 ###
#print("\n---TEST Step 6---")
#dailyMinimumsTscList = convertTimeSeries(tscList, "1DAY", "0MIN", "MIN")
#dailyMaximumsTscList = convertTimeSeries(tscList, "1DAY", "0MIN", "MAX")
#print("First day of original 15-minute timeseries")
#for t,v in zip(tscList[0].times[0:96], tscList[0].values[0:96]):
#	ht = HecTime()
#	ht.set(t)
#	print(ht,v)

#print("\nFirst daily average: %.5f" %(dailyTscList[0].values[0]))
#print("First daily minimum: %.2f" %(dailyMinimumsTscList[0].values[0]))
#print("First daily maximum: %.2f" %(dailyMaximumsTscList[0].values[0]))
#print("---End TEST Step 6---")
### End TEST Step 6 ###

### BONUS Part 1 ###
#outputDssFileName = workingDirectory + r'Workshop_2_daily_Tsc_Output.dss'
#outputDssFile = HecDss.open(outputDssFileName)
#for tsc in dailyTscList:
#	tsc.fileName = outputDssFileName
#	outputDssFile.put(tsc)
#outputDssFile.close()
### End BONUS Part 1 ###

### BONUS Part 2 ###
#print("\n---Bonus Part 2---")
#greenRiverTscList = getGreenRiverTimeSeriesFromDssFile(dssFileName)
#print("\nAll timeseries:")
#print(tscList)
#print("\nGreen River timeseries:")
#print(greenRiverTscList)
#print("---End BONUS Part 2---")
### End BONUS Part 2 ###

### BONUS Part 3 ###
#print("\n---Bonus Part 3---")
#bonusPart3DssFileName = workingDirectory + r'Workshop_2_Bonus_Part_3_Input.dss'
#cyclicAnalysisExample(bonusPart3DssFileName)
#print("---End BONUS Part 3---")
### End BONUS Part 3 ###

print("Script finished!")
### End Main Code ###