"""Functions that could be used to visualize Tensors.

This is adapted from the old-time iceberk package that Yangqing wrote... Oh gold
memories. Before decaf and caffe. Why iceberk? Because I was at Berkeley,
bears are vegetarian, and iceberg lettuce has layers of leaves.

(This joke is so lame.)
"""

import numpy as np
from matplotlib import cm, pyplot


def ChannelFirst(arr):
    """Convert a HWC array to CHW."""
    ndim = arr.ndim
    return arr.swapaxes(ndim - 1, ndim - 2).swapaxes(ndim - 2, ndim - 3)


def ChannelLast(arr):
    """Convert a CHW array to HWC."""
    ndim = arr.ndim
    return arr.swapaxes(ndim - 3, ndim - 2).swapaxes(ndim - 2, ndim - 1)


class PatchVisualizer(object):
    """PatchVisualizer visualizes patches.
  """

    def __init__(self, gap=1):
        self.gap = gap

    def ShowSingle(self, patch, cmap=None):
        """Visualizes one single patch.

    The input patch could be a vector (in which case we try to infer the shape
    of the patch), a 2-D matrix, or a 3-D matrix whose 3rd dimension has 3
    channels.
    """
        if len(patch.shape) == 1:
            patch = patch.reshape(self.get_patch_shape(patch))
        elif len(patch.shape) > 2 and patch.shape[2] != 3:
            raise ValueError("The input patch shape isn't correct.")
        # determine color
        if len(patch.shape) == 2 and cmap is None:
            cmap = cm.gray
        pyplot.imshow(patch, cmap=cmap)
        return patch

    def ShowMultiple(self, patches, ncols=None, cmap=None, bg_func=np.mean):
        """Visualize multiple patches.

    In the passed in patches matrix, each row is a patch, in the shape of either
    n*n, n*n*1 or n*n*3, either in a flattened format (so patches would be a
    2-D array), or a multi-dimensional tensor. We will try our best to figure
    out automatically the patch size.
    """
        num_patches = patches.shape[0]
        if ncols is None:
            ncols = int(np.ceil(np.sqrt(num_patches)))
        nrows = int(np.ceil(num_patches / float(ncols)))
        if len(patches.shape) == 2:
            patches = patches.reshape(
                (patches.shape[0], ) + self.get_patch_shape(patches[0])
            )
        patch_size_expand = np.array(patches.shape[1:3]) + self.gap
        image_size = patch_size_expand * np.array([nrows, ncols]) - self.gap
        if len(patches.shape) == 4:
            if patches.shape[3] == 1:
                # gray patches
                patches = patches.reshape(patches.shape[:-1])
                image_shape = tuple(image_size)
                if cmap is None:
                    cmap = cm.gray
            elif patches.shape[3] == 3:
                # color patches
                image_shape = tuple(image_size) + (3, )
            else:
                raise ValueError("The input patch shape isn't expected.")
        else:
            image_shape = tuple(image_size)
            if cmap is None:
                cmap = cm.gray
        image = np.ones(image_shape) * bg_func(patches)
        for pid in range(num_patches):
            row = pid / ncols * patch_size_expand[0]
            col = pid % ncols * patch_size_expand[1]
            image[row:row+patches.shape[1], col:col+patches.shape[2]] = \
                patches[pid]
        pyplot.imshow(image, cmap=cmap, interpolation='nearest')
        pyplot.axis('off')
        return image

    def ShowImages(self, patches, *args, **kwargs):
        """Similar to ShowMultiple, but always normalize the values between 0 and 1
    for better visualization of image-type data.
    """
        patches = patches - np.min(patches)
        patches /= np.max(patches) + np.finfo(np.float64).eps
        return self.ShowMultiple(patches, *args, **kwargs)

    def ShowChannels(self, patch, cmap=None, bg_func=np.mean):
        """ This function shows the channels of a patch.

    The incoming patch should have shape [w, h, num_channels], and each channel
    will be visualized as a separate gray patch.
    """
        if len(patch.shape) != 3:
            raise ValueError("The input patch shape isn't correct.")
        patch_reordered = np.swapaxes(patch.T, 1, 2)
        return self.ShowMultiple(patch_reordered, cmap=cmap, bg_func=bg_func)

    def get_patch_shape(self, patch):
        """Gets the shape of a single patch.

    Basically it tries to interprete the patch as a square, and also check if it
    is in color (3 channels)
    """
        edgeLen = np.sqrt(patch.size)
        if edgeLen != np.floor(edgeLen):
            # we are given color patches
            edgeLen = np.sqrt(patch.size / 3.)
            if edgeLen != np.floor(edgeLen):
                raise ValueError("I can't figure out the patch shape.")
            return (edgeLen, edgeLen, 3)
        else:
            edgeLen = int(edgeLen)
            return (edgeLen, edgeLen)


_default_visualizer = PatchVisualizer()
"""Utility functions that directly point to functions in the default visualizer.

These functions don't return anything, so you won't see annoying printouts of
the visualized images. If you want to save the images for example, you should
explicitly instantiate a patch visualizer, and call those functions.
"""


class NHWC(object):
    @staticmethod
    def ShowSingle(*args, **kwargs):
        _default_visualizer.ShowSingle(*args, **kwargs)

    @staticmethod
    def ShowMultiple(*args, **kwargs):
        _default_visualizer.ShowMultiple(*args, **kwargs)

    @staticmethod
    def ShowImages(*args, **kwargs):
        _default_visualizer.ShowImages(*args, **kwargs)

    @staticmethod
    def ShowChannels(*args, **kwargs):
        _default_visualizer.ShowChannels(*args, **kwargs)


class NCHW(object):
    @staticmethod
    def ShowSingle(patch, *args, **kwargs):
        _default_visualizer.ShowSingle(ChannelLast(patch), *args, **kwargs)

    @staticmethod
    def ShowMultiple(patch, *args, **kwargs):
        _default_visualizer.ShowMultiple(ChannelLast(patch), *args, **kwargs)

    @staticmethod
    def ShowImages(patch, *args, **kwargs):
        _default_visualizer.ShowImages(ChannelLast(patch), *args, **kwargs)

    @staticmethod
    def ShowChannels(patch, *args, **kwargs):
        _default_visualizer.ShowChannels(ChannelLast(patch), *args, **kwargs)
