# Path: indiff/utils.py
# def wraparound(arr, dim, left_to_right=0, right_to_left=0,
#                circumf=360., spacing=1):
#     """Append wrap-around point(s) to the DataArray or Dataset coord."""
#     # TODO: Bugfix: if points on both sides are added, as written this
#     # causes the points first added to the right to then be added to the left,
#     # rather than the original points on the right.
#     new = add_cyclic_to_right(arr, dim, left_to_right, circumf)
#     return add_cyclic_to_left(new, dim, right_to_left, circumf)
# 
# Path: indiff/diff/finite.py
# class FiniteDiff(object):
#     """Base class for finite differencing of xarray objects."""
#     def __init__(self, arr, dim, spacing=1, wrap=False):
#         """
#         Create a `FiniteDiff` object.
# 
#         :param arr: Data to be center-differenced.
#         :type arr: `xarray.DataArray` or `xarray.Dataset`
#         :param str dim: Dimension over which to perform the differencing.
#         :param int spacing: How many gridpoints over to use.  Size of resulting
#             array depends on this value.
#         """
#         self.arr = arr
#         self.dim = dim
#         self.spacing = spacing
#         self.wrap = wrap
# 
#     def _slice_arr_dim(self, slice_, arr):
#         """Get a slice of a DataArray along a particular dim."""
#         return arr[{self.dim: slice_}]
# 
#     def _reverse_dim(self, arr):
#         """Reverse the DataArray along the given dimension."""
#         return self._slice_arr_dim(slice(-1, None, -1), arr)
# 
#     def _wrap(self):
#         raise NotImplementedError
# 
#     def diff(self):
#         raise NotImplementedError


import xarray as xr
from ..utils import wraparound
from . import FiniteDiff
    def __init__(self, arr, dim, spacing=1, wrap=False):
        super(OneSidedDiff, self).__init__(arr, dim, spacing=spacing)

    def _wrap(self):
        raise NotImplementedError

    def diff(self):
        """One-sided differencing."""
        left = self._slice_arr_dim(slice(0, -self.spacing), self.arr)
        right = self._slice_arr_dim(slice(self.spacing, None), self.arr)
        return xr.DataArray(right.values, dims=left.dims,
                            coords=left.coords) - left


class FwdDiff(OneSidedDiff):
    """Forward finite differencing."""
    def __init__(self, arr, dim, spacing=1, wrap=False):
        super(FwdDiff, self).__init__(arr, dim, spacing=spacing)

    def _wrap(self):
        return wraparound(self.arr, self.dim, left_to_right=self.spacing,
                          right_to_left=0, circumf=0, spacing=1)


class BwdDiff(OneSidedDiff):
    """Backward finite differencing."""
    def __init__(self, arr, dim, spacing=1, wrap=False):
        super(BwdDiff, self).__init__(arr, dim, spacing=spacing)

    def _wrap(self):

# Path: indiff/utils.py
# def wraparound(arr, dim, left_to_right=0, right_to_left=0,
#                circumf=360., spacing=1):
#     """Append wrap-around point(s) to the DataArray or Dataset coord."""
#     # TODO: Bugfix: if points on both sides are added, as written this
#     # causes the points first added to the right to then be added to the left,
#     # rather than the original points on the right.
#     new = add_cyclic_to_right(arr, dim, left_to_right, circumf)
#     return add_cyclic_to_left(new, dim, right_to_left, circumf)
# 
# Path: indiff/diff/finite.py
# class FiniteDiff(object):
#     """Base class for finite differencing of xarray objects."""
#     def __init__(self, arr, dim, spacing=1, wrap=False):
#         """
#         Create a `FiniteDiff` object.
# 
#         :param arr: Data to be center-differenced.
#         :type arr: `xarray.DataArray` or `xarray.Dataset`
#         :param str dim: Dimension over which to perform the differencing.
#         :param int spacing: How many gridpoints over to use.  Size of resulting
#             array depends on this value.
#         """
#         self.arr = arr
#         self.dim = dim
#         self.spacing = spacing
#         self.wrap = wrap
# 
#     def _slice_arr_dim(self, slice_, arr):
#         """Get a slice of a DataArray along a particular dim."""
#         return arr[{self.dim: slice_}]
# 
#     def _reverse_dim(self, arr):
#         """Reverse the DataArray along the given dimension."""
#         return self._slice_arr_dim(slice(-1, None, -1), arr)
# 
#     def _wrap(self):
#         raise NotImplementedError
# 
#     def diff(self):
#         raise NotImplementedError


# Path: indiff/diff/one_sided.py
import xarray as xr
from ..utils import wraparound
from . import FiniteDiff

    def __init__(self, arr, dim, spacing=1, wrap=False):
        super(OneSidedDiff, self).__init__(arr, dim, spacing=spacing)

    def _wrap(self):
        raise NotImplementedError

    def diff(self):
        """One-sided differencing."""
        left = self._slice_arr_dim(slice(0, -self.spacing), self.arr)
        right = self._slice_arr_dim(slice(self.spacing, None), self.arr)
        return xr.DataArray(right.values, dims=left.dims,
                            coords=left.coords) - left


class FwdDiff(OneSidedDiff):
    """Forward finite differencing."""
    def __init__(self, arr, dim, spacing=1, wrap=False):
        super(FwdDiff, self).__init__(arr, dim, spacing=spacing)

    def _wrap(self):
        return wraparound(self.arr, self.dim, left_to_right=self.spacing,
                          right_to_left=0, circumf=0, spacing=1)


class BwdDiff(OneSidedDiff):
    """Backward finite differencing."""
    def __init__(self, arr, dim, spacing=1, wrap=False):
        super(BwdDiff, self).__init__(arr, dim, spacing=spacing)

    def _wrap(self):

        return wraparound(self.arr, self.dim, left_to_right=0,