from search.general import char_compare
from search.string_iterator import StringIterator
from search.string_node import StringNode
from search.string_node_iterator import StringNodeIterator



class StringNodeList:
    def __init__(self, string):
        length = len(string)
        self.char_dict = dict([(x, []) for x in range(256)])
        self.node_list = [StringNode(x) for x in string]
        if length != 1:
            for index in range(length):
                if index == 0:
                    self.node_list[index].next = self.node_list[index + 1]
                elif index == len(string) - 1:
                    self.node_list[index].prev = self.node_list[index - 1]
                else:
                    self.node_list[index].next = self.node_list[index + 1]
                    self.node_list[index].prev = self.node_list[index - 1]
        for node in self.node_list:
            self.char_dict[ord(node.value)].append(node)

    def search(self, string):
        search_list = self.char_dict[ord(string[0])]
        search_list += self.char_dict[ord(string[0].swapcase())] if string[0].isalpha() else None
        results = []
        for node in search_list:
            str_node_iter = StringNodeIterator(node)
            str_iter = StringIterator(string)
            while str_node_iter.next_uniq_alpha_char():
                if char_compare(str_node_iter.cur.value, str_iter.cur()):
                    if str_iter.has_next_uniq():
                        str_iter.next_uniq_char()
                    else:
                        results.append([str_node_iter.root, str_node_iter.cur])
                        break
                else:
                    break
        return results


def nodes_to_string(start, end):
    word = []
    while start != end:
        word.append(start.value)
        start = start.next
    word.append(start.value)
    return ''.join(word)


def search_for_words(text_to_search, txt_to_search_for):
    my_list = StringNodeList(text_to_search)
    results = []
    for word in txt_to_search_for:
        string_node_list = my_list.search(word)
        results += [nodes_to_string(x, y) for x, y in string_node_list]
    return results

