from functools import partial

from direct.gui.DirectGui import *
from panda3d.core import TextNode, WindowProperties, LVector2

from global_stuff import base, anonymous


class ConsoleEntry:
    text_color = (0.15, 0.15, 0.15, 1)
    unfocus_color = (0.5, 0.5, 0.5, 1)
    highlight_color = (0, 0, 0, 1)
    error_color = (1, 0.5, 0.5, 1)

    def __init__(self, x, y, lines):
        self._selected_line = None
        props = WindowProperties()
        base.win.request_properties(props)
        if (props.has_size()):
            winsize = props.get_size()
        else:
            winsize = LVector2(1280, 720)

        line_height = 35
        height = lines*line_height
        y = -y

        self.entries = [
            DirectEntry(text="", scale=(35, 1, 35),
                        pos=(x, 0, y - line_height*(i+0.75)),
                        command=partial(self.next_line, i=i), parent=base.pixel2d, relief=None,
                        focusInCommand=partial(self.set_active, i=i),
                        initialText="", numLines=1, focus=1)
            for i in range(lines)
        ]

        self.default_tn = TextNode('default')
        self.default_tn.setFont(anonymous)
        self.default_tn.set_text_color(self.text_color)

        self.unfocus_tn = TextNode('unfocus')
        self.unfocus_tn.setFont(anonymous)
        self.unfocus_tn.set_text_color(self.unfocus_color)

        self.error_tn = TextNode('error_tn')
        self.error_tn.setFont(anonymous)
        self.error_tn.set_text_color(self.error_color)

        self.highlight_tn = TextNode('highlight_tn')
        self.highlight_tn.setFont(anonymous)
        self.highlight_tn.set_text_color(self.highlight_color)

        self.clear_error()

    def hide(self):
        for e in self.entries:
            e.hide()

    def show(self):
        for i in self.entries:
            i.show()

    def clear(self):
        for e in self.entries:
            e.set("")

    def clear_error(self):
        for e in self.entries:
            e.guiItem.setTextDef(0, self.highlight_tn)
            e.guiItem.setTextDef(1, self.default_tn)

    def unfocus(self):
        for e in self.entries:
            if e.guiItem.getTextDef(1) == self.default_tn:
                e.guiItem.setTextDef(0, self.highlight_tn)
                e.guiItem.setTextDef(1, self.unfocus_tn)

    def focus(self):
        for e in self.entries:
            if e.guiItem.getTextDef(1) == self.unfocus_tn:
                e.guiItem.setTextDef(0, self.highlight_tn)
                e.guiItem.setTextDef(1, self.default_tn)

    def set_error(self, *indices):
        for i in indices:
            e = self.entries[i]
            e.guiItem.setTextDef(1, self.error_tn)
            e.guiItem.setTextDef(0, self.error_tn)

    def set_active(self, i):
        self._selected_line = i
        base.accept_once('arrow_up', lambda: self.select_line(self._selected_line-1))
        base.accept_once('arrow_down', lambda: self.select_line(self._selected_line+1))

    def next_line(self, text, i):
        if i < len(self.entries) - 1:
            self.select_line(i+1)

    def select_line(self, i):
        if i < 0 or i > len(self.entries) - 1:
            return
        self.entries[i].setFocus()

    @property
    def text(self):
        out_string = ""
        for entry in self.entries:
            out_string += entry.get(True) + "\n"
        return out_string

