# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# This file provides a static (non-interactive) matplotlib plotting backend
# for zeppelin notebooks for use with the python/pyspark interpreters

from __future__ import print_function

import sys
import uuid
import warnings
import base64
from io import BytesIO
try:
    from StringIO import StringIO
except ImportError:
    from io import StringIO

import mpl_config
import matplotlib
from matplotlib._pylab_helpers import Gcf
from matplotlib.backends.backend_agg import new_figure_manager, FigureCanvasAgg
from matplotlib.backend_bases import ShowBase, FigureManagerBase
from matplotlib.figure import Figure

########################################################################
#
# The following functions and classes are for pylab and implement
# window/figure managers, etc...
#
########################################################################

class Show(ShowBase):
    """
    A callable object that displays the figures to the screen. Valid kwargs
    include figure width and height (in units supported by the div tag), block
    (allows users to override blocking behavior regardless of whether or not
    interactive mode is enabled, currently unused) and close (Implicitly call
    matplotlib.pyplot.close('all') with each call to show()).
    """
    def __call__(self, close=None, block=None, **kwargs):
        if close is None:
            close = mpl_config.get('close')
        try:
            managers = Gcf.get_all_fig_managers()
            if not managers:
                return

            # Tell zeppelin that the output will be html using the %html magic
            # We want to do this only once to avoid seeing "%html" printed
            # directly to the outout when multiple figures are displayed from
            # one paragraph.
            if mpl_config.get('angular'):
                print('%angular')
            else:
                print('%html')

            # Show all open figures
            for manager in managers:
                manager.show(**kwargs)
        finally:
            # This closes all the figures if close is set to True.
            if close and Gcf.get_all_fig_managers():
                Gcf.destroy_all()


class FigureCanvasZInline(FigureCanvasAgg):
    """
    The canvas the figure renders into. Calls the draw and print fig
    methods, creates the renderers, etc...
    """
    def get_bytes(self, **kwargs):
        """
        Get the byte representation of the figure.
        Should only be used with jpg/png formats.
        """
        # Make sure format is correct
        fmt = kwargs.get('format', mpl_config.get('format'))
        if fmt == 'svg':
            raise ValueError("get_bytes() does not support svg, use png or jpg")
        
        # Express the image as bytes
        buf = BytesIO()
        self.print_figure(buf, **kwargs)
        fmt = fmt.encode()
        if sys.version_info >= (3, 4) and sys.version_info < (3, 5):
            byte_str = bytes("data:image/%s;base64," %fmt, "utf-8")
        else:
            byte_str = b"data:image/%s;base64," %fmt
        byte_str += base64.b64encode(buf.getvalue())
            
        # Python3 forces all strings to default to unicode, but for raster image
        # formats (eg png, jpg), we want to work with bytes. Thus this step is
        # needed to ensure compatability for all python versions.
        byte_str = byte_str.decode('ascii')
        buf.close()
        return byte_str

    def get_svg(self, **kwargs):
        """
        Get the svg representation of the figure.
        Should only be used with svg format.
        """
        # Make sure format is correct
        fmt = kwargs.get('format', mpl_config.get('format'))
        if fmt != 'svg':
            raise ValueError("get_svg() does not support png or jpg, use svg")
        
        # For SVG the data string has to be unicode, not bytes
        buf = StringIO()
        self.print_figure(buf, **kwargs)
        svg_str = buf.getvalue()
        buf.close()
        return svg_str
    
    def draw_idle(self, *args, **kwargs):
        """
        Called when the figure gets updated (eg through a plotting command).
        This is overriden to allow open figures to be reshown after they
        are updated when mpl_config.get('close') is False.
        """
        if not self._is_idle_drawing:
            with self._idle_draw_cntx():
                self.draw(*args, **kwargs)
                draw_if_interactive()
                

class FigureManagerZInline(FigureManagerBase):
    """
    Wrap everything up into a window for the pylab interface
    """
    def __init__(self, canvas, num):
        FigureManagerBase.__init__(self, canvas, num)
        self.fig_id = "figure_{0}".format(uuid.uuid4().hex)
        self._shown = False

    def angular_bind(self, **kwargs):
        """
        Bind figure data to Zeppelin's Angular Object Registry.
        If mpl_config("angular") is True and PY4J is supported, this allows
        for the possibility to interactively update a figure from a separate
        paragraph without having to display it multiple times.
        """
        # This doesn't work for SVG so make sure it's not our format
        fmt = kwargs.get('format', mpl_config.get('format'))
        if fmt == 'svg':
            return
        
        # Get the figure data as a byte array
        src = self.canvas.get_bytes(**kwargs)
        
        # Flag to determine whether or not to use
        # zeppelin's angular display system
        angular = mpl_config.get('angular')
        
        # ZeppelinContext instance (requires PY4J)
        context = mpl_config.get('context')
        
        # Finally we must ensure that automatic closing is set to False,
        # as otherwise using the angular display system is pointless
        close = mpl_config.get('close')
        
        # If above conditions are met, bind the figure data to
        # the Angular Object Registry.
        if not close and angular:
            if hasattr(context, 'angularBind'):
                # Binding is performed through figure ID to ensure this works
                # if multiple figures are open
                context.angularBind(self.fig_id, src)
                
                # Zeppelin will automatically replace this value even if it
                # is updated from another pargraph thanks to the {{}} notation
                src = "{{%s}}" %self.fig_id
            else:
                warnings.warn("Cannot bind figure to Angular Object Registry. "
                              "Check if PY4J is installed.")
        return src
    
    def angular_unbind(self):
        """
        Unbind figure from angular display system.
        """
        context = mpl_config.get('context')
        if hasattr(context, 'angularUnbind'):
            context.angularUnbind(self.fig_id)
                
    def destroy(self):
        """
        Called when close=True or implicitly by pyplot.close().
        Overriden to automatically clean up the angular object registry.
        """
        self.angular_unbind()

    def show(self, **kwargs):
        if not self._shown:
            zdisplay(self.canvas.figure, **kwargs)
        else:
            self.canvas.draw_idle()
            self.angular_bind(**kwargs)
            
        self._shown = True


def draw_if_interactive():
    """
    If interactive mode is on, this allows for updating properties of
    the figure when each new plotting command is called.
    """
    manager = Gcf.get_active()
    interactive = matplotlib.is_interactive()
    angular = mpl_config.get('angular')
    
    # Don't bother continuing if we aren't in interactive mode
    # or if there are no active figures. Also pointless to continue
    # in angular mode as we don't want to reshow the figure.
    if not interactive or angular or manager is None:
        return
        
    # Allow for figure to be reshown if close is false since
    # this function call implies that it has been updated
    if not mpl_config.get('close'):
        manager._shown = False
        

def new_figure_manager(num, *args, **kwargs):
    """
    Create a new figure manager instance
    """
    # if a main-level app must be created, this (and
    # new_figure_manager_given_figure) is the usual place to
    # do it -- see backend_wx, backend_wxagg and backend_tkagg for
    # examples.  Not all GUIs require explicit instantiation of a
    # main-level app (egg backend_gtk, backend_gtkagg) for pylab
    FigureClass = kwargs.pop('FigureClass', Figure)
    thisFig = FigureClass(*args, **kwargs)
    return new_figure_manager_given_figure(num, thisFig)


def new_figure_manager_given_figure(num, figure):
    """
    Create a new figure manager instance for the given figure.
    """
    canvas = FigureCanvasZInline(figure)
    manager = FigureManagerZInline(canvas, num)
    return manager


########################################################################
#
# Backend specific functions
#
########################################################################
            
def zdisplay(fig, **kwargs):
    """
    Publishes a matplotlib figure to the notebook paragraph output.
    """
    # kwargs can be width or height (in units supported by div tag)
    width = kwargs.pop('width', 'auto')
    height = kwargs.pop('height', 'auto')
    fmt = kwargs.get('format', mpl_config.get('format'))

    # Check if format is supported
    supported_formats = mpl_config.get('supported_formats')
    if fmt not in supported_formats:
        raise ValueError("Unsupported format %s" %fmt)
    
    # For SVG the data string has to be unicode, not bytes
    if fmt == 'svg':
        img = fig.canvas.get_svg(**kwargs)
        
        # This is needed to ensure the SVG image is the correct size.
        # We should find a better way to do this...
        width = '{}px'.format(mpl_config.get('width'))
        height = '{}px'.format(mpl_config.get('height'))
    else:
        # Express the image as bytes
        src = fig.canvas.manager.angular_bind(**kwargs)
        img = "<img src={src} style='width={width};height:{height}'>"
        img = img.format(src=src, width=width, height=height)
    
    # Print the image to the notebook paragraph via the %html magic
    html = "<div style='width:{width};height:{height}'>{img}<div>"
    print(html.format(width=width, height=height, img=img))

def displayhook():
    """
    Called post paragraph execution if interactive mode is on
    """
    if matplotlib.is_interactive():
        show()

########################################################################
#
# Now just provide the standard names that backend.__init__ is expecting
#
########################################################################

# Create a reference to the show function we are using. This is what actually
# gets called by matplotlib.pyplot.show().
show = Show()

# Default FigureCanvas and FigureManager classes to use from the backend
FigureCanvas = FigureCanvasZInline
FigureManager = FigureManagerZInline
