# -*- coding: utf-8 -*-
#
# tree.py
#
# (c) D.C.-G. 2014
#
# Tree widget for albow
#
from albow.widget import Widget
from albow.menu import Menu
from albow.fields import IntField, FloatField, TextFieldWrapped
from albow.controls import CheckBox, AttrRef, Label, Button
from albow.dialogs import ask, alert, input_text_buttons
from albow.translate import _
from extended_widgets import ChoiceButton
from theme import ThemeProperty
from layout import Column, Row
from dialogs import Dialog
from palette_view import PaletteView
from scrollpanel import ScrollRow
from utils import blit_in_rect
from pygame import image, Surface, Rect, SRCALPHA, draw, event
import copy


#-----------------------------------------------------------------------------
item_types_map = {dict: ("Compound", None, {}),
                  int: ("Integer", IntField, 0),
                  float: ("Floating point", FloatField, 0.0),
                  unicode: ("Text", TextFieldWrapped, ""),
                  bool: ("Boolean", CheckBox, True),
                 }

def setup_map_types_item(mp=None):
    if not mp:
        mp = item_types_map
    map_types_item = {}
    for k, v in mp.items():
        if v[0] in map_types_item.keys():
            _v = map_types_item.pop(v[0])
            map_types_item[u"%s (%s)"%(_(v[0]), _v[0].__name__)] = _v
            map_types_item[u"%s (%s)"%(_(v[0]), k.__name__)] = (k, v[1], v[2])
        else:
            map_types_item[v[0]] = (k, v[1], v[2])
    return map_types_item

map_types_item = setup_map_types_item()


#-----------------------------------------------------------------------------
# Tree item builder methods
def create_base_item(self, i_type, i_name, i_value):
    return i_name, type(i_type)(i_value)

create_dict = create_int = create_float = create_unicode = create_bool = create_base_item


#-----------------------------------------------------------------------------
class SetupNewItemPanel(Dialog):
    def __init__(self, type_string, types=map_types_item, ok_action=None):
        self.type_string = type_string
        self.ok_action = ok_action
        title = Label("Choose default data")
        self.t, widget, self.v = types[type_string]
        self.n = u""
        w_name = TextFieldWrapped(ref=AttrRef(self, 'n'))
        self.w_value = self.get_widget(widget)
        col = Column([Column([title,]), Label(_("Item Type: %s")%type_string, doNotTranslate=True), Row([Label("Name"), w_name], margin=0), Row([Label("Value"), self.w_value], margin=0), Row([Button("OK", action=ok_action or self.dismiss_ok), Button("Cancel", action=self.dismiss)], margin=0)], margin=0, spacing=2)
        Dialog.__init__(self, client=col)

    def dismiss_ok(self):
        self.dismiss((self.t, self.n, getattr(self.w_value, 'value', map_types_item.get(self.type_string, [None,] * 3)[2])))

    def get_widget(self, widget):
        if hasattr(widget, 'value'):
            value = widget(value=self.v)
        elif hasattr(widget, 'text'):
            value = widget(text=self.v)
        elif widget is None:
            value = Label("This item type is a container. Add chlidren later.")
        else:
            msg = "*** Error in SelectItemTypePanel.__init__():\n    Widget <%s> has no 'text' or 'value' member."%widget
            print msg
            value = Label(msg)
        return value


#-----------------------------------------------------------------------------
class SelectItemTypePanel(Dialog):
    def __init__(self, title, responses, default=None, ok_action=None):
        self.response = responses[0]
        self.ok_action = ok_action
        title = Label(title)
        self.w_type = ChoiceButton(responses)
        col = Column([title, self.w_type, Row([Button("OK", action=ok_action or self.dismiss_ok), Button("Cancel", action=ok_action or self.dismiss)], margin=0)], margin=0, spacing=2)
        Dialog.__init__(self, client=col)

    def dismiss_ok(self):
        self.dismiss(self.w_type.selectedChoice)


#-----------------------------------------------------------------------------
def select_item_type(ok_action, types=map_types_item):
    if len(types) > 1:
        choices = t
ypes.keys()
        choices.sort()
        result = SelectItemTypePanel("Choose item type", responses=choices, default=None).present()
    else:
        result = types.keys()[0]
    if type(result) in (str, unicode):
        return SetupNewItemPanel(result, types, ok_action).present()
    return None


#-----------------------------------------------------------------------------
class TreeRow(ScrollRow):
    def click_item(self, n, e):
        self.parent.click_item(n, e.local)

    def mo
use_down(self, e):
        if e.button == 3:
            _e = event.Event(e.type, {'alt': e.alt, 'meta': e.meta, 'ctrl': e.ctrl,
                              'shift': e.shift, 'button': 1, 'cmd': e.cmd,
                              'local': e.local, 'pos': e.pos,
                              'num_clicks': e.num_clicks})
            ScrollRow.mouse_down(self, _e)
            self.parent.show_menu(e.local)
        else:
            ScrollRow.mouse_down(self, e)


#-----------------------------------------------------------------------------
class Tree(Column):
    """..."""
    rows = []
    row_margin = 2
    column_margin = 2
    bullet_size = ThemeProperty('bullet_size')
    bullet_color_active = ThemeProperty('bullet_color_active')
    bullet_color_inactive = ThemeProperty('bullet_color_inactive')

    def __init__(self, *args, **kwargs):
        self.menu = [("Add", "add_item"),
                     ("Delete", "delete_item"),
                     ("New child", "add_child"),
                     ("Rename", "rename_item"),
                     ("", ""),
                     ("Cut", "cut_item"),
                     ("Copy", "copy_item"),
                     ("Paste", "paste_item"),
                     ("Paste as child", "paste_child"),
                     ]
        if not hasattr(self, 'map_types_item'):
            global map_types_item
            self.map_types_item = setup_map_types_item()
        self.selected_item_index = None
        self.selected_item = None
        self.clicked_item = None
        self.copyBuffer = kwargs.pop('copyBuffer', None)
        self._parent = kwargs.pop('_parent', None)
        self.styles = kwargs.pop('styles', {})
        self.compound_types = [dict,] + kwargs.pop('compound_types', [])
        self.item_types = self.compound_types + kwargs.pop('item_types', [a[0] for a in self.map_types_item.values()] or [int, float, unicode, bool])
        for t in self.item_types:
            if 'create_%s'%t.__name__ in globals().keys():
                setattr(self, 'create_%s'%t.__name__, globals()['create_%s'%t.__name__])
        self.show_fields = kwargs.pop('show_fields', False)
        self.deployed = []
        self.data = data = kwargs.pop("data", {})
        self.draw_zebra = draw_zebra = kwargs.pop('draw_zebra', True)
#        self.inner_width = kwargs.pop('inner_width', 'auto')
        self.inner_width = kwargs.pop('inner_width', 500)
        self.__num_rows = len(data.keys())
        self.build_layout()
#        row_height = self.font.size(' ')[1]
        row_height = self.font.get_linesize()
        self.treeRow = treeRow = TreeRow((self.inner_width, row_height), 10, draw_zebra=draw_zebra)
        Column.__init__(self, [treeRow,], **kwargs)

    def dispatch_key(self, name, evt):
        if not hasattr(evt, 'key'):
            return
        if name == "key_down":
            keyname = self.root.getKey(evt)
            if keyname == "Up" and self.selected_item_index > 0:
                if self.selected_item_index == None:
                    self.selected_item_index = -1
                self.selected_item_index = max(self.selected_item_index - 1, 0)

            elif keyname == "Down" and self.selected_item_index < len(self.rows) - 1:
                if self.selected_item_index == None:
                    self.selected_item_index = -1
                self.selected_item_index += 1
            elif keyname == 'Page down':
                if self.selected_item_index == None:
                    self.selected_item_index = -1
        