cdef class OctreeSubsetSelector(SelectorObject):

    def __init__(self, dobj):
        self.base_selector = dobj.base_selector
        self.min_level = self.base_selector.min_level
        self.max_level = self.base_selector.max_level
        self.domain_id = dobj.domain_id
        self.overlap_cells = getattr(dobj.oct_handler, 'overlap_cells', 1)

    @cython.boundscheck(False)
    @cython.wraparound(False)
    @cython.cdivision(True)
    def select_grids(self,
                     np.ndarray[np.float64_t, ndim=2] left_edges,
                     np.ndarray[np.float64_t, ndim=2] right_edges,
                     np.ndarray[np.int32_t, ndim=2] levels):
        raise RuntimeError

    @cython.boundscheck(False)
    @cython.wraparound(False)
    @cython.cdivision(True)
    cdef int select_sphere(self, np.float64_t pos[3], np.float64_t radius) noexcept nogil:
        return 1

    @cython.boundscheck(False)
    @cython.wraparound(False)
    @cython.cdivision(True)
    cdef int select_cell(self, np.float64_t pos[3], np.float64_t dds[3]) noexcept nogil:
        return 1

    @cython.boundscheck(False)
    @cython.wraparound(False)
    @cython.cdivision(True)
    cdef int select_point(self, np.float64_t pos[3]) noexcept nogil:
        return self.base_selector.select_point(pos)

    @cython.boundscheck(False)
    @cython.wraparound(False)
    @cython.cdivision(True)
    cdef int select_bbox(self, np.float64_t left_edge[3],
                               np.float64_t right_edge[3]) noexcept nogil:
        # return 1
        return self.base_selector.select_bbox(left_edge, right_edge)

    @cython.boundscheck(False)
    @cython.wraparound(False)
    @cython.cdivision(True)
    cdef int select_grid(self, np.float64_t left_edge[3],
                         np.float64_t right_edge[3], np.int32_t level,
                         Oct *o = NULL) noexcept nogil:
        # Because visitors now use select_grid, we should be explicitly
        # checking this.
        cdef int res
        res = self.base_selector.select_grid(left_edge, right_edge, level, o)
        if self.domain_id == -1:
            return res
        elif res == 1 and o != NULL and o.domain != self.domain_id:
            return -1
        return res

    def _hash_vals(self):
        return (hash(self.base_selector), self.domain_id)

octree_subset_selector = OctreeSubsetSelector
