# -*- coding: utf-8 -*-
# Copyright 2021 IRT Saint Exupéry, https://www.irt-saintexupery.com
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

# Contributors:
#    INITIAL AUTHORS - API and implementation and/or documentation
#        :author: Francois Gallard
#        :author: Damien Guenot
#    OTHER AUTHORS   - MACROSCOPIC CHANGES
"""
Plot the derivatives of the functions
*************************************
"""
from __future__ import absolute_import, division, unicode_literals

from future import standard_library
from matplotlib import pyplot
from numpy import arange, atleast_2d

from gemseo.post.opt_post_processor import OptPostProcessor

standard_library.install_aliases()

from gemseo import LOGGER

"""
builds histograms of derivatives of objective and constraints

The plot method considers the derivatives at the last iteration.
The iteration can be changed in option. The x- and y- figure sizes
can also be modified in option.
It is possible either to save the plot, to show the plot or both.
"""

def _plot(
self,
iteration=-1,
figsize_x=10,
figsize_y=10,
save=False,
show=False,
extension="pdf",
):
"""

:param iteration:  the iteration to plot sensitivities, if negative,
use optimum
:type iteration: int
:param figsize_x: size of figure in horizontal direction (inches)
:type figsize_x: int
:param figsize_y: size of figure in vertical direction (inches)
:type figsize_y: int
:param show: if True, displays the plot windows
:type show: bool
:param save: if True, exports plot to pdf
:type save: bool
:param file_path: the base paths of the files to export
:type file_path: str
:param extension: file extension
:type extension: str
"""
all_funcs = self.opt_problem.get_all_functions_names()

if iteration == -1:
x_ref = self.opt_problem.solution.x_opt
else:
x_ref = self.opt_problem.database.get_x_by_iter(iteration)
for func in all_funcs:
grad = self.database.get_f_of_x("@" + func, x_ref)
else:
for i in range(n_f):

fig = self.__generate_subplots(x_ref, grad_dict, figsize_x, figsize_y)
self._save_and_show(
fig, save=save, show=show, file_path=file_path, extension=extension
)

@staticmethod
"""
Generates the gradient sub plots from the data

:param x_ref: reference value for x
:param figsize_x : size of figure in horizontal direction (inches)
:param figsize_y : size of figure in vertical direction (inches)
"""
if n_funcs == 0:
raise ValueError("No gradients to plot at current iteration !")
nrows = n_funcs // 2
if 2 * nrows < n_funcs:
nrows += 1
ncols = 2
fig, axes = pyplot.subplots(
nrows=nrows,
ncols=2,
sharex=True,
sharey=False,
figsize=(figsize_x, figsize_y),
)
i = 0
j = -1

axes = atleast_2d(axes)
n_subplots = len(axes) * len(axes[0])
abscissa = arange(len(x_ref))
x_labels = [r"$x_{" + str(x_id) + "}$" for x_id in abscissa]
j += 1
if j == ncols:
j = 0
i += 1
axe = axes[i][j]
axe.set_title(func)
axe.set_xticklabels(x_labels, fontsize=14)
axe.set_xticks(abscissa)
# Update y labels spacing
vis_labels = [
label for label in axe.get_yticklabels() if label.get_visible() is True
]
pyplot.setp(vis_labels[::2], visible=False)

# xlabel must be written with the same fontsize on the 2 columns
j += 1
#             if j == ncols: Seems impossible to reach
#                 j = 0
#                 i += 1
axe = axes[i][j]
axe.set_xticklabels(x_labels, fontsize=14)
axe.set_xticks(abscissa)

fig.suptitle(
"Derivatives of objective and constraints"
+ " with respect to design variables",
fontsize=14,
)
return fig