# This file was automatically generated by SWIG (http://www.swig.org).
# Version 4.0.2
#
# Do not make changes to this file unless you know what you are doing--modify
# the SWIG interface file instead.

from sys import version_info as _swig_python_version_info
if _swig_python_version_info < (2, 7, 0):
    raise RuntimeError("Python 2.7 or later required")

# Import the low-level C/C++ module
if __package__ or "." in __name__:
    from . import _pyBiDirectionalCpp
else:
    import _pyBiDirectionalCpp

try:
    import builtins as __builtin__
except ImportError:
    import __builtin__

def _swig_repr(self):
    try:
        strthis = "proxy of " + self.this.__repr__()
    except __builtin__.Exception:
        strthis = ""
    return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)


def _swig_setattr_nondynamic_instance_variable(set):
    def set_instance_attr(self, name, value):
        if name == "thisown":
            self.this.own(value)
        elif name == "this":
            set(self, name, value)
        elif hasattr(self, name) and isinstance(getattr(type(self), name), property):
            set(self, name, value)
        else:
            raise AttributeError("You cannot add instance attributes to %s" % self)
    return set_instance_attr


def _swig_setattr_nondynamic_class_variable(set):
    def set_class_attr(cls, name, value):
        if hasattr(cls, name) and not isinstance(getattr(cls, name), property):
            set(cls, name, value)
        else:
            raise AttributeError("You cannot add class attributes to %s" % cls)
    return set_class_attr


def _swig_add_metaclass(metaclass):
    """Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass"""
    def wrapper(cls):
        return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy())
    return wrapper


class _SwigNonDynamicMeta(type):
    """Meta class to enforce nondynamic attributes (no new attributes) for a class"""
    __setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__)


import weakref

class SwigPyIterator(object):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def __init__(self, *args, **kwargs):
        raise AttributeError("No constructor defined - class is abstract")
    __repr__ = _swig_repr
    __swig_destroy__ = _pyBiDirectionalCpp.delete_SwigPyIterator

    def value(self) -> "PyObject *":
        return _pyBiDirectionalCpp.SwigPyIterator_value(self)

    def incr(self, n: "size_t"=1) -> "swig::SwigPyIterator *":
        return _pyBiDirectionalCpp.SwigPyIterator_incr(self, n)

    def decr(self, n: "size_t"=1) -> "swig::SwigPyIterator *":
        return _pyBiDirectionalCpp.SwigPyIterator_decr(self, n)

    def distance(self, x: "SwigPyIterator") -> "ptrdiff_t":
        return _pyBiDirectionalCpp.SwigPyIterator_distance(self, x)

    def equal(self, x: "SwigPyIterator") -> "bool":
        return _pyBiDirectionalCpp.SwigPyIterator_equal(self, x)

    def copy(self) -> "swig::SwigPyIterator *":
        return _pyBiDirectionalCpp.SwigPyIterator_copy(self)

    def next(self) -> "PyObject *":
        return _pyBiDirectionalCpp.SwigPyIterator_next(self)

    def __next__(self) -> "PyObject *":
        return _pyBiDirectionalCpp.SwigPyIterator___next__(self)

    def previous(self) -> "PyObject *":
        return _pyBiDirectionalCpp.SwigPyIterator_previous(self)

    def advance(self, n: "ptrdiff_t") -> "swig::SwigPyIterator *":
        return _pyBiDirectionalCpp.SwigPyIterator_advance(self, n)

    def __eq__(self, x: "SwigPyIterator") -> "bool":
        return _pyBiDirectionalCpp.SwigPyIterator___eq__(self, x)

    def __ne__(self, x: "SwigPyIterator") -> "bool":
        return _pyBiDirectionalCpp.SwigPyIterator___ne__(self, x)

    def __iadd__(self, n: "ptrdiff_t") -> "swig::SwigPyIterator &":
        return _pyBiDirectionalCpp.SwigPyIterator___iadd__(self, n)

    def __isub__(self, n: "ptrdiff_t") -> "swig::SwigPyIterator &":
        return _pyBiDirectionalCpp.SwigPyIterator___isub__(self, n)

    def __add__(self, n: "ptrdiff_t") -> "swig::SwigPyIterator *":
        return _pyBiDirectionalCpp.SwigPyIterator___add__(self, n)

    def __sub__(self, *args) -> "ptrdiff_t":
        return _pyBiDirectionalCpp.SwigPyIterator___sub__(self, *args)
    def __iter__(self):
        return self

# Register SwigPyIterator in _pyBiDirectionalCpp:
_pyBiDirectionalCpp.SwigPyIterator_swigregister(SwigPyIterator)

class DoubleVector(object):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def iterator(self) -> "swig::SwigPyIterator *":
        return _pyBiDirectionalCpp.DoubleVector_iterator(self)
    def __iter__(self):
        return self.iterator()

    def __nonzero__(self) -> "bool":
        return _pyBiDirectionalCpp.DoubleVector___nonzero__(self)

    def __bool__(self) -> "bool":
        return _pyBiDirectionalCpp.DoubleVector___bool__(self)

    def __len__(self) -> "std::vector< double >::size_type":
        return _pyBiDirectionalCpp.DoubleVector___len__(self)

    def __getslice__(self, i: "std::vector< double >::difference_type", j: "std::vector< double >::difference_type") -> "std::vector< double,std::allocator< double > > *":
        return _pyBiDirectionalCpp.DoubleVector___getslice__(self, i, j)

    def __setslice__(self, *args) -> "void":
        return _pyBiDirectionalCpp.DoubleVector___setslice__(self, *args)

    def __delslice__(self, i: "std::vector< double >::difference_type", j: "std::vector< double >::difference_type") -> "void":
        return _pyBiDirectionalCpp.DoubleVector___delslice__(self, i, j)

    def __delitem__(self, *args) -> "void":
        return _pyBiDirectionalCpp.DoubleVector___delitem__(self, *args)

    def __getitem__(self, *args) -> "std::vector< double >::value_type const &":
        return _pyBiDirectionalCpp.DoubleVector___getitem__(self, *args)

    def __setitem__(self, *args) -> "void":
        return _pyBiDirectionalCpp.DoubleVector___setitem__(self, *args)

    def pop(self) -> "std::vector< double >::value_type":
        return _pyBiDirectionalCpp.DoubleVector_pop(self)

    def append(self, x: "std::vector< double >::value_type const &") -> "void":
        return _pyBiDirectionalCpp.DoubleVector_append(self, x)

    def empty(self) -> "bool":
        return _pyBiDirectionalCpp.DoubleVector_empty(self)

    def size(self) -> "std::vector< double >::size_type":
        return _pyBiDirectionalCpp.DoubleVector_size(self)

    def swap(self, v: "DoubleVector") -> "void":
        return _pyBiDirectionalCpp.DoubleVector_swap(self, v)

    def begin(self) -> "std::vector< double >::iterator":
        return _pyBiDirectionalCpp.DoubleVector_begin(self)

    def end(self) -> "std::vector< double >::iterator":
        return _pyBiDirectionalCpp.DoubleVector_end(self)

    def rbegin(self) -> "std::vector< double >::reverse_iterator":
        return _pyBiDirectionalCpp.DoubleVector_rbegin(self)

    def rend(self) -> "std::vector< double >::reverse_iterator":
        return _pyBiDirectionalCpp.DoubleVector_rend(self)

    def clear(self) -> "void":
        return _pyBiDirectionalCpp.DoubleVector_clear(self)

    def get_allocator(self) -> "std::vector< double >::allocator_type":
        return _pyBiDirectionalCpp.DoubleVector_get_allocator(self)

    def pop_back(self) -> "void":
        return _pyBiDirectionalCpp.DoubleVector_pop_back(self)

    def erase(self, *args) -> "std::vector< double >::iterator":
        return _pyBiDirectionalCpp.DoubleVector_erase(self, *args)

    def __init__(self, *args):
        _pyBiDirectionalCpp.DoubleVector_swiginit(self, _pyBiDirectionalCpp.new_DoubleVector(*args))

    def push_back(self, x: "std::vector< double >::value_type const &") -> "void":
        return _pyBiDirectionalCpp.DoubleVector_push_back(self, x)

    def front(self) -> "std::vector< double >::value_type const &":
        return _pyBiDirectionalCpp.DoubleVector_front(self)

    def back(self) -> "std::vector< double >::value_type const &":
        return _pyBiDirectionalCpp.DoubleVector_back(self)

    def assign(self, n: "std::vector< double >::size_type", x: "std::vector< double >::value_type const &") -> "void":
        return _pyBiDirectionalCpp.DoubleVector_assign(self, n, x)

    def resize(self, *args) -> "void":
        return _pyBiDirectionalCpp.DoubleVector_resize(self, *args)

    def insert(self, *args) -> "void":
        return _pyBiDirectionalCpp.DoubleVector_insert(self, *args)

    def reserve(self, n: "std::vector< double >::size_type") -> "void":
        return _pyBiDirectionalCpp.DoubleVector_reserve(self, n)

    def capacity(self) -> "std::vector< double >::size_type":
        return _pyBiDirectionalCpp.DoubleVector_capacity(self)
    __swig_destroy__ = _pyBiDirectionalCpp.delete_DoubleVector

# Register DoubleVector in _pyBiDirectionalCpp:
_pyBiDirectionalCpp.DoubleVector_swigregister(DoubleVector)

class StringVector(object):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def iterator(self) -> "swig::SwigPyIterator *":
        return _pyBiDirectionalCpp.StringVector_iterator(self)
    def __iter__(self):
        return self.iterator()

    def __nonzero__(self) -> "bool":
        return _pyBiDirectionalCpp.StringVector___nonzero__(self)

    def __bool__(self) -> "bool":
        return _pyBiDirectionalCpp.StringVector___bool__(self)

    def __len__(self) -> "std::vector< std::string >::size_type":
        return _pyBiDirectionalCpp.StringVector___len__(self)

    def __getslice__(self, i: "std::vector< std::string >::difference_type", j: "std::vector< std::string >::difference_type") -> "std::vector< std::string,std::allocator< std::string > > *":
        return _pyBiDirectionalCpp.StringVector___getslice__(self, i, j)

    def __setslice__(self, *args) -> "void":
        return _pyBiDirectionalCpp.StringVector___setslice__(self, *args)

    def __delslice__(self, i: "std::vector< std::string >::difference_type", j: "std::vector< std::string >::difference_type") -> "void":
        return _pyBiDirectionalCpp.StringVector___delslice__(self, i, j)

    def __delitem__(self, *args) -> "void":
        return _pyBiDirectionalCpp.StringVector___delitem__(self, *args)

    def __getitem__(self, *args) -> "std::vector< std::string >::value_type const &":
        return _pyBiDirectionalCpp.StringVector___getitem__(self, *args)

    def __setitem__(self, *args) -> "void":
        return _pyBiDirectionalCpp.StringVector___setitem__(self, *args)

    def pop(self) -> "std::vector< std::string >::value_type":
        return _pyBiDirectionalCpp.StringVector_pop(self)

    def append(self, x: "std::vector< std::string >::value_type const &") -> "void":
        return _pyBiDirectionalCpp.StringVector_append(self, x)

    def empty(self) -> "bool":
        return _pyBiDirectionalCpp.StringVector_empty(self)

    def size(self) -> "std::vector< std::string >::size_type":
        return _pyBiDirectionalCpp.StringVector_size(self)

    def swap(self, v: "StringVector") -> "void":
        return _pyBiDirectionalCpp.StringVector_swap(self, v)

    def begin(self) -> "std::vector< std::string >::iterator":
        return _pyBiDirectionalCpp.StringVector_begin(self)

    def end(self) -> "std::vector< std::string >::iterator":
        return _pyBiDirectionalCpp.StringVector_end(self)

    def rbegin(self) -> "std::vector< std::string >::reverse_iterator":
        return _pyBiDirectionalCpp.StringVector_rbegin(self)

    def rend(self) -> "std::vector< std::string >::reverse_iterator":
        return _pyBiDirectionalCpp.StringVector_rend(self)

    def clear(self) -> "void":
        return _pyBiDirectionalCpp.StringVector_clear(self)

    def get_allocator(self) -> "std::vector< std::string >::allocator_type":
        return _pyBiDirectionalCpp.StringVector_get_allocator(self)

    def pop_back(self) -> "void":
        return _pyBiDirectionalCpp.StringVector_pop_back(self)

    def erase(self, *args) -> "std::vector< std::string >::iterator":
        return _pyBiDirectionalCpp.StringVector_erase(self, *args)

    def __init__(self, *args):
        _pyBiDirectionalCpp.StringVector_swiginit(self, _pyBiDirectionalCpp.new_StringVector(*args))

    def push_back(self, x: "std::vector< std::string >::value_type const &") -> "void":
        return _pyBiDirectionalCpp.StringVector_push_back(self, x)

    def front(self) -> "std::vector< std::string >::value_type const &":
        return _pyBiDirectionalCpp.StringVector_front(self)

    def back(self) -> "std::vector< std::string >::value_type const &":
        return _pyBiDirectionalCpp.StringVector_back(self)

    def assign(self, n: "std::vector< std::string >::size_type", x: "std::vector< std::string >::value_type const &") -> "void":
        return _pyBiDirectionalCpp.StringVector_assign(self, n, x)

    def resize(self, *args) -> "void":
        return _pyBiDirectionalCpp.StringVector_resize(self, *args)

    def insert(self, *args) -> "void":
        return _pyBiDirectionalCpp.StringVector_insert(self, *args)

    def reserve(self, n: "std::vector< std::string >::size_type") -> "void":
        return _pyBiDirectionalCpp.StringVector_reserve(self, n)

    def capacity(self) -> "std::vector< std::string >::size_type":
        return _pyBiDirectionalCpp.StringVector_capacity(self)
    __swig_destroy__ = _pyBiDirectionalCpp.delete_StringVector

# Register StringVector in _pyBiDirectionalCpp:
_pyBiDirectionalCpp.StringVector_swigregister(StringVector)

class BiDirectionalCpp(object):
    r"""
    BiDirectional algorithm. see docs

    1. ctor (memory allocation for the graph)
    2. add edges to graph using `addEdge`.
    3. [optional] set solving parameters if desired (e.g. time_limit, ...)
    	3.1. [optional] set callback using `setREFCallback`
    	3.2. [optional] set seed using `setSeed`
    4. call `run`
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, number_vertices: "int const &", number_edges: "int const &", max_res: "DoubleVector", min_res: "DoubleVector"):
        r"""
        :type number_vertices: int, in
        :param number_vertices:, int number of vertices in the graph (to be
            added using addEdge)
        :type number_edges: int, in
        :param number_edges:, int number of edges in the graph
        :type max_res: std::vector< double,std::allocator< double > >, in
        :param max_res:, vector of double with upper bound for resource
            consumption
        :type min_res: std::vector< double,std::allocator< double > >, in
        :param min_res:, vector of double with lower bound for resource
            consumption
        """
        _pyBiDirectionalCpp.BiDirectionalCpp_swiginit(self, _pyBiDirectionalCpp.new_BiDirectionalCpp(number_vertices, number_edges, max_res, min_res))
    __swig_destroy__ = _pyBiDirectionalCpp.delete_BiDirectionalCpp
    max_res = property(_pyBiDirectionalCpp.BiDirectionalCpp_max_res_get, _pyBiDirectionalCpp.BiDirectionalCpp_max_res_set, doc=r""" vector with upper and lower bounds for resources""")
    min_res = property(_pyBiDirectionalCpp.BiDirectionalCpp_min_res_get, _pyBiDirectionalCpp.BiDirectionalCpp_min_res_set)
    direction = property(_pyBiDirectionalCpp.BiDirectionalCpp_direction_get, _pyBiDirectionalCpp.BiDirectionalCpp_direction_set, doc=r""" string with direction of search""")
    method = property(_pyBiDirectionalCpp.BiDirectionalCpp_method_get, _pyBiDirectionalCpp.BiDirectionalCpp_method_set, doc=r""" string with method to determine the next direction of search""")
    time_limit = property(_pyBiDirectionalCpp.BiDirectionalCpp_time_limit_get, _pyBiDirectionalCpp.BiDirectionalCpp_time_limit_set, doc=r""" double with time limit in seconds""")
    threshold = property(_pyBiDirectionalCpp.BiDirectionalCpp_threshold_get, _pyBiDirectionalCpp.BiDirectionalCpp_threshold_set, doc=r""" double with threshold to stop search with total cost <= threshold""")
    elementary = property(_pyBiDirectionalCpp.BiDirectionalCpp_elementary_get, _pyBiDirectionalCpp.BiDirectionalCpp_elementary_set, doc=r""" bool with whether output path is required to be elementary""")
    bounds_pruning = property(_pyBiDirectionalCpp.BiDirectionalCpp_bounds_pruning_get, _pyBiDirectionalCpp.BiDirectionalCpp_bounds_pruning_set, doc=r"""
    bool with whether lower bounds based on shortest paths are used to prune
    labels
    """)
    graph = property(_pyBiDirectionalCpp.BiDirectionalCpp_graph_get, _pyBiDirectionalCpp.BiDirectionalCpp_graph_set, doc=r""" DiGraph pointer (raw cause of SWIG!)""")

    def setSeed(self, seed: "int const &") -> "void":
        r""" set random using a given seed"""
        return _pyBiDirectionalCpp.BiDirectionalCpp_setSeed(self, seed)

    def setREFCallback(self, cb: "REFCallback") -> "void":
        r"""
        Pass python callback for label extensions.
        Note: swig needs namespace specifier
        """
        return _pyBiDirectionalCpp.BiDirectionalCpp_setREFCallback(self, cb)

    def addEdge(self, tail: "std::string const &", head: "std::string const &", weight: "double const &", resource_consumption: "DoubleVector") -> "void":
        r""" Add an edge to the graph"""
        return _pyBiDirectionalCpp.BiDirectionalCpp_addEdge(self, tail, head, weight, resource_consumption)

    def run(self) -> "void":
        r""" run the algorithm (assumes all the appropriate options are set)"""
        return _pyBiDirectionalCpp.BiDirectionalCpp_run(self)

    def getPath(self) -> "std::vector< std::string,std::allocator< std::string > >":
        r""" Return the final path"""
        return _pyBiDirectionalCpp.BiDirectionalCpp_getPath(self)

    def getConsumedResources(self) -> "std::vector< double,std::allocator< double > >":
        r""" Return the consumed resources"""
        return _pyBiDirectionalCpp.BiDirectionalCpp_getConsumedResources(self)

    def getTotalCost(self) -> "double":
        r""" Return the total cost"""
        return _pyBiDirectionalCpp.BiDirectionalCpp_getTotalCost(self)

# Register BiDirectionalCpp in _pyBiDirectionalCpp:
_pyBiDirectionalCpp.BiDirectionalCpp_swigregister(BiDirectionalCpp)

class REFCallback(object):
    r"""
    Generic callback for custom Resource Extensions.
    In the case the user has not defined all three, default additive REFs are
    used.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self):
        if self.__class__ == REFCallback:
            _self = None
        else:
            _self = self
        _pyBiDirectionalCpp.REFCallback_swiginit(self, _pyBiDirectionalCpp.new_REFCallback(_self, ))
    __swig_destroy__ = _pyBiDirectionalCpp.delete_REFCallback

    def REF_fwd(self, cumulative_resource: "DoubleVector", tail: "std::string const &", head: "std::string const &", edge_resource_consumption: "DoubleVector", partial_path: "StringVector", accummulated_cost: "double const &") -> "std::vector< double,std::allocator< double > >":
        r""" Default implementation of a forward REF"""
        return _pyBiDirectionalCpp.REFCallback_REF_fwd(self, cumulative_resource, tail, head, edge_resource_consumption, partial_path, accummulated_cost)

    def REF_bwd(self, cumulative_resource: "DoubleVector", tail: "std::string const &", head: "std::string const &", edge_resource_consumption: "DoubleVector", partial_path: "StringVector", accummulated_cost: "double const &") -> "std::vector< double,std::allocator< double > >":
        r""" Default implementation of a backward REF"""
        return _pyBiDirectionalCpp.REFCallback_REF_bwd(self, cumulative_resource, tail, head, edge_resource_consumption, partial_path, accummulated_cost)

    def REF_join(self, fwd_resource: "DoubleVector", bwd_resource: "DoubleVector", tail: "std::string const &", head: "std::string const &", edge_resource_consumption: "DoubleVector") -> "std::vector< double,std::allocator< double > >":
        r"""
        Default implementation of a joining REF (used to merge forward and
        backward paths)
        """
        return _pyBiDirectionalCpp.REFCallback_REF_join(self, fwd_resource, bwd_resource, tail, head, edge_resource_consumption)
    def __disown__(self):
        self.this.disown()
        _pyBiDirectionalCpp.disown_REFCallback(self)
        return weakref.proxy(self)

# Register REFCallback in _pyBiDirectionalCpp:
_pyBiDirectionalCpp.REFCallback_swigregister(REFCallback)


def additiveForwardREF(cumulative_resource: "DoubleVector", tail: "std::string const &", head: "std::string const &", edge_resource_consumption: "DoubleVector") -> "std::vector< double,std::allocator< double > >":
    r""" Default additive REF for forward labels"""
    return _pyBiDirectionalCpp.additiveForwardREF(cumulative_resource, tail, head, edge_resource_consumption)

def additiveBackwardREF(cumulative_resource: "DoubleVector", tail: "std::string const &", head: "std::string const &", edge_resource_consumption: "DoubleVector") -> "std::vector< double,std::allocator< double > >":
    r""" Default additive REF for backward labels"""
    return _pyBiDirectionalCpp.additiveBackwardREF(cumulative_resource, tail, head, edge_resource_consumption)


