# This file is part of Elide, frontend to Lisien, a framework for life simulation games.
# Copyright (c) Zachary Spector, public@zacharyspector.com
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.
from functools import partial

from kivy.app import App
from kivy.clock import Clock
from kivy.properties import ListProperty, ObjectProperty, StringProperty
from kivy.uix.recycleview import RecycleView
from kivy.uix.screenmanager import Screen

from .util import SelectableRecycleBoxLayout, logwrap, store_kv

# TODO: Visual preview
# TODO: Background image chooser


class CharactersRecycleBoxLayout(SelectableRecycleBoxLayout):
	character_name = StringProperty()

	@partial(logwrap, section="CharactersRecycleBoxLayout")
	def apply_selection(self, index, view, is_selected):
		super().apply_selection(index, view, is_selected)
		if is_selected:
			self.character_name = view.text


class CharactersView(RecycleView):
	character_name = StringProperty()

	def __init__(self, **kwargs):
		self.i2name = {}
		self.name2i = {}
		super().__init__(**kwargs)


class CharactersScreen(Screen):
	toggle = ObjectProperty()
	charsview = ObjectProperty()
	character_name = StringProperty()
	wallpaper_path = StringProperty()
	names = ListProperty()
	new_board = ObjectProperty()
	push_character_name = ObjectProperty()

	@property
	def engine(self):
		return App.get_running_app().engine

	@logwrap(section="CharactersScreen")
	def new_character(self, name, *_):
		self.engine.add_character(name)
		self.ids.newname.text = ""
		i = len(self.charsview.data)
		self.charsview.i2name[i] = name
		self.charsview.name2i[name] = i
		self.charsview.data.append({"index": i, "text": name})
		self.names.append(name)
		self.new_board(name)
		self.push_character_name(name)

	@logwrap(section="CharactersScreen")
	def _trigger_new_character(self, name):
		part = partial(self.new_character, name)
		if hasattr(self, "_scheduled_new_character"):
			Clock.unschedule(self._scheduled_new_character)
		self._scheduled_new_character = Clock.schedule_once(part)

	@logwrap(section="CharactersScreen")
	def _munge_names(self, names):
		for i, name in enumerate(names):
			self.charsview.i2name[i] = name
			self.charsview.name2i[name] = i
			yield {"index": i, "text": name}

	@logwrap(section="CharactersScreen")
	def on_names(self, *_):
		app = App.get_running_app()
		if not app.character or not self.charsview:
			Clock.schedule_once(self.on_names, 0)
			return
		self.charsview.data = list(self._munge_names(self.names))
		charname = app.character.name
		for i, name in enumerate(self.names):
			if name == charname:
				self.charsview.children[0].select_node(i)
				return

	@logwrap(section="CharactersScreen")
	def on_charsview(self, *_):
		if not self.push_character_name:
			Clock.schedule_once(self.on_charsview, 0)
			return
		self.charsview.bind(character_name=self.setter("character_name"))
		self.bind(character_name=self.push_character_name)


store_kv(
	__name__,
	"""
#: import resource_find kivy.resources.resource_find
<CharactersView>:
	viewclass: 'RecycleToggleButton'
	character_name: boxl.character_name
	CharactersRecycleBoxLayout:
		id: boxl
		multiselect: False
		default_size: None, dp(56)
		default_size_hint: 1, None
		size_hint_y: None
		height: self.minimum_height
		orientation: 'vertical'
<CharactersScreen>:
	name: 'chars'
	charsview: charsview
	BoxLayout:
		id: chars
		orientation: 'vertical'
		CharactersView:
			id: charsview
			size_hint_y: 0.8
			character_name: root.character_name
		TextInput:
			id: newname
			size_hint_y: 0.1
			hint_text: 'New character name'
			write_tab: False
			multiline: False
		Button:
			text: '+'
			on_release: root._trigger_new_character(newname.text)
			size_hint_y: 0.05
		Button:
			text: 'Close'
			on_release: root.toggle()
			size_hint_y: 0.05
""",
)
