#!/usr/bin/env python
# coding:utf-8
# Author:  mozman -- <mozman@gmx.at>
# Purpose: TreeSlice
# Created: 11.04.2011
# Copyright (c) 2010-2013 by Manfred Moitzi
# License: MIT License


class TreeSlice(object):
    __slots__ = ['_tree', '_start', '_stop']

    def __init__(self, tree, start, stop):
        self._tree = tree
        self._start = start
        self._stop = stop

    def __repr__(self):
        tpl = "%s({%s})" % (self._tree.__class__.__name__, '%s')
        return tpl % ", ".join(("%r: %r" % item for item in self.items()))

    def __contains__(self, key):
        if self._is_in_range(key):
            return key in self._tree
        else:
            return False

    def _is_in_range(self, key):
        if self._start is not None and key < self._start:
            return False
        if self._stop is not None and key >= self._stop:
            return False
        return True

    def __getitem__(self, key):
        if isinstance(key, slice):
            return self._sub_slice(key.start, key.stop)
        if self._is_in_range(key):
            return self._tree[key]
        else:
            raise KeyError(key)

    def _sub_slice(self, start, stop):
        def newstart():
            if start is None:
                return self._start
            elif self._start is None:
                return start
            else:
                return max(start, self._start)

        def newstop():
            if stop is None:
                return self._stop
            elif self._stop is None:
                return stop
            else:
                return min(stop, self._stop)

        return TreeSlice(self._tree, newstart(), newstop())

    def keys(self):
        return self._tree.key_slice(self._start, self._stop)

    __iter__ = keys

    def values(self):
        return self._tree.value_slice(self._start, self._stop)

    def items(self):
        return self._tree.iter_items(self._start, self._stop)
