import matplotlib.pyplot as plt
import matplotlib.patches as patches
import matplotlib.lines as lines
import seaborn as sns
import numpy
import matplotlib as mpl
import matplotlib.pyplot as plt
import plotly.plotly as py
import plotly.graph_objs as go

from ._nmrPlotting import nmrRangeHelper, plotlyRangeHelper

def plotWaterResonance(nmrData, savePath=None, figureFormat='png', dpi=72, figureSize=(11,7)):
	"""
	plotWaterResonance(nmrData, **kwargs)

	Plot the water region to be cut from the spectrum along with spectra failing water region checks.

	:param NMRDataset nmrData: Dataset to plot
	:param savePath: If ``None`` draw interactively, otherwise save to this path
	:type savePath: None or str
	"""
	bounds = (min(nmrData.Attributes['waterPeakCheckRegion'][0]), max(nmrData.Attributes['waterPeakCheckRegion'][1]))

	localPPM, ppmMask, meanSpectrum, lowerPercentile, upperPercentile = nmrRangeHelper(nmrData, bounds, percentiles=(5, 95))

	globalMask = numpy.ix_(nmrData.sampleMask, ppmMask)

	fig, ax = plt.subplots(1, 1, sharey=True, figsize=figureSize, dpi=dpi)

	ax.plot(localPPM, meanSpectrum, color=(0.46,0.71,0.63))

	ax.fill_between(localPPM, lowerPercentile, y2=upperPercentile, color=(0,0.4,.3,0.2))

	##
	# Plot failures
	##
	for i in range(nmrData.noSamples):

		if nmrData.sampleMetadata.loc[i, 'WaterPeakFail']:
				ax.plot(localPPM, nmrData.intensityData[i, ppmMask], color=(0.8,0.05,0.01,0.7))

		if nmrData.sampleMetadata.loc[i, 'WaterPeakFail']:
			ax.plot(localPPM, nmrData.intensityData[i, ppmMask], color=(0.05,0.05,0.8,0.7))


	ax.axvspan(max(nmrData.Attributes['waterPeakCheckRegion'][0]),
			   min(nmrData.Attributes['waterPeakCheckRegion'][1]), facecolor='k', alpha=0.2)
	# ax.set_xlabel('ppm')
	ax.invert_xaxis()
	ax.get_yaxis().set_ticks([])
	##
	# Set up legend
	##
	variance = patches.Patch(color=(0,0.4,.3,0.2), label='Variance about the median')
	water = patches.Patch(color=(0,0,0,0.2), label='Water region to be removed')
	failures = lines.Line2D([], [], color=(0.8,0.05,0.01,0.7), marker='',
									label='Water resonances failed on area')

	plt.legend(handles=[variance, water, failures])

	if savePath:
		plt.savefig(savePath, bbox_inches='tight', format=figureFormat, dpi=dpi)
		plt.close()
	else:
		plt.show()


def plotWaterResonanceInteractive(nmrData):
	"""
	Ploty interactive version of :py:func:`plotWaterResonance`

	Plot the water region to be cut from the spectrum along with spectra failing water region checks.

	:param NMRDataset nmrData: Dataset to plot
	:returns: Plotly figure object to plot with iPlot
	"""
	data = []
	failed = []

	bounds = (min(nmrData.Attributes['waterPeakCheckRegion'][0]), max(nmrData.Attributes['waterPeakCheckRegion'][1]))

	localPPM, ppmMask, meanSpectrum, lowerPercentile, upperPercentile = nmrRangeHelper(nmrData, bounds, percentiles=(5, 95))
	trace = plotlyRangeHelper(localPPM, meanSpectrum, lowerPercentile, upperPercentile)
	data = data + trace

	##
	# Add fails
	##
	for i in range(nmrData.noSamples):

		if nmrData.sampleMetadata.loc[i, 'WaterPeakFail']:

			trace = go.Scatter(
				x = nmrData.featureMetadata.loc[:, 'ppm'].values[ppmMask],
				y = nmrData.intensityData[i, ppmMask],
				line = dict(
					color = ('rgb(12, 12, 205)')
				),
				text = '%s' % (nmrData.sampleMetadata.loc[i, 'Sample File Name']),
				hoverinfo = 'text',
				showlegend = False
			)
			failed.append(trace)

	data = data + failed

	trace = go.Scatter(
		x = nmrData.featureMetadata.loc[:, 'ppm'].values[ppmMask],
		y = nmrData.intensityData[0, ppmMask],
		name ='Mean Spectrum and variance',
		line = dict(
			color = ('rgb(117,182,160)')
		),
		mode = 'lines',
		visible = 'legendonly'
		)
	data.append(trace)

	##
	# Add water region in layout
	##
	layout = go.Layout(
		title='Residual water resonance',
		legend=dict(
			orientation="h"),
		hovermode = "closest",
		xaxis=dict(
			range=(min(nmrData.Attributes['waterPeakCheckRegion'][0]), max(nmrData.Attributes['waterPeakCheckRegion'][1]))
		),
		yaxis = dict(
			showticklabels=False
		),
		shapes= [
			{
				'type': 'rect',
				'yref': 'paper',
				'x0': max(nmrData.Attributes['waterPeakCheckRegion'][0]),
				'y0': 0,
				'x1': min(nmrData.Attributes['waterPeakCheckRegion'][1]),
				'y1': 1,
				'line': {
					'color': 'rgb(0, 0, 0, 0)',
					'width': 0,
					},
				'fillcolor': 'rgba(128, 128, 128, 0.5)',
				},
			]
		)

	figure = go.Figure(data=data, layout=layout)

	return figure
