import GTree
from omniORB import CORBA
import GCD
from iNode import *
from pub import *
from TLS import *
import GblPilotQueryDef
from OFS.SimpleItem import SimpleItem
import GblPilotDef

from TimeStamp import *
from iLogger import *


def load_tree_interface (tag):
    sm = getTLS().get("Session", {})["SearchManager"]
    try:
        if (sm):
            return sm.get_index_tree(eval('GblPilotQueryDef.' + tag))
    except:
        print "Couldn't load index tree",tag
        write_error()
    
    return None

def iTree_load (tag):
    return iTree (load_tree_interface(tag))

class iTree(SimpleItem):
    lTree = None
    root_id = None
    root_children_count = None
    pointers_to_filter = []
    nodelist = []
    master_children_count = 0
    

    def __init__(self, itree, root_id = '[0]', root_children_count = None):
        self.lTree = itree
        self.root_id = root_id
        self.root_children_count = root_children_count
        #####################
        
    def get_branch(self, node_id, start_pos, count, maskfilter = None):
        if not self.lTree:
            return []
        node_list = []

        for server_node in self._get_branch(node_id, start_pos, count):
            try:
                inode = self._create_node (server_node, node_id)
            except:
                write_error ()
                continue
      
            if maskfilter:
                if maskfilter (inode):
                    node_list.append (inode)
            else:
                node_list.append(inode)
        return node_list
    
    def _create_node (self, server_node, parent_id):
        parent_path = eval (parent_id)
        parent_path.append (server_node.pointer)

        inode = iNode (str(parent_path), server_node.name.data)
        try:
            inode.ntype = server_node.value.type._n
        except:
            inode.ntype = ''
            
        try:
            inode.info = server_node.value.info
        except:
            inode.info = ""

        try:
            inode.type = server_node.value.type
        except:
            inode.type = ""
                
        try:
            inode.value_id = server_node.value.id
        except:
            inode.value_id = ''
         
        inode.children_count = server_node.master_children_count
        inode.children = []
        inode.node = server_node
        inode.server_tree = self.lTree
        
        return inode        
        #############################          

    def _get_branch(self, node_id, start_pos, count):
        start_pos = int (start_pos)
        count = int (count)
        parent_path = eval(node_id)
        
        try:
            start_node = parent_path[-1]
            if (not start_node):
                res = TimeStampWrap(self.lTree.get_branch, (GTree.NodeSelector(GTree.ROOT_PARENT_POINT, 0), 0, 0)).run()
                
                start_node = res[0].pointer
                
                self.master_children_count = res[0].master_children_count
                
                if (not self.master_children_count):
                    return []              
                
                if (count == 0): 
                    count = self.master_children_count
                    
            res = TimeStampWrap(self.lTree.get_branch, (GTree.NodeSelector(start_node, 0), start_pos, count)).run()
        except GCD.CanNotFindData:
            res = []
        except CORBA.UNKNOWN:
            res = []
        
        return res
    
    def _fake_root_node (self):
        root = iNode (str(self.root_id)
                      ,'Special root node'  #node.name.data
                      ,None
                      ,None
                      ,None
                      ,self.get_root_node_count () #node.master_children_count
                      )
        return root  
        

    def get_root_node_count(self):
        if (self.root_children_count == None and self.root_id == '[0]'):
            if not self.lTree:
                self.root_children_count = 0
                return 0
            
            self.root_children_count = TimeStampWrap(self.lTree.get_branch, (GTree.NodeSelector(GTree.ROOT_PARENT_POINT, 0), 0, 0)).run()[0].master_children_count
                    
        return self.root_children_count


    def _load_level (self, node, level, maskfilter = None):
        
        if (level == 0 or not node or not node.children_count):
            return
        
        node.children = self.get_branch (node.id, 0, node.children_count, maskfilter)
        
        for el in node.children:
            self._load_level(el, level - 1, maskfilter)


    def get_tree (self, level=1, maskfilter = None):
        root = self._fake_root_node ()
        self._load_level (root, int(level), maskfilter)
        
        return root.children
        #############################          


    def get_trimmed_tree (self):
        filter = [GTree.TrimFilter(1)]
        
        return self.get_filtered_tree (filter)
            
    def get_filtered_context_tree (self, context, order = "FO_ANY", area = 'SA_ALL_LEVEL'):
        if context:
            filter = [GTree.NameFilter(context, eval('GTree.'+area), eval('GTree.' + order), GTree.CP_ANY)]
        else:
            filter = None

        return self.get_filtered_tree (filter, truncate = 1)
        #####################
        
    def get_filtered_sort_tree (self, sort_type, sort_order, trunc):
        if (sort_type and sort_order):
            filter = [GTree.SortFilter(eval("GblPilotDef." + sort_type)._v, eval("GCD." + sort_order), None)]
        else:
            filter = None
# Вызывается метод наследника, если переопределен!

        return self.get_filtered_tree (filter, truncate = trunc)
        #####################
        

    def get_filtered_tree(self, filter, truncate = 0):
        if not self.lTree:
            return None
        
        flTree = None
        
        if (filter):
            flTree = self.lTree.get_view(0, filter, 0, truncate)[0]

        return flTree
        #####################
        
    def find (self, filter, start = 0):
        if not self.lTree:
            return None
        
        position = GTree.NodePosition (pos = 0, node = GTree.NodeSelector (child_pointer = 0))
        
        return self.lTree.find (start, filter)

    def find_next (self, nodeselector, filterlist):
        if not self.lTree:
            return [-1]
            
        return self.lTree.find_next(nodeselector, filterlist)


    def history (self):
        return self.lTree.get_my_history ()
        #####################
    
    def server_tree (self):
        return self.lTree

    def _pointer_filter (self, node):
        if node.numeric_id in self.pointers_to_filter:
            self.nodelist.append (node)
            return True
        
        return False
        
    
    def get_nodelist_by_pointerpath (self, pointer_path):
        self.nodelist = []
        self.pointers_to_filter = pointer_path
        self.get_tree (-1, self._pointer_filter)
        nodelist = self.nodelist
        self.nodelist = []
        
        return nodelist
        #####################

    def pointer_path_to_index_path (self, pointer_path):
        return self.lTree.pointer_path_to_index_path (pointer_path)
        
    
##############################################################