from .filechooserthumbview import StudioFileChooserThumbView

from kivy.uix.modalview import ModalView
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button

from kivy.properties import ObjectProperty, OptionProperty
from kivy.factory import Factory
from kivy.core.window import Window
from kivy.utils import platform
from kivy.lang import Builder

import os
from functools import partial

from kivystudio.behaviors import HighlightBehavior
from kivystudio.widgets.splitter import StudioSplitter

file_path = os.path.dirname(__file__)

from kivy.resources import resource_add_path
resource_add_path(os.path.join(file_path, 'images'))
resource_add_path(os.path.join(file_path, 'file_formats'))

Builder.load_file(os.path.join(file_path,'filemanager.kv'))

# filepath_for_cool_icons ='/usr/share/icons/Vibrancy-Kali/apps/64'


class SideSelector_(HighlightBehavior, FocusBehavior, GridLayout):
    pass


class SideButton_(Button):

    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos):
            self.parent.set_highlighted(self)

        return super(SideButton_, self).on_touch_down(touch)

class FileManager(ModalView):

    _dir_selector = ObjectProperty(None)
    '''internal widget used to show and display the current dir path'''

    _file_chooser = ObjectProperty(None)
    ''' the internal file chooser a subclass of FileChooserController'''

    mode = OptionProperty('open_file', options=['open_file', 'save_file', 'choose_dir'])

    __events__ = ('on_finished', )

    def __init__(self, **k):
        super(FileManager, self).__init__(**k)
        self.new_bub = Factory.NewFolderBub_()
        self.new_bub.ids.input.bind(on_text_validate=self.create_new_folder)
        self._file_chooser.path = self.get_defualt_user_dir()

        # self.mode = 'save_file'

    def get_defualt_user_dir(self):
        default_dir = None
        if platform == 'linux':
            username = os.getlogin()
            if username != 'root':
                default_dir = r'/home/%s'%username
            else:
                default_dir = r'/root'

        elif platform == 'win':
            base = os.getcwd().split("\\")[:3]
            default_dir = "\\".join(base)

        return default_dir

    def set_side_panel_dir(self, name):
        user_dir = self.get_defualt_user_dir()

        self._file_chooser.path = os.path.join(user_dir, name)

    def on_path(self, path):
        path_list = path.split('/')

        self._dir_selector.clear_widgets()
        for i in path_list:
            if i:
                btn = Factory.DirButton_(size_hint=(None,1), text=str(i))

                btn.bind(on_release=partial(self._go_dir_with_btn, btn))

                if btn.width <= btn.texture_size[0]:
                    btn.width = btn.texture_size[0]+10

                self._dir_selector.add_widget(btn)
        else:
            if i:
                self.ids.dir_scroll.scroll_to(btn)

    def _go_dir_with_btn(self, btn, *args):
        path_list = []
        children = self._dir_selector.children[:]
        children.reverse()
        for child in children:
            path_list.append(child.text)
            if child == btn:
                break

        self._file_chooser.path = '/'+ '/'.join(path_list)

    def on_open(self):
        Window.bind(on_key_down=self.handle_key)

    def on_dismiss(self):
        Window.unbind(on_key_down=self.handle_key)
        # remove bubble if open
        if self.new_bub in Window.children:
            Window.remove_widget(self.new_bub)

    def handle_key(self, keyboard, key, codepoint, text, modifier, *args):
        if key == 8:    # if user press the backspace reverse dir
            if self.mode!='save_file' or (hasattr(self,'save_widget') \
                 and not(self.save_widget.ids.input.focus)):
                self.reverse_dir()
        elif key == 27:
            self.handle_escape()
        elif key == 13:     # enter
            pass

    def reverse_dir(self):
        previous_path = os.path.dirname(self._file_chooser.path)

        if os.path.exists(previous_path):
            self._file_chooser.path = previous_path

    def on_mode(self, *args):
        if hasattr(self, 'save_widget') and \
                self.save_widget in self.ids.saving_container.children:
               self.ids.saving_container.remove_widget(self.save_widget)
        if hasattr(self, 'folder_btn') and \
            self.folder_btn in self.ids.saving_container.children:
            self.ids.saving_container.remove_widget(self.folder_btn)

        if self.mode == 'save_file':
            self.ids.title.text = 'Save file'
            if not hasattr(self, 'save_widget'):
                self.save_widget = Factory.SaveWidget_()
                self.save_widget.ids.input.bind(on_text_validate=self.handle_saving)
                func = lambda *args: self.handle_saving(self.save_widget.ids.input)
                self.save_widget.ids.save_btn.bind(on_release=func)
            self.ids.saving_container.add_widget(self.save_widget)

        else:
            if self.mode == 'open_file':
                self.ids.title.text = 'Open file'

            elif self.mode == 'choose_dir':
                self.ids.title.text = 'Open folder'

                if not hasattr(self, 'folder_btn'):
                    self.folder_btn = Factory.DirButton_(text='Select')
                    self.folder_btn.bind(on_release=self.folder_selected)
                self.ids.saving_container.add_widget(self.folder_btn)
    
    def folder_selected(self, *args):
        path=self.ids.file_chooser.ids.stacklayout.current_highlighted_child.path
        self.dispatch('on_finished', path)

    def handle_escape(self):
        if self.new_bub in Window.children:
            Window.remove_widget(self.new_bub)
        else:
            self.dismiss()        

    def handle_bubble(self, btn):
        if self.new_bub in Window.children:
            Window.remove_widget(self.new_bub)
        else:
            self.new_bub.pos = (btn.x - (self.new_bub.width-btn.width), btn.y - self.new_bub.height)
            Window.add_widget(self.new_bub)

    def create_new_folder(self, textinput):
        path = os.path.join(self._file_chooser.path, textinput.text)
        if not os.path.exists(path):
            print('making folder ', path)
            try:
                os.mkdir(path)

                # a simple trick to force the file chooser to recompute the files
                former_path = self._file_chooser.path
                self._file_chooser.path = 'eeraef7h98fwb38rh3f8h23yr8i'  # change to an invaid path
                self._file_chooser.path = former_path       # then change back
                Window.remove_widget(self.new_bub)

            except OSError:
                print('error making dir')
        else:
            print('already exists')

    def handle_saving(self, textinput):
        path = os.path.join(self._file_chooser.path, textinput.text)
        if not os.path.exists(path):
            self.dispatch('on_finished', path)
        else:
            print('file already exist')

    def file_selected(self, obj, path):
        if self.mode == 'open_file':
            self.dispatch('on_finished', path)
            self.dismiss()

    def on_finished(self, path):
        self.on_selection([path])
        self.dismiss()

    def open_file(self, path='', on_selection=None):
        self.mode = 'open_file'
        self.on_selection = on_selection
        self.open()

    def save_file(self, path='', on_selection=None):
        self.mode = 'save_file'
        self.on_selection = on_selection
        self.open()
        
    def choose_dir(self, path='', on_selection=None):
        self.mode = 'choose_dir'
        self.on_selection = on_selection
        self.open()

filemanager = FileManager()


if __name__ == "__main__":
    from kivy.base import runTouchApp
    from kivy.uix.button import Button

    file_picker = FileManager()
    btn = Button(text='push me')
    btn.bind(on_release=lambda *args: file_picker.open())
    runTouchApp(btn)