#!/usr/bin/env python3.5
# Copyright 2017 Digital
#
# This file is part of BeeWatch.
#
# BeeWatch is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# BeeWatch 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with BeeWatch.  If not, see <http://www.gnu.org/licenses/>.

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from gi.repository import Gdk
import logging
import logging.config
import os
import pprint
import random
import string
import sys
import time
import yaml
# My libraries
import beewatch
import beewatch.gui
import digilib.misc
import digilib.gui
import digilib.network
## Logging
lgui = logging.getLogger(__name__+".gui")

class ChildConsole(digilib.gui.ChildConsole):
    def __init__(self,get_client=None):
        super(ChildConsole,self).__init__(get_client)
        self.text_buffer_log.set_text("program:HAIIII")
        self.add_msg(digilib.misc.LOREM_IPSUM,"code")
        self.add_msg(digilib.misc.LOREM_IPSUM,"code")
        self.add_msg(digilib.misc.LOREM_IPSUM,"code")


class ChildOverview(digilib.gui.ChildOverview):
    def __init__(self):
        super(ChildOverview,self).__init__()
        self.prepare()
    def prepare(self):
        self.infobox1 = digilib.gui.InfoFrame()
        self.infobox2 = digilib.gui.InfoFrame()
        self.make_infobox_controller()
        self.make_infobox_weight()
        self.make_infobox_test(self.infobox1)
        self.make_infobox_test(self.infobox2)
        self.layout.attach(self.infobox_controller,0,0,1,1)
        self.layout.attach(self.infobox_weight,    1,0,1,1)
        self.layout.attach(self.infobox1,          0,1,1,1)
        self.layout.attach(self.infobox2,          1,1,1,1)
    def make_infobox_controller(self):
        levelbar_cpu = Gtk.LevelBar()
        levelbar_cpu.set_hexpand(True)
        levelbar_mem = Gtk.LevelBar()
        levelbar_mem.set_hexpand(True)
        self.infobox_controller = digilib.gui.InfoFrame(label="Weight")
        self.infobox_controller.add_line("uptime","Uptime:","99:59:592017-03-06 12:56")
        self.infobox_controller.add_line("ip","IP:","30.47.10.O9",None)
        self.infobox_controller.add_line("cpu","CPU:",30,"%",
            levelbar_cpu,True)
        self.infobox_controller.add_line("mem","Memory:",0.40,"%",
            levelbar_mem,True)
    def make_infobox_weight(self):
        self.infobox_weight = digilib.gui.InfoFrame(label="Weight")
        self.infobox_weight.add_line("total","Total:","50 kg")
        self.infobox_weight.add_line("bees","Bees:","20 kg")
        self.infobox_weight.add_line("honey","Honey:","42 kg")
        self.infobox_weight.add_line("time","Time:","2017-03-06 12:56")
    def make_infobox_test(self,infobox):
        infobox.add_line("1","Label:","Value")
        infobox.add_line("2","Baum:","Haus")
        infobox.add_line("3","Weight:","40 kg")
        infobox.add_line("4","Wiff","Woff")

class ChildControl(digilib.gui.ChildControl):
    def __init__(self):
        super(ChildControl, self).__init__()
        self.prepare()
    def prepare(self):
        pass

class ChildSettings(digilib.gui.ChildSettings):
    def __init__(self):
        super(ChildSettings, self).__init__()
        self.prepare()
    def prepare(self):
        pass

class BeeWindow(digilib.gui.WindowBase):
    def __init__(self,host,port,af_family):
        super(BeeWindow,self).__init__(title="BeeWatch")
        self.host = host
        self.port = port
        self.af_family = af_family
        self.client = None
        self.set_border_width(10)
        self.tb = digilib.misc.Container()
        self.prepare()
        self.add_key_shortcut("Control_L q",self.quit)
        self.add_key_shortcut("Control_L h e",lgui.info,["hello world"])
        self.add_key_shortcut("Control_L h i",lgui.info,["hi world"])
        # self.client = self.make_client()
    def prepare(self):
        self.child_console = ChildConsole(self.get_client)
        self.child_overview = ChildOverview()
        self.child_control = ChildControl()
        self.child_settings = ChildSettings()
        self.child_test = self.make_child_test()
        self.child_label = self.make_child_label()
        self.make_toolbar()
        self.stack = Gtk.Stack()
        self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT_RIGHT)
        self.stack.set_transition_duration(750)
        self.stack.add_titled(self.child_console, "child_console", "Console")
        self.stack.add_titled(self.child_overview, "child_overview", "Overview")
        self.stack.add_titled(self.child_control, "child_control", "Control")
        self.stack.add_titled(self.child_settings, "child_settings", "Settings")
        self.stack.add_titled(self.child_test, "check", "Check Button")
        self.stack.add_titled(self.child_label, "label", "A label")
        self.stack_switcher = Gtk.StackSwitcher()
        self.stack_switcher.set_stack(self.stack)
        self.scrolled_switcher = Gtk.ScrolledWindow()
        self.scrolled_switcher.add(self.stack_switcher)
        self.vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
        self.vbox.add(self.tb.toolbar)
        self.vbox.add(self.scrolled_switcher)
        self.vbox.add(self.stack)
        self.add(self.vbox)
        # self.vbox.pack_start(self.stack_switcher, True, True, 0)
        # self.vbox.pack_start(self.stack, True, True, 0)
    def make_toolbar(self):
        self.tb.toolbar = Gtk.Toolbar()
        self.tb.img_connect = Gtk.Image(stock=Gtk.STOCK_CONNECT)
        self.tb.img_connect.set_tooltip_text("Connect")
        self.tb.bconnect = Gtk.ToolButton()
        self.tb.bconnect.set_icon_widget(self.tb.img_connect)
        self.tb.bconnect.connect("clicked",self.on_connect_request)
        self.tb.img_disconnect = Gtk.Image(stock=Gtk.STOCK_DISCONNECT)
        self.tb.img_disconnect.set_tooltip_text("Disconnect")
        self.tb.bdisconnect = Gtk.ToolButton()
        self.tb.bdisconnect.set_icon_widget(self.tb.img_disconnect)
        self.tb.bdisconnect.connect("clicked",self.on_disconnect_request)
        self.tb.img_auto_scroll = Gtk.Image(stock=Gtk.STOCK_GOTO_BOTTOM)
        self.tb.img_auto_scroll.set_tooltip_text("Toggle auto scrolling")
        self.tb.bauto_scroll = Gtk.ToolButton()
        self.tb.bauto_scroll.set_icon_widget(self.tb.img_auto_scroll)
        self.tb.bauto_scroll.connect(
            "clicked",self.child_console.toggle_scroll)
        self.tb.img_scroll_down = Gtk.Image(stock=Gtk.STOCK_GO_DOWN)
        self.tb.img_scroll_down.set_tooltip_text("Toggle auto scrolling")
        self.tb.bscroll_down = Gtk.ToolButton()
        self.tb.bscroll_down.set_icon_widget(self.tb.img_scroll_down)
        self.tb.bscroll_down.connect(
            "clicked",self.child_console.scroll_down)
        self.tb.iconnected = Gtk.ToolItem()
        self.tb.img_connected = Gtk.Image(stock=Gtk.STOCK_YES)
        self.tb.iconnected.set_visible_horizontal(False)
        self.tb.iconnected.set_visible_vertical(False)
        self.tb.img_connected.set_tooltip_text("Connection Status: Connected")
        self.tb.idisconnected = Gtk.ToolItem()
        self.tb.img_disconnected = Gtk.Image(stock=Gtk.STOCK_NO)
        self.tb.img_disconnected.set_tooltip_text(
            "Connection Status: Disconnected")
        self.tb.iconnected.add(self.tb.img_connected)
        self.tb.idisconnected.add(self.tb.img_disconnected)
        self.tb.toolbar.add(self.tb.iconnected)
        self.tb.toolbar.add(self.tb.idisconnected)
        self.tb.toolbar.add(self.tb.bconnect)
        self.tb.toolbar.add(self.tb.bdisconnect)
        self.tb.toolbar.add(self.tb.bauto_scroll)
        self.tb.toolbar.add(self.tb.bscroll_down)
    def make_child_test(self):
        box_test = Gtk.FlowBox()
        for i in range(0,10):
            checkbutton = Gtk.CheckButton("Click me!")
            box_test.add(checkbutton)
        return box_test
    def make_child_label(self):
        grid = Gtk.Grid()
        label = Gtk.Label()
        label.set_markup("<big>A fancy label</big>")
        grid.add(label)
        return grid
    def make_client(self):
        client = digilib.network.Client(
            host=self.host,
            port=self.port,
            af_family=self.af_family,
            handle_data_func=self.child_console.add_msg_threadsafe,
        )
        return client
    def get_client(self):
        return self.client
    def quit(self,*args):
        lgui.debug("quit")
        if self.client:
            self.client.stop()
            # if self.client.is_connected:
        Gtk.main_quit()
    def start(self):
        self.css_provider = Gtk.CssProvider()
        self.css_provider.load_from_path("config/style.css")
        screen = Gdk.Screen.get_default()
        self.style_context = Gtk.StyleContext()
        self.style_context.add_provider_for_screen(
            screen,
            self.css_provider,
            Gtk.STYLE_PROVIDER_PRIORITY_USER,
        )
        self.show_all()
        self.stack.set_visible_child(self.child_console)
        Gdk.threads_init()
        Gtk.main()
    def on_connect_request(self,widget):
        try:
            lgui.debug("connect request")
            if self.client == None:
                self.client = self.make_client()
            if not self.client.is_running():
                self.client.start()
            if not self.client.is_connected:
                if self.client.connect():
                    self.tb.iconnected.set_visible_horizontal(True)
                    self.tb.iconnected.set_visible_vertical(True)
                    self.tb.idisconnected.set_visible_horizontal(False)
                    self.tb.idisconnected.set_visible_vertical(False)
                    lgui.debug("client started")
                else:
                    lgui.debug(
                        "client failed to connect, maybe it is connected")
        except Exception as e:
            lgui.error("error trying to connect",exc_info=e)
    def on_disconnect_request(self,widget):
        try:
            lgui.debug("disconnect request")
            if self.client != None:
                if self.client.is_connected:
                    self.client.disconnect()
                    self.tb.iconnected.set_visible_horizontal(False)
                    self.tb.iconnected.set_visible_vertical(False)
                    self.tb.idisconnected.set_visible_horizontal(True)
                    self.tb.idisconnected.set_visible_vertical(True)
                    lgui.debug("client disconnected")
                    return
            lgui.debug(
                "client failed to disconnect, maybe it wasn't connected")
        except Exception as e:
            lgui.error("error trying to disconnect",exc_info=e)
    def on_scroll_down_request(self,widget):
        self.child_console.scroll_down()
    def on_toggle_scroll_request(self,widget):
        self.child_console.scroll = not self.child_console.scroll
    def on_exit_button_press(self,*args):
        self.destroy()
        Gtk.main_quit()
        return True