# Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018  Rickard Lindberg, Roger Lindberg
#
# This file is part of Timeline.
#
# Timeline 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.
#
# Timeline 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 Timeline.  If not, see <http://www.gnu.org/licenses/>.

import wx
import timelinelib.wxgui.frames.mainframe.menus as mid
from timelinelib.wxgui.frames.mainframe.menus.menubase import MenuBase
from timelinelib.plugin.factory import EVENTBOX_DRAWER
from timelinelib.plugin import factory
from timelinelib.proxies.drawingarea import DrawingAreaProxy
from timelinelib.wxgui.dialogs.slideshow.view import open_slideshow_dialog
from timelinelib.config.menuiteminfo import MenuItemInfo
from timelinelib.config.shortcut import CTRL_MODIFIER, LABEL_VIEW, ALT_MODIFIER


REQUIRING_TIMELINE = (mid.ID_LEGEND, mid.ID_BALLOONS, mid.ID_ZOOMIN, mid.ID_ZOOMOUT, mid.ID_VERT_ZOOMIN,
                      mid.ID_VERT_ZOOMOUT, mid.ID_PRESENTATION)
REQUIRING_VISIBLE_TIMELINE_VIEW = (mid.ID_SIDEBAR,)
MENU_LABELS = {
    mid.ID_TOOLBAR: _("Toolbar"),
    mid.ID_SIDEBAR: _("&Sidebar"),
    mid.ID_LEGEND: _("&Legend"),
    mid.ID_LABEL_FILTERING: _("La&bel Filtering"),
    mid.ID_BALLOONS: _("&Balloons on hover"),
    mid.ID_ZOOMIN: _("Zoom &In"),
    mid.ID_ZOOMOUT: _("Zoom &Out"),
    mid.ID_VERT_ZOOMIN: _("Vertical Zoom &In"),
    mid.ID_VERT_ZOOMOUT: _("Vertical Zoom &Out"),
    mid.ID_LEFT_ALIGNMENT: _("Left"),
    mid.ID_CENTER_ALIGNMENT: _("Center"),
    mid.ID_PRESENTATION: _("Start slide show") + "...",
    mid.ID_HIDE_DONE: _("&Hide Events done"),
}


class ViewMenu(MenuBase):
    """The View menu (a wx.Menu)."""

    def __init__(self, main_frame):
        MenuBase.__init__(self, main_frame, REQUIRING_TIMELINE, REQUIRING_VISIBLE_TIMELINE_VIEW)
        self._menu_items_info = self._create_menu_items_info(main_frame)
        self._create_menu()
        self._bind_event_handlers()
        self._register_shortcuts()
        self._register_menus_requiring_timeline()
        self._check_view_menu_items()

    def _create_menu_items_info(self, main_frame):
        return [
            MenuItemInfo(wxid=mid.ID_TOOLBAR,
                         event_handler=lambda evt: main_frame.config.set('show_toolbar', evt.IsChecked()),
                         config_key="shortcut_toolbar",
                         config_display_name=LABEL_VIEW % MENU_LABELS[mid.ID_TOOLBAR],
                         shortcut_key="T",
                         shortcut_modifier=CTRL_MODIFIER,
                         sort_order=1),
            MenuItemInfo(wxid=mid.ID_SIDEBAR,
                         event_handler=lambda evt: main_frame.config.set('show_sidebar', evt.IsChecked()),
                         config_key="shortcut_sidebar",
                         config_display_name=LABEL_VIEW % MENU_LABELS[mid.ID_SIDEBAR],
                         shortcut_key="I",
                         shortcut_modifier=CTRL_MODIFIER,
                         sort_order=2),
            MenuItemInfo(wxid=mid.ID_LEGEND,
                         event_handler=lambda evt: main_frame.config.set('show_legend', evt.IsChecked()),
                         config_key="shortcut_legend",
                         config_display_name=LABEL_VIEW % MENU_LABELS[mid.ID_LEGEND],
                         sort_order=3),
            MenuItemInfo(wxid=mid.ID_LABEL_FILTERING,
                         event_handler=lambda evt: main_frame.config.set('show_label_filtering', evt.IsChecked()),
                         config_key="shortcut_label_filtering",
                         config_display_name=LABEL_VIEW % MENU_LABELS[mid.ID_LABEL_FILTERING],
                         sort_order=4),
            MenuItemInfo(wxid=mid.ID_BALLOONS,
                         event_handler=lambda evt: main_frame.config.set('balloon_on_hover', evt.IsChecked()),
                         config_key="shortcut_ballons",
                         config_display_name=LABEL_VIEW % MENU_LABELS[mid.ID_BALLOONS],
                         sort_order=5),
            MenuItemInfo(wxid=mid.ID_ZOOMIN,
                         event_handler=lambda evt: DrawingAreaProxy(main_frame).zoom_in(),
                         config_key="shortcut_zoomin",
                         config_display_name=LABEL_VIEW % MENU_LABELS[mid.ID_ZOOMIN],
                         shortcut_key="+",
                         shortcut_modifier=CTRL_MODIFIER,
                         sort_order=6),
            MenuItemInfo(wxid=mid.ID_ZOOMOUT,
                         event_handler=lambda evt: DrawingAreaProxy(main_frame).zoom_out(),
                         config_key="shortcut_zoomout",
                         config_display_name=LABEL_VIEW % MENU_LABELS[mid.ID_ZOOMOUT],
                         shortcut_key="-",
                         shortcut_modifier=CTRL_MODIFIER,
                         sort_order=7),
            MenuItemInfo(wxid=mid.ID_VERT_ZOOMIN,
                         event_handler=lambda evt: DrawingAreaProxy(main_frame).vertical_zoom_in(),
                         config_key="shortcut_vertical_zoomin",
                         config_display_name=LABEL_VIEW % MENU_LABELS[mid.ID_VERT_ZOOMIN],
                         shortcut_key="+",
                         shortcut_modifier=ALT_MODIFIER,
                         sort_order=8),
            MenuItemInfo(wxid=mid.ID_VERT_ZOOMOUT,
                         event_handler=lambda evt: DrawingAreaProxy(main_frame).vertical_zoom_out(),
                         config_key="shortcut_vertical_zoomout",
                         config_display_name=LABEL_VIEW % MENU_LABELS[mid.ID_VERT_ZOOMOUT],
                         shortcut_key="-",
                         shortcut_modifier=ALT_MODIFIER,
                         sort_order=9),
            MenuItemInfo(wxid=mid.ID_LEFT_ALIGNMENT,
                         event_handler=lambda evt: main_frame.config.set('draw_point_events_to_right', True),
                         config_key="shortcut_event_text_left_alignment",
                         config_display_name=LABEL_VIEW % MENU_LABELS[mid.ID_LEFT_ALIGNMENT],
                         sort_order=20),
            MenuItemInfo(wxid=mid.ID_CENTER_ALIGNMENT,
                         event_handler=lambda evt: main_frame.config.set('draw_point_events_to_right', False),
                         config_key="shortcut_event_text_center_alignment",
                         config_display_name=LABEL_VIEW % MENU_LABELS[mid.ID_CENTER_ALIGNMENT],
                         sort_order=21),
            MenuItemInfo(wxid=mid.ID_EVENTBOX_DRAWER_PLAIN,
                         config_key="shortcut_eventbox_drawer_plain",
                         sort_order=30),
            MenuItemInfo(wxid=mid.ID_EVENTBOX_DRAWER_GRADIENT_VERTICAL,
                         config_key="shortcut_eventbox_drawer_gradient_vertical",
                         sort_order=31),
            MenuItemInfo(wxid=mid.ID_EVENTBOX_DRAWER_GRADIENT_HORIZONTAL,
                         config_key="shortcut_eventbox_drawer_gradient_horizontal",
                         sort_order=32),
            MenuItemInfo(wxid=mid.ID_EVENTBOX_DRAWER_GRADIENT_HORIZONTAL_ALT,
                         config_key="shortcut_eventbox_drawer_gradient_horizontal_alt",
                         sort_order=33),
            MenuItemInfo(wxid=mid.ID_PRESENTATION,
                         event_handler=lambda evt: self._start_slide_show(main_frame),
                         config_key="shortcut_slideshow",
                         config_display_name=LABEL_VIEW % MENU_LABELS[mid.ID_PRESENTATION],
                         sort_order=40),
            MenuItemInfo(wxid=mid.ID_HIDE_DONE,
                         event_handler=lambda evt: main_frame.config.set('hide_events_done', evt.IsChecked()),
                         config_key="shortcut_hide_done",
                         config_display_name=LABEL_VIEW % MENU_LABELS[mid.ID_HIDE_DONE],
                         sort_order=41),
        ]

    def _create_menu(self):
        self._append_menu_item(mid.ID_TOOLBAR, kind=wx.ITEM_CHECK)
        self._append_menu_item(mid.ID_SIDEBAR, kind=wx.ITEM_CHECK)
        self._append_menu_item(mid.ID_LEGEND, kind=wx.ITEM_CHECK)
        self._append_menu_item(mid.ID_LABEL_FILTERING, kind=wx.ITEM_CHECK)
        self.AppendSeparator()
        self._append_menu_item(mid.ID_BALLOONS, kind=wx.ITEM_CHECK)
        self.AppendSeparator()
        self._append_menu_item(mid.ID_ZOOMIN)
        self._append_menu_item(mid.ID_ZOOMOUT)
        self._append_menu_item(mid.ID_VERT_ZOOMIN)
        self._append_menu_item(mid.ID_VERT_ZOOMOUT)
        self.AppendSeparator()
        point_even_alignmentsub_menu = wx.Menu()
        point_even_alignmentsub_menu.Append(mid.ID_LEFT_ALIGNMENT, MENU_LABELS[mid.ID_LEFT_ALIGNMENT], kind=wx.ITEM_RADIO)
        point_even_alignmentsub_menu.Append(mid.ID_CENTER_ALIGNMENT, MENU_LABELS[mid.ID_CENTER_ALIGNMENT], kind=wx.ITEM_RADIO)
        self.Append(wx.ID_ANY, _("Point event alignment"), point_even_alignmentsub_menu)
        self.AppendSeparator()
        self.Append(wx.ID_ANY, _("Event appearance"), self._create_event_box_drawers_submenu())
        self.AppendSeparator()
        self.Append(mid.ID_PRESENTATION, MENU_LABELS[mid.ID_PRESENTATION] + "...")
        self.AppendSeparator()
        self.Append(mid.ID_HIDE_DONE, MENU_LABELS[mid.ID_HIDE_DONE], kind=wx.ITEM_CHECK)

    def _check_view_menu_items(self):
        self.FindItemById(mid.ID_TOOLBAR).Check(self._main_frame.config.show_toolbar)
        self.FindItemById(mid.ID_SIDEBAR).Check(self._main_frame.config.show_sidebar)
        self.FindItemById(mid.ID_LEGEND).Check(self._main_frame.config.show_legend)
        self.FindItemById(mid.ID_LABEL_FILTERING).Check(self._main_frame.config.show_label_filtering)
        self.FindItemById(mid.ID_BALLOONS).Check(self._main_frame.config.balloon_on_hover)
        self.FindItemById(mid.ID_HIDE_DONE).Check(self._main_frame.config.hide_events_done)
        self.FindItemById(mid.ID_LEFT_ALIGNMENT).Check(self._main_frame.config.draw_point_events_to_right)
        self.FindItemById(mid.ID_CENTER_ALIGNMENT).Check(not self._main_frame.config.draw_point_events_to_right)

    def _create_event_box_drawers_submenu(self):
        submenu = wx.Menu()
        for plugin in factory.get_plugins(EVENTBOX_DRAWER):
            self._create_submenu(plugin, submenu)
        return submenu

    def _create_submenu(self, plugin, submenu):
        wxid = plugin.wxid()
        submenu.Append(wxid, plugin.display_name(), plugin.display_name(), kind=wx.ITEM_RADIO)
        self._main_frame.menu_controller.add_menu_requiring_timeline(submenu.FindItemById(wxid))
        if plugin.display_name() == self._main_frame.config.get_selected_event_box_drawer():
            submenu.FindItemById(wxid).Check()
        menu_item_info = self.get_menu_item_info(wxid)
        menu_item_info.event_handler = self._plugin_handler(plugin)
        menu_item_info.config_display_name = LABEL_VIEW % plugin.display_name()

    def _plugin_handler(self, plugin):
        def event_handler(evt):
            self._main_frame.canvas.SetEventBoxDrawer(plugin.run())
            self._main_frame.config.set_selected_event_box_drawer(plugin.display_name())
        return event_handler

    def _start_slide_show(self, main_frame):
        open_slideshow_dialog(main_frame.timeline, main_frame.canvas)

    def _append_menu_item(self, wxid, kind=None):
        if kind:
            self.Append(wxid, MENU_LABELS[wxid], kind=kind)
        else:
            self.Append(wxid, MENU_LABELS[wxid])
