from kivy.logger import Logger
from kivy.graphics import Color, Rectangle
from kivy.uix.button import ButtonBehavior
from kivy.uix.image import AsyncImage
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.widget import Widget
from kivy.app import App
from kivy.clock import Clock
from kivy.factory import Factory
from kivy.properties import StringProperty, DictProperty, \
			OptionProperty, ListProperty, NumericProperty, \
			BooleanProperty

from appPublic.dictObject import DictObject
from appPublic.registerfunction import RegisterFunction

from .widgetExt.scrollwidget import ScrollWidget
from .utils import *
from .ready import WidgetReady
from .color_definitions import getColors
from .baseWidget import Text, Box
from .scrollpanel import ScrollPanel
from .command_action import cmd_action

class Toolbar(ScrollPanel):
	"""
	tool has the follow attributes
	{
		"name",
		"source_on,
		"source_off,
		# source_on, source_off, or "img_src",
		"label",
		"deletable"
		"url",
		"rfname",
	}
	toolbar has follow attributes
	{
		"img_size_c":image height in charecter size
		"text_size_c":
		"toolbar_orient":"H" or "V"
		"tool_orient":"horizontal" or "vertical"
		"css_on",
		"css_off",
		"tools":
	}
	"""

	css_on = StringProperty('default')
	css_off = StringProperty('default')
	tools = ListProperty([])
	tool_orient = OptionProperty('horizontal', \
						options=['horizontal', 'vertical'])
	toolbar_orient = OptionProperty('H', options=['H', 'V'])
	img_size_c = NumericProperty(2)
	text_size_c = NumericProperty(1)
	target = StringProperty(None)
	executable = BooleanProperty(False)
	def __init__(self, **kw):
		self.w_dic = {}
		SUPER(Toolbar, self, kw)
		self.buffer = {}
		self.register_event_type('on_press')
		self.register_event_type('on_delete_tool')
		if self.toolbar_orient == 'H':
			self._inner.orientation = 'horizontal'
		else:
			self._inner.orientation = 'vertical'
		self.clear_widgets()
		for t in self.tools:
			self.add_tool(t)
		
		self.bar_width = 0
		if self.toolbar_orient == 'H':
			self.do_scroll_y = False
		else:
			self.do_scroll_x = False

	def on_children_size(self, o, size):
		self.on_size(None, None)

	def on_size(self, o, size):
		if self.toolbar_orient == 'H':
			self.size_hint_x = 1
			self.size_hint_y = None
			if len(self.w_dic.keys()) > 0:
				self.height = max([w.height for w in self.w_dic.keys()])
		else:
			self.size_hint_x = None
			self.size_hint_y = 1
			if len(self.w_dic.keys()) > 0:
				self.width = max([w.width for w in self.w_dic.keys() ])
		
	def add_tool(self, t):
		label = t.get('label', t.get('name', None))
		source_on = t.get('source_on', t.get('img_src',None))
		source_off = t.get('source_off', t.get('img_src', None))
		ToggleIconText = Factory.ToggleIconText
		ToggleText = Factory.ToggleText
		ToggleImage = Factory.ToggleImage
		ClickableImage = Factory.ClickableImage
		if label and source_on:
			w = ToggleIconText(css_on=self.css_on,
							css_off=self.css_off,
							text=label,
							size_hint = (None, None),
							fontsize=self.text_size_c,
							source_on=source_on,
							source_off=source_off,
							orientation=self.tool_orient,
							img_kw={
								"size_hint":(None, None),
								"height":CSize(self.img_size_c),
								"width":CSize(self.img_size_c)
							}
			)
		elif label:
			w = ToggleText(css_on=self.css_on,
							css_off=self.css_off,
							size_hint = (None, None),
							orientation=self.tool_orient,
							fontsize=CSize(self.text_size_c),
							text=label)
		elif source_on:
			w = ToggleImage( source_on=source_on,
							source_off=source_off,
							size_hint = (None, None),
							orientation=self.tool_orient,
							img_kw={
								"size_hint":(None, None),
								"height":CSize(self.img_size_c),
								"width":CSize(self.img_size_c)
							}
			)

		w.widget_id = t['name']
		if t.get('deletable', False):
			x = ClickableImage(source=blockImage('delete.png'),
							size_hint=(None,None),
							size=CSize(1,1)
						)
			x.data = (w, t)
			x.bind(on_press=self.delete_tool)
			w.add_widget(x)

		if w:
			self.add_widget(w)
			self.w_dic[w] = t.copy()
			self.w_dic[w]['widget'] = w
			w.select(False)
			w.bind(size=self.on_children_size)
			w.bind(on_press=self.tool_press)
			w.bind(minimum_width=w.setter('width'))
			w.bind(minimum_height=w.setter('height'))

	def delete_tool(self, o):
		w, t = o.data
		self.del_tool(w)
		self.dispatch('on_delete_tool', o.data)

	def on_delete_tool(self, o, d=None):
		pass

	def del_tool(self, w):
		self.remove_widget(w)
		self.w_dic = {k:v for k,v in self.w_dic.copy().items() \
						if k != w }
		
	def on_press(self, o):
		pass

	def select(self,name):
		for w, v in self.w_dic.items():
			if v['name'] == name:
				w.select(True)
				self.tool_press(w)
				break

	def tool_press(self, o):
		for w,v in self.w_dic.items():
			if w == o:
				ret_v = v
				w.select(True)
			else:
				w.select(False)
		if not self.executable:
			self.dispatch('on_press', ret_v)
			return

		desc = self.w_dic[o].copy()
		if not desc.get('target'):
			desc['target'] = self.target

		cmd_action(desc, self)

class ToolPage(Box):
	"""
	ToolPage:
	{
		toolbar_size:
		tool_at
		toolbar
	}
	"""
	toolbar_size = NumericProperty(2)
	tool_at = OptionProperty('top', \
					options=['top', 'bottom', 'left', 'right'])
	toolbar = DictProperty({})
	def __init__(self, **kw):
		SUPER(ToolPage, self, kw)
		if self.tool_at in [ 'top','bottom']:
			self.orientation = 'vertical'
		else:
			self.orientation = 'horizontal'
		if not self.toolbar_size:
			self.toolbar_size = self.img_size + self.text_size + 0.3
		self.content_widgets = {}
		self.content_w = None
		self.toolbar_w = None
		self.init()
		self.toolbar_w.bind(on_delete_tool=self.delete_content_widget)
		name = self.toolbar['tools'][0]['name']
		self.toolbar_w.select(name)
	
	def get_subwidgets(self):
		children = [ i for i in self.children]
		x = [ i for i in self.content_widgets.values() ]
		return children + x

	def delete_content_widget(self, o, d):
		w, dic = d
		self.del_tool(dic['name'])

	def add_tool(self, tool):
		self.toolbar_w.add_tool(tool)

	def del_tool(self, name):
		g = self.content_widgets.copy()
		self.content_widgets = {k:v for k,v in g.items() if k!=name}

	def on_size(self,obj,size):
		if self.content_w is None:
			return
		if self.tool_at in ['top','bottom']:
			self.toolbar_w.size_hint_y = None
			self.content_w.height = self.height - self.toolbar_w.height
		else:
			self.toolbar_w.size_hint_x = None
			self.content_w.width = self.width - self.toolbar_w.width

	def init(self):
		self.content_w = BoxLayout()
		self.content_w.widget_id = 'content'
		self.toolbar_w = Toolbar(**self.toolbar)
		if self.tool_at in ['top','left']:
			self.add_widget(self.toolbar_w)
			self.add_widget(self.content_w)
		else:
			self.add_widget(self.content_w)
			self.add_widget(self.toolbar_w)
		
		self.toolbar_w.bind(on_press=self.on_press_handle)

	def build_widget(self, url):
		desc = {
			"widgettype":"urlwidget",
			"options":{
				"url":url
			}
		}
		b = Factory.Blocks()
		return b.widgetBuild(desc)

	def print_all(self):
		self.print_info(self)
		self.print_info(self.toolbar_w)
		for w in self.toolbar_w.w_dic.keys():
			self.print_info(w)
			for c in w.children:
				self.print_info(c)
		self.print_info(self.content_w)
		for c in self.content_w.children:
			self.print_info(c)

	def print_info(self, o):
		print('self.size_hint=', o.__class__, o.size_hint, 
				'self.x,y=', o.width, o.height)
		
	def on_press_handle(self, o, v):
		name = v.get('name')
		refresh = v.get('refresh', False)
		# self.print_all()

		w = self.content_widgets.get(name)
		self.content_w.clear_widgets()
		if w and not refresh:
			self.content_w.add_widget(w)
			return
		url = v.get('url')
		if url:
			w = self.build_widget(url)
			if w:
				self.content_widgets[name] = w
				self.content_w.add_widget(w)
			return
		rfname = v.get('rfname')
		if rfname:
			rf = RegisterFunction()
			f = rf.get(rfname)
			if f:
				r = f()
				if isinstance(r,Widget):
						self.content_w.add_widget(r)

