import matplotlib.pyplot as plt
import numpy
from matplotlib.ticker import FixedLocator
from matplotlib.colors import BoundaryNorm


def _produce_axis(spectra, dimension):
    """ This method produces an array that represents the axis.

    The array is formed of the value at the bin-centre for each bin
    along the specified dimension.

    Args:
      spectra (:class:`echidna.core.spectra.Spectra`): The spectra you
        wish to produce the axis from.
      dimension (string): The dimension you wish to produce the axis for.

    Returns:
      :class:`numpy.array`: The values for the axis.
    """
    par = spectra.get_config().get_par(dimension)
    width = par.get_width()
    return numpy.arange(par._low, par._high, width) + 0.5*width


def _produce_bins(spectra, dimension):
    """ This method produces an array that represents the bin boundaries.

    The array is formed of the value at each bin boundary from par._low
    to par._high along the specified dimension. The length of the array
    of bin boundaries is one greater than the length of the axis array.

    Args:
      spectra (:class:`echidna.core.spectra.Spectra`): The spectra you
        wish to produce the bin boundaries from.
      dimension (string): The dimension you wish to produce the bin
        boundaries for.

    Returns:
      :class:`numpy.array`: The values for the axis.
    """
    par = spectra.get_config().get_par(dimension)
    return numpy.linspace(par._low, par._high, par._bins+1)


def plot_projection(spectra, dimension, fig_num=1, show_plot=True):
    """ Plot the spectra as projected onto the dimension.

    For example dimension == 0 will plot the spectra as projected onto the
    energy dimension.

    Args:
      spectra (:class:`echidna.core.spectra`): The spectra to plot.
      dimension (string): The dimension to project the spectra onto.
      fig_num (int, optional): The number of the figure. If you are
        producing multiple spectral plots automatically, this can be
        useful to ensure pyplot treats each plot as a separate figure.
        Default is 1.
      show_plot (bool, optional): Displays the plot if true. Default is True.

    Returns:
      matplotlib.pyplot.figure: Plot of the projection.
    """
    fig = plt.figure(fig_num)
    axis = fig.add_subplot(1, 1, 1)

    par = spectra.get_config().get_par(dimension)