"""
Autors: Rinalds
"""
CreateLayout('S11 and other charts')
pythonView1 = CreateView('PythonView')
SetActiveView(renderView1)
layout2 = GetLayoutByName("S11 and other charts")
RenameLayout('3D View', GetLayoutByName("Layout #1"))
#AssignViewToLayout(view=pythonView1, layout=layout2, hint=0)
layout2.AssignView(0, pythonView1)

timeKeeper1 = GetTimeKeeper()
times = timeKeeper1.TimestepValues
if len(times) == 1: # Single frequency
	f1 = str(times[0] * 0.9)
	f2 = str(times[0] * 1.1)
else: # Multi frequency simulation
	f1 = str(times[0])
	f2 = str(times[-1])

pythonView1.Script = '''frequency_range = [%s, %s] #(MHz)
# Click anywhere on the charts
# to update the view

plot1 = ["", ""]
plot2 = ["", ""]
plot3 = ["", ""]
plot4 = ["", ""]

"""
example:  plot1 = ["billet", "Active_Power_[W]"]

Common parameter names:
Active_Power_[W]
Apparent_Power_[VA]
Magnetic_Energy_[J]
Source_Current.RMS_[A]
Voltage.RMS_[V]
Inductance_[uH]
Resistance_[Ohm]

"""

#CONFIG
xAxName = "Frequency" #Default x axis title
xAxUnit = "Hz" #Default x axis unit

lineWidth = 0.5 #Plot line thickness
markerSize = 3.0 #Plot point size

legendLoc = "best" #legend location
legendSize = 10 #Font size for legend

threshold = 0.02 #If the relative delta of the data is below this, the y axis is scaled
scaleCoef = 4.0 #By how much the y-axis is scales if data has minute delta.

spRows = 2 #Number of subplot rows
spCols = 2 #Number of subplot columns

#IMPORTS
import re
import json
import os
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.ticker import EngFormatter
from paraview import python_view

#FILE DIRECTORIES
caseDir = os.getcwd()
resultDir = os.path.join(caseDir, 'results')
resultData = json.load(open(os.path.join(resultDir, 'resultData.json'), encoding='utf-8'))
globalResultsData = json.load(open(os.path.join(resultDir, 'globalResultsFile.json'), encoding='utf-8'))

#DATA FUNCTIONS
def getTimeValues():
	try:
		bc = globalResultsData["bcs"][0]["time"]["timeValues"]
		return(bc)
	except:
		print("Could not get time values!")

def getBCValues(name, post):
	try:
		bcs = globalResultsData["bcs"]
		for bc in bcs:
			if bc["name"] == name:
				for p in bc["postValues"]:
					if p["postName"] == post:
						return(p["values"])
	except:
		pass

def getDomainValues(name, post):
	try:
		domainList = globalResultsData["domains"]
		for domain in domainList:
			if domain["name"] == name:
				for p in domain["postValues"]:
					if p["postName"] == post:
						return(p["values"])
	except:
		pass

def getValues(name, post):
	d = getDomainValues(name, post)
	if d is not None:
		return(d)
	else:
		d = getBCValues(name, post)
		return(d)

def getInductorValues(param):
	try:
		terminals = resultData['boundariesByType']["physicsElectromagnetics"]["current"]
		if terminals:
			vals = getBCValues(terminals[0] + "_CH", param)
			return(vals)
	except:
		pass

	try:
		terminals2 = resultData['domainsByRole']["inductor"]
		if len(terminals2) == 1:
			vals = getDomainValues(terminals2[0], param)
			return(vals)
		else:
			vals = getDomainValues(terminals2[0] + "...", param)
			return(vals)
	except:
		pass

#PLOT FUNCTIONS
def plotBegin():
	newFigure = plt.figure()
	matplotlib.use #global plot style
	plt.style.use('ggplot') #global plot style
	return(newFigure)

def plot(rows, cols, pos, x, y, xUnit, yUnit, title, xlabel, ylabel, leg):
	if ylabel == "Inductance":
		my_new_list = [i / 1000 for i in y]
		y = my_new_list
		new_unit = yUnit[1:]
		yUnit = new_unit

	ax = fig.add_subplot(rows, cols, pos)
	ax.tick_params(axis="both", direction = "in", length = 4, color='#DDDDDD')
	ax.plot(x, y, linewidth=lineWidth, marker="o", markersize=markerSize, label=leg)
	ax.xaxis.set_major_formatter(EngFormatter(unit=xUnit))
	ax.yaxis.set_major_formatter(EngFormatter(unit=yUnit))
	ax.set_title(title, color='#222222', pad=16)
	ax.set_xlabel(xlabel)
	ax.set_ylabel(ylabel)
	ax.grid(color='#DDDDDD', linestyle='-', linewidth=0.5)
	ax.tick_params(axis="both", direction = "in", length = 4, color='#DDDDDD', labelsize=9)
	ax.set_facecolor("#FFFFFF")

	if max(y) == 0:
		delta_rel = 0
	else:
		delta_rel = (max(y) - min(y)) / max(y)
	if 0.00001 < delta_rel < threshold:
		ax.set_ylim([min(y)*(1.0 - delta_rel * scaleCoef), max(y)* (1.0 + delta_rel * scaleCoef)])
	if frequency_range:
		ax.set_xlim([i*10**6 for i in frequency_range])	
	return(ax)

def plotAddLine(ax, yValues, legend, colour):
	ax.plot(x, yValues, linewidth=lineWidth, marker="o", markersize=markerSize, label=legend, color=colour)
	ax.legend(loc=legendLoc, frameon=False, prop={'size': legendSize})

def plotGlobals():
	fig.tight_layout(pad=-0.5, w_pad=-5.5, h_pad=0.0, rect=[-0.06,0.0,0.99,1]) #kaut kas ir pakalaa, tadel sis to itkaa salabo
										  #(left, bottom, right, top)

def tryPlot(name, func):
	if name not in locals():
		try:
			func
		except:
			print("exception!")
	else:
		print(name + " not in locals()")

#USER PLOT FUNCTIONS
def getName_Unit(param):
	unit = re.search('_\[(.*)\]', param).group(1)
	name = re.search('(.*)_', param).group(1)
	name = name.replace("_", " ")
	return(name, unit)

def cPlot(plot_list, pos):
	try:
		domainName = plot_list[0]
		paramName = plot_list[1]
		x = getTimeValues()
		y = getValues(domainName, paramName)
		xUnit = xAxUnit
		rows = spRows
		cols = spCols
		xlabel = xAxName
		ylabel, yUnit = getName_Unit(paramName)
		title = ylabel + " in " + domainName
		ax = plot(rows, cols, pos, x, y, xUnit, yUnit, title, xlabel, ylabel, "none")
		return(ax)
	except:
		ax = fig.add_subplot(spRows, spCols, pos)
		ax.annotate('Please check that the custom plot inputs are correct.\\n It should be: plotN = ["domain name", "parameter name"]\\nwhere the domain name and parameter names\\n are taken from the .csv results', (0.05, 0.48))
		return(ax)

#AUTOMATIC PLOTS
for i in ["uniformPort","coaxialPort"]:
	if i in resultData['boundariesByType']["physicsMicrowaves"]:
		if resultData['boundariesByType']["physicsMicrowaves"][i]: # if not empty
			portName = resultData['boundariesByType']["physicsMicrowaves"][i]


#dielectricName = resultData['domainsByRole']["inductor"]
#otherName = resultData['domainsByRole']["other"]

x1 = getTimeValues()
x = [element * 10**6 for element in x1]

def plotAuto1():
	S11 = getBCValues(portName[-1], "S11")
	ax = plot(spRows, spCols, 1, x, S11, xAxUnit, "dB", "S-Parameters", xAxName, " ", "S11")
	#ax.set_ylim(ymin=0)


	colors = ['#e69567', '#318251', '#AAAAAA'] * 20
	i = 1
	bcs = globalResultsData["bcs"]
	bcs = globalResultsData["bcs"]
	for bc in bcs:
		if bc["name"] == portName[-1]:
			for p in bc["postValues"]:
				if p["postName"].startswith("S") and not(p["postName"].startswith("S11")):
					plotAddLine(ax, p["values"], p["postName"], colors[i])
					i += 1


	# if wpName:
	#     try:
	#         wpPower = getDomainValues(wpName[-1], "Active_Power_[W]")
	#         plotAddLine(ax, wpPower, "Workpiece power", '#848d9a')
	#     except:
	#         pass

	# if indName:
	#     try:
	#         indPower = getDomainValues(indName[-1], "Active_Power_[W]")
	#         plotAddLine(ax, indPower, "Inductor power", '#e69567')
	#     except:
	#         pass


	# if concName:
	#     try:
	#         concPower = getDomainValues(concName[-1], "Active_Power_[W]")
	#         plotAddLine(ax, concPower, "Concentator power", '#318251')
	#     except:
	#         pass

	# if otherName:
	#     try:
	#         otherPower = getDomainValues(otherName[-1], "Active_Power_[W]")
	#         plotAddLine(ax, otherPower, "Other domain power", '#AAAAAA')
	#     except:
	#         pass

def plotAuto2():
	VSWR = getBCValues(portName[-1], "VSWR")
	ax2 = plot(spRows, spCols, 2, x, VSWR, xAxUnit, "", "VSWR", xAxName, " ", "no_label")

def plotAuto3():
	impedance = getBCValues(portName[-1], "Antenna_Impedance[Ohm]")
	if not impedance:
		impedance = getBCValues(portName[-1], "Port_Impedance[Ohm]")

	ax2 = plot(spRows, spCols, 3, x, impedance, xAxUnit, "Ohm", "Impedance, Resistance, Reactance", xAxName, " ", "Antenna Impedance Z")

	reactance = getBCValues(portName[-1], "Antenna_Reactance[Ohm]")
	if not reactance:
		reactance = getBCValues(portName[-1], "Port_Reactance[Ohm]")

	plotAddLine(ax2, reactance, "Antenna Reactance X", '#2c7fbf')

	resistance = getBCValues(portName[-1], "Antenna_Resistance[Ohm]")
	if not resistance:
		resistance = getBCValues(portName[-1], "Port_Resistance[Ohm]")

	plotAddLine(ax2, resistance, "Antenna Resistance R", '#324853')

def plotAuto4():
	power = getBCValues(portName[-1], "Accepted_Power[W]")
	ax2 = plot(spRows, spCols, 4, x, power, xAxUnit, "W", "Accepted Power", xAxName, " ", "no_label")


#FINAL EXECUTION
fig = plotBegin() #variable fig is used in the plot functions

if plot1[0] and plot1[1]:
	ax1 = cPlot(plot1, 1)
else:
	plotAuto1()

if plot2[0] and plot2[1]:
	ax2 = cPlot(plot2, 2)
else:
	plotAuto2()

if plot3[0] and plot3[1]:
	ax3 = cPlot(plot3, 3)
else:
	plotAuto3()

if plot4[0] and plot4[1]:
	ax4 = cPlot(plot4, 4)
else:
	plotAuto4()

plotGlobals()

#LIVE RENDER
def render(view, width, height):
	DPI = fig.get_dpi()
	fig.set_size_inches(width/float(DPI),height/float(DPI))
	return python_view.figure_to_image(fig)

plt.close('all')
''' % (f1, f2)

extractBlock11.BlockIndices = [0] # Note: Cannot open state file without this
extractBlock11.BlockIndices = [1]
RenderAllViews()

