from gi.repository import Gtk, GdkPixbuf

from pychess.ic.FICSObjects import FICSChallenge

SEPARATOR, ACCEPT, ASSESS, OBSERVE, FOLLOW, CHAT, CHALLENGE, FINGER, ARCHIVED = range(9)


def cmp(x, y):
    return (x > y) - (x < y)


class ParrentListSection:
    """Parrent for sections mainly consisting of a large treeview"""

    def button_press_event(self, treeview, event):
        if event.button == 3:  # right click
            pathinfo = treeview.get_path_at_pos(int(event.x), int(event.y))
            if pathinfo is not None:
                path, col = pathinfo[0], pathinfo[1]
                treeview.grab_focus()
                treeview.set_cursor(path, col, 0)
                self.menu.show_all()
                self.menu.popup(
                    None, None, None, None, event.button, Gtk.get_current_event_time()
                )
            return True
        return False

    def createLocalMenu(self, items):
        ITEM_MAP = {
            ACCEPT: (_("Accept"), self.on_accept),
            ASSESS: (_("Assess"), self.on_assess),
            OBSERVE: (_("Observe"), self.on_observe),
            FOLLOW: (_("Follow"), self.on_follow),
            CHAT: (_("Chat"), self.on_chat),
            CHALLENGE: (_("Challenge"), self.on_challenge),
            FINGER: (_("Finger"), self.on_finger),
            ARCHIVED: (_("Archived"), self.on_archived),
        }

        self.menu = Gtk.Menu()
        for item in items:
            if item == SEPARATOR:
                menu_item = Gtk.SeparatorMenuItem()
            else:
                label, callback = ITEM_MAP[item]
                menu_item = Gtk.MenuItem(label)
                menu_item.connect("activate", callback)
            self.menu.append(menu_item)
        self.menu.attach_to_widget(self.tv, None)

    def addColumns(self, treeview, *columns, **keyargs):
        if "hide" in keyargs:
            hide = keyargs["hide"]
        else:
            hide = []
        if "pix" in keyargs:
            pix = keyargs["pix"]
        else:
            pix = []
        for i, name in enumerate(columns):
            if i in hide:
                continue
            if i in pix:
                crp = Gtk.CellRendererPixbuf()
                crp.props.xalign = 0.5
                column = Gtk.TreeViewColumn(name, crp, pixbuf=i)
            else:
                crt = Gtk.CellRendererText()
                column = Gtk.TreeViewColumn(name, crt, text=i)
                column.set_resizable(True)
            column.set_sort_column_id(i)
            # prevent columns appear choppy
            column.set_sizing(Gtk.TreeViewColumnSizing.GROW_ONLY)

            column.set_reorderable(True)
            treeview.append_column(column)

    def lowLeftSearchPosFunc(self, tv, search_dialog, user_data):
        alloc = tv.get_allocation()
        window = tv.get_toplevel().get_window()
        x_loc = alloc.x + window.get_position()[0]
        y_loc = alloc.y + window.get_position()[1] + alloc.height
        search_dialog.move(x_loc, y_loc)
        search_dialog.show_all()

    def pixCompareFunction(self, treemodel, iter0, iter1, column):
        pix0 = treemodel.get_value(iter0, column)
        pix1 = treemodel.get_value(iter1, column)
        if isinstance(pix0, GdkPixbuf.Pixbuf) and isinstance(pix1, GdkPixbuf.Pixbuf):
            return cmp(pix0.get_pixels(), pix1.get_pixels())
        return cmp(pix0, pix1)

    def timeCompareFunction(self, treemodel, iter0, iter1, column):
        (minute0, minute1) = (
            treemodel.get_value(iter0, 8),
            treemodel.get_value(iter1, 8),
        )
        return cmp(minute0, minute1)

    def on_accept(self, button):
        model, sel_iter = self.tv.get_selection().get_selected()
        if sel_iter is None:
            return
        sought = model.get_value(sel_iter, 0)
        if isinstance(sought, FICSChallenge):
            self.connection.om.acceptIndex(sought.index)
        else:
            self.connection.om.playIndex(sought.index)

        try:
            message = self.messages[hash(sought)]
        except KeyError:
            pass
        else:
            message.dismiss()
            del self.messages[hash(sought)]

    def on_assess(self, widget):
        model, sel_iter = self.tv.get_selection().get_selected()
        if sel_iter is None:
            return
        sought = model.get_value(sel_iter, 0)
        player1 = self.connection.username
        player2 = sought.player.name
        game_type = sought.game_type.short_fics_name
        self.connection.glm.assess(player1, player2, game_type)
        self.assess_sent = True

    def on_observe(self, widget, *args):
        player = self.getSelectedPlayer()
        if player is not None:
            if player.game is not None:
                self.connection.bm.observe(player.game)
            else:
                self.connection.bm.observe(None, player=player)

    def on_follow(self, widget):
        player = self.getSelectedPlayer()
        if player is not None:
            self.connection.bm.follow(player)

    def on_chat(self, button):
        player = self.getSelectedPlayer()
        if player is None:
            return
        self.lounge.chat.openChatWithPlayer(player.name)
        # TODO: isadmin og type

    def on_challenge(self, widget):
        player = self.getSelectedPlayer()
        if player is not None:
            self.lounge.seek_challenge.onChallengeButtonClicked(widget, player)

    def on_finger(self, widget):
        player = self.getSelectedPlayer()
        if player is not None:
            self.connection.fm.finger(player.name)
            self.lounge.finger_sent = True

    def on_archived(self, widget):
        player = self.getSelectedPlayer()
        if player is not None:
            self.connection.adm.queryAdjournments(player.name)
            self.connection.adm.queryHistory(player.name)
            self.connection.adm.queryJournal(player.name)
