#!/usr/bin/env python2
# Terminator by Chris Jones <cmsj@tenshu.net>
# GPL v2 only
"""window.py - class for the main Terminator window"""
import copy
import time
import uuid
import gi
from gi.repository import GObject
from gi.repository import Gtk, Gdk, GdkX11
from util import dbg, err, make_uuid, display_manager
import util
from translation import _
from version import APP_NAME
from container import Container
from factory import Factory
from terminator import Terminator
if display_manager() == 'X11':
    try:
        gi.require_version('Keybinder', '3.0')
        from gi.repository import Keybinder
        Keybinder.init()
    except (ImportError, ValueError):
        err('Unable to load Keybinder module. This means the \
hide_window shortcut will be unavailable')
# pylint: disable-msg=R0904
class Window(Container, Gtk.Window):
    """Class implementing a top-level Terminator window"""
    terminator = None
    title = None
    isfullscreen = None
    ismaximised = None
    hidebound = None
    hidefunc = None
    losefocus_time = 0
    position = None
    ignore_startup_show = None
    set_pos_by_ratio = None
    last_active_term = None
    zoom_data = None
    term_zoomed = False
    __gproperties__ = {
            'term_zoomed': (GObject.TYPE_BOOLEAN,
                            'terminal zoomed',
                            'whether the terminal is zoomed',
                            False,
                            GObject.PARAM_READWRITE)
    }
    def __init__(self):
        """Class initialiser"""
        self.terminator = Terminator()
        self.terminator.register_window(self)
        Container.__init__(self)
        GObject.GObject.__init__(self)
        GObject.type_register(Window)
        self.register_signals(Window)
        self.get_style_context().add_class("terminator-terminal-window")
#        self.set_property('allow-shrink', True)  # FIXME FOR GTK3, or do we need this actually?
        icon_to_apply=''
        self.register_callbacks()
        self.apply_config()
        self.title = WindowTitle(self)
        self.title.update()
        options = self.config.options_get()
        if options:
            if options.forcedtitle:
                self.title.force_title(options.forcedtitle)
            if options.role:
                self.set_role(options.role)
            
#            if options.classname is not None:
#                self.set_wmclass(options.classname, self.wmclass_class)
            
            if options.forcedicon is not None:
                icon_to_apply = options.forcedicon
            if options.geometry:
                if not self.parse_geometry(options.geometry):
                    err('Window::__init__: Unable to parse geometry: %s' % 
                            options.geometry)
        self.apply_icon(icon_to_apply)
        self.pending_set_rough_geometry_hint = False
    def do_get_property(self, prop):
        """Handle gobject getting a property"""
        if prop.name in ['term_zoomed', 'term-zoomed']:
            return(self.term_zoomed)
        else:
            raise AttributeError('unknown property %s' % prop.name)
    def do_set_property(self, prop, value):
        """Handle gobject setting a property"""
        if prop.name in ['term_zoomed', 'term-zoomed']:
            self.term_zoomed = value
        else:
            raise AttributeError('unknown property %s' % prop.name)
    def register_callbacks(self):
        """Connect the GTK+ signals we care about"""
        self.connect('key-press-event', self.on_key_press)
        self.connect('button-press-event', self.on_button_press)
        self.connect('delete_event', self.on_delete_event)
        self.connect('destroy', self.on_destroy_event)
        self.connect('window-state-event', self.on_window_state_changed)
        self.connect('focus-out-event', self.on_focus_out)
        self.connect('focus-in-event', self.on_focus_in)
        # Attempt to grab a global hotkey for hiding the window.
        # If we fail, we'll never hide the window, iconifying instead.
        if self.config['keybindings']['hide_window'] != None:
            if display_manager() == 'X11':
                try:
                    self.hidebound = Keybinder.bind(
                        self.config['keybindings']['hide_window'].replace('<Shift>',''),
                        self.on_hide_window)
                except (KeyError, NameError):
                    pass
                if not self.hidebound:
                    err('Unable to bind hide_window key, another instance/window has it.')
                    self.hidefunc = self.iconify
                else:
                    self.hidefunc = self.hide
    def apply_config(self):
        """Apply various configuration options"""
        options = self.config.options_get()
        maximise = self.config['window_state'] == 'maximise'
        fullscreen = self.config['window_state'] == 'fullscreen'
        hidden = self.config['window_state'] == 'hidden'
        borderless = self.config['borderless']
        skiptaskbar = self.config['hide_from_taskbar']
        alwaysontop = self.config['always_on_top']
        sticky = self.config['sticky']
        if options:
            if options.maximise:
                maximise = True
            if options.fullscreen:
                fullscreen = True
            if options.hidden:
                hidden = True
            if options.borderless:
                borderless = True
        self.set_fullscreen(fullscreen)
        self.set_maximised(maximise)
        self.set_borderless(borderless)
        self.set_always_on_top(alwaysontop)
        self.set_real_transparency()
        self.set_sticky(sticky)
        if self.hidebound:
            self.set_hidden(hidden)
            self.set_skip_taskbar_hint(skiptaskbar)
        else:
            self.set_iconified(hidden)
    def apply_icon(self, requested_icon):
        """Set the window icon"""
        icon_theme = Gtk.IconTheme.get_default()
        icon_name_list = [APP_NAME]   # disable self.wmclass_name, n/a in GTK3
        if requested_icon:
            try:
                self.set_icon_from_file(requested_icon)
                return
            except (NameError, GObject.GError):
                dbg('Unable to load %s icon as file' % (repr(requested_icon)))
            icon_name_list.insert(0, requested_icon)
        for icon_name in icon_name_list:
            # Test if the icon is available first
            if icon_theme.lookup_icon(icon_name, 48, 0):
                self.set_icon_name(icon_name)
                return # Success! We're done.
            else:
                dbg('Unable to load %s icon' % (icon_name))
        icon = self.render_icon(Gtk.STOCK_DIALOG_INFO, Gtk.IconSize.BUTTON)
        self.set_icon(icon)
    def on_key_press(self, window, event):
        """Handle a keyboard event"""
        maker = Factory()
        self.set_urgency_hint(False)
        mapping = self.terminator.keybindings.lookup(event)
        if mapping:
            dbg('Window::on_key_press: looked up %r' % mapping)
            if mapping == 'full_screen':
                self.set_fullscreen(not self.isfullscreen)
            elif mapping == 'close_window':
                if not self.on_delete_event(window,
                        Gdk.Event.new(Gdk.EventType.DELETE)):
                    self.on_destroy_event(window,
                            Gdk.Event.new(Gdk.EventType.DESTROY))
            else:
                return(False)
            return(True)
    def on_button_press(self, window, event):
        """Handle a mouse button event. Mainly this is just a clean way to
        cancel any urgency hints that are set."""
        self.set_urgency_hint(False)
        return(False)
    def on_focus_out(self, window, event):
        """Focus has left the window"""
        for terminal in self.get_visible_terminals():
            terminal.on_window_focus_out()
        self.losefocus_time = time.time()
        if self.config['hide_on_lose_focus'] and self.get_property('visible'):
            self.position = self.get_position()
            self.hidefunc()
    def on_focus_in(self, window, event):
        """Focus has entered the window"""
        self.set_urgency_hint(False)
        if not self.terminator.doing_layout:
            self.terminator.last_active_window = self.uuid
        # FIXME: Cause the terminal titlebars to update here
    def is_child_notebook(self):
        """Returns True if this Window's child is a Notebook"""
        maker = Factory()
        return(maker.isinstance(self.get_child(), 'Notebook'))
    def tab_new(self, widget=None, debugtab=False, _param1=None, _param2=None):
        """Make a new tab"""
        cwd = None
        profile = None
        if self.get_property('term_zoomed') == True:
            err("You can't create a tab while a terminal is maximised/zoomed")
            return
        if widget:
            cwd = widget.get_cwd()
            profile = widget.get_profile()
        maker = Factory()


Answer:         if not self.is_child_notebook():