# -*- coding: utf-8 -*-

# Copyright (C) 2010-2011
#   Drakmail < drakmail@gmail.com >
#   NomerUNO < uno.kms@gmail.com >
#   Platon Peacel☮ve <platonny@ngs.ru>
#   Elec.Lomy.RU <Elec.Lomy.RU@gmail.com>
#   ADcomp <david.madbox@gmail.com>
#
# This program 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.

# 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 General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import gtk
import sys

try:
    from config import ConfigController
    import snapfly_core
    import ui
    from version import Application
    from launcher import launch_command
except ImportError:
    sys.stderr.write("Can't import snapfly menu modules.\nExiting\n")
    import traceback
    traceback.print_exc(sys.stderr)
    sys.exit(1)


class Menu:
    def create_about(self, widget):
        about = gtk.AboutDialog()
        about.set_program_name(Application.name_full)
        about.set_version(Application.version)
        about.set_website(Application.website)
        about.set_authors(["Drakmail", "NomerUNO", "Pythonist", "Πλάτων"])
        about.set_comments(snapfly_core._("Lightweight, DE-independent PyGTK menu"))
        about.set_logo_icon_name(Application.name)
        about.run()
        about.destroy()

    def __init__(self, notifier, INOTIFY_SUPPORT):
        self.window = None
        self.len = 0
        self.nbook = None
        self.makemenu = None
        self.hide_me = False
        self.updating = False
        self.focus_check = False
        self.mode = None
        config = ConfigController()
        self.terminal = config.getValue('terminal')
        self.systray = config.getValue('systray')
        self.rounded = int(config.getValue('rounded'))
        self.menu_width = int(config.getValue('menu_width'))
        self.bg_color = config.getValue('bg_color')
        self.border_color = config.getValue('border_color')
        self.hideList = config.getValue('hide_list').split(',')
        self.showFavs = config.getValue('favorites')
        self.mouse_at_scroll = False
        self.notifier = notifier
        self.INOTIFY_SUPPORT = INOTIFY_SUPPORT
        self.tab_width = None
        if config.getValue('category_click') == 'false':
            self.category_click = False
        else:
            self.category_click = True

        if self.systray == "true":
            self.statusIcon = gtk.StatusIcon()
            self.statusIcon.set_from_icon_name(Application.name)
            self.statusIcon.set_visible(True)
            self.statusIcon.set_tooltip(Application.name_full)
            self.statusIcon.connect('popup-menu', self.status_icon_popup)
            self.statusIcon.connect('activate', self.toggle_hide)
            # context menu create
            self.popupMenu = gtk.Menu()
            # Add Exit String
            exit_item = gtk.ImageMenuItem (gtk.STOCK_QUIT)
            exit_item.connect("activate", self.doQuit)
            # Add About String
            about_item = gtk.ImageMenuItem (gtk.STOCK_ABOUT)
            about_item.connect("activate", self.create_about)
            self.popupMenu.add(about_item)
            self.popupMenu.add(exit_item)
            self.popupMenu.show_all()

        self.create_window()
        self.toggle_hide()

    def doQuit(self, widget=None, data=None):
        gtk.main_quit()

    def run(self):
        gtk.main()

    def update_menu(self):
        if not self.updating:
            self.updating = True
            tmpBook = gtk.Notebook()
            tmpBook.set_tab_pos(gtk.POS_LEFT)
            tmpBook.set_border_width(0)
            self.len = self.makemenu.make(tmpBook)
            tmpBook.show()
            self.window.remove(self.nbook)
            self.window.add(tmpBook)
            self.nbook.destroy()
            self.nbook = tmpBook
            self.updating = False

    def create_window(self):
        bg_color_rgb = snapfly_core.hex2rgb(self.bg_color)
        border_color_rgb = snapfly_core.hex2rgb(self.border_color)
        self.window = ui.PopupWindow(bg_color_rgb, border_color_rgb, self.rounded)
        self.window.add_events(gtk.gdk.FOCUS_CHANGE_MASK)
        if not self.category_click:
            self.window.connect("motion_notify_event", self.motion_notify_event)
        self.window.connect("focus-out-event", self.lost_focus)
        self.window.connect("key-press-event", self.onkeypress)
        self.window.connect("destroy", self.destroy)
        self.window.set_size_request(self.menu_width,-1)

        self.nbook = gtk.Notebook()
        self.nbook.show()
        self.nbook.set_tab_pos(gtk.POS_LEFT)
        self.nbook.set_border_width(0)
        self.window.add(self.nbook)
        self.window.show_all()
        self.makemenu = snapfly_core.MakeMenu(self.ExecuteAction,
                                self.move_on_scroll_event, self.terminal,
                                self.hideList, self.showFavs)
        self.len = self.makemenu.make(self.nbook)

    def ExecuteAction(self, widget, event, cmd):
        self.focus_check = False
        launch_command(cmd)
        self.toggle_hide(widget)

    def toggle_hide(self, widget=None, event=None):
        if self.hide_me:
            self.hide_me = False
            self.show_menu(self.mode)
            self.window.show()
            self.window.present()
            self.focus_check = True
        else:
            self.hide_me = True
            self.focus_check = False
            self.window.hide()

    def show_menu(self, mode=None):
        screen_width, screen_height = gtk.gdk.screen_width(), gtk.gdk.screen_height()

        if not mode:
            rect = self.statusIcon.get_geometry()[1]
            y = rect[1]+rect[3]
            if rect[0] + self.menu_width > screen_width:
                x = screen_width - self.menu_width
            else:
                if not self.tab_width:
                    x = max( 0, rect[0] - self.menu_width/2 )
                    self.window.move(x,y)
                    self.window.present()
                    try:
                        self.tab_width = self.menu_width - self.nbook.get_children(
                        )[0].get_window().get_children()[1].get_size()[1]
                    except:
                        pass
                    else:
                        x = max( 0, rect[0] - self.tab_width)
                        self.window.move(x,y)
                else:
                    x = max( 0, rect[0] - self.tab_width)
            if rect[1] < (screen_height // 2):
                y = rect[1] + rect[3]
                self.window.move(x, y)
            else:
                width, height = self.window.get_size()
                self.window.move(x, gtk.gdk.screen_height() - height)
            self.window.present()
        else:
            rootwin = self.window.get_screen().get_root_window()
            w_width , w_height = self.window.get_size()
            x, y, mods = rootwin.get_pointer()
            if x + self.menu_width > screen_width:
                x = screen_width - self.menu_width
            if y + w_height > screen_height:
                y = screen_height - w_height
            self.window.move(x, y)
            self.window.present()

    def lost_focus(self, widget, event):
        if self.focus_check:
            self.toggle_hide()

    def move_on_scroll_event(self,widget,event):
        self.mouse_at_scroll = True

    def motion_notify_event(self,widget,event):
        if not self.mouse_at_scroll:
            if event.is_hint:
                y = event.window.get_pointer()[1]
            else:
                y = event.y
            self.nbook.set_current_page(int(y // ( self.nbook.get_allocation().height / self.len )))
        self.mouse_at_scroll = False

    def onkeypress(self, widget, event):
        if event.keyval == gtk.keysyms.Escape:
            self.toggle_hide()

    def status_icon_popup(self, widget, button, active_time):
        self.popupMenu.popup(None, None, None, 1, 0)

    def callback_signal(self):
        self.mode = "mouse"
        self.toggle_hide()
        self.mode = None

    def destroy(self):
        if self.INOTIFY_SUPPORT:
            self.notifier.stop()

