text: # -*- coding: UTF-8 -*-
  
  from gi.repository import Gtk
  
  from pychess.Utils.const import EMPTY, FEN_EMPTY, FEN_START
  from pychess.Utils.Board import Board
  from pychess.Utils.Cord import Cord
  from pychess.widgets.BoardControl import BoardControl
  from pychess.Savers.ChessFile import LoadingError
  from pychess.System.prefix import addDataPrefix
  from pychess.widgets import mainwindow
  
  __title__ = _("Preview")
  
  __icon__ = addDataPrefix("glade/panel_games.svg")
  
  __desc__ = _("Preview panel can filter game list by current game moves")
  
  
  class PreviewPanel:
      def __init__(self, persp):
          self.persp = persp
          self.filtered = False
  
          self.box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
  
          # buttons
          toolbar = Gtk.Toolbar()
  
          firstButton = Gtk.ToolButton(stock_id=Gtk.STOCK_MEDIA_PREVIOUS)
          toolbar.insert(firstButton, -1)
  
          prevButton = Gtk.ToolButton(stock_id=Gtk.STOCK_MEDIA_REWIND)
          toolbar.insert(prevButton, -1)
  
          nextButton = Gtk.ToolButton(stock_id=Gtk.STOCK_MEDIA_FORWARD)
          toolbar.insert(nextButton, -1)
  
          lastButton = Gtk.ToolButton(stock_id=Gtk.STOCK_MEDIA_NEXT)
          toolbar.insert(lastButton, -1)
  
          self.filterButton = Gtk.ToggleToolButton(Gtk.STOCK_FIND)
          self.filterButton.set_tooltip_text(_("Filter game list by current game moves"))
          toolbar.insert(self.filterButton, -1)
  
          addButton = Gtk.ToolButton(stock_id=Gtk.STOCK_ADD)
          addButton.set_tooltip_text(_("Add sub-fen filter from position/circles"))
          toolbar.insert(addButton, -1)
  
          firstButton.connect("clicked", self.on_first_clicked)
          prevButton.connect("clicked", self.on_prev_clicked)
          nextButton.connect("clicked", self.on_next_clicked)
          lastButton.connect("clicked", self.on_last_clicked)
  
          addButton.connect("clicked", self.on_add_clicked)
          self.filterButton.connect("clicked", self.on_filter_clicked)
  
          tool_box = Gtk.Box()
          tool_box.pack_start(toolbar, False, False, 0)
  
          # board
          self.gamemodel = self.persp.gamelist.gamemodel
          self.boardcontrol = BoardControl(self.gamemodel, {}, game_preview=True)
          self.boardview = self.boardcontrol.view
          self.board = self.gamemodel.boards[self.boardview.shown].board
          self.boardview.set_size_request(170, 170)
  
          self.boardview.got_started = True
          self.boardview.auto_update_shown = False
  
          self.box.pack_start(self.boardcontrol, True, True, 0)
          self.box.pack_start(tool_box, False, True, 0)
          self.box.show_all()
  
          selection = self.persp.gamelist.get_selection()
          self.conid = selection.connect_after("changed", self.on_selection_changed)
          self.persp.gamelist.preview_cid = self.conid
  
          # force first game to show
          self.persp.gamelist.set_cursor(0)
  
      def on_selection_changed(self, selection):
          model, iter = selection.get_selected()
          if iter is None:
              self.gamemodel.boards = [Board(FEN_EMPTY)]
              del self.gamemodel.moves[:]
              self.boardview.shown = 0
              self.boardview.redrawCanvas()
              return
  
          path = self.persp.gamelist.get_model().get_path(iter)
  
          rec, ply = self.persp.gamelist.get_record(path)
          if rec is None:
              return
  
          try:
              self.persp.chessfile.loadToModel(rec, -1, self.gamemodel)
          except LoadingError as err:
              dialogue = Gtk.MessageDialog(
                  mainwindow(),
                  type=Gtk.MessageType.WARNING,
                  buttons=Gtk.ButtonsType.OK,
                  message_format=err.args[0],
              )
              if len(err.args) > 1:
                  dialogue.format_secondary_text(err.args[1])
              dialogue.connect("response", lambda dialogue, a: dialogue.hide())
              dialogue.show()
          self.boardview.noAnimation = True
          self.boardview.lastMove = None
          self.boardview._shown = self.gamemodel.lowply
  
          if ply > 0 or self.persp.gamelist.ply > 0:
              self.boardview.shown = ply if ply > 0 else self.persp.gamelist.ply
          else:
              self.boardview.shown = self.boardview.model.ply
  
      def on_first_clicked(self, button):
          self.boardview.showFirst()
          if self.filtered:
              self.update_gamelist()
  
      def on_prev_clicked(self, button):
          self.boardview.showPrev()
          if self.filtered:
              self.update_gamelist()
  
      def on_next_clicked(self, button):
          self.boardview.showNext()
          if self.filtered:
              self.update_gamelist()
  
      def on_last_clicked(self, button):
          self.boardview.showLast()
          if self.filtered:
              self.update_gamelist()
  
      def on_filter_clicked(self, button):
          self.filtered = button.get_active()
          if not self.filtered:
              self.persp.filter_panel.filterButton.set_sensitive(True)
              self.boardview.showFirst()
              self.filtered = True
              self.update_gamelist()
              self.filtered = False
          else:
              self.persp.filter_panel.filterButton.set_sensitive(False)
              self.update_gamelist()
  
      def on_add_clicked(self, button):
          """ Create sub-fen from current FEN removing pieces not marked with circles """
  
          self.board = self.gamemodel.boards[self.boardview.shown].board
          board = self.board.clone()
          fen = board.asFen()
  
          for cord in range(64):
              kord = Cord(cord)
              if kord not in self.boardview.circles:
                  board.arBoard[cord] = EMPTY
  
          sub_fen = board.asFen().split()[0]
  
          # If all pieces removed (no circles at all) use the original FEN
          if sub_fen == "8/8/8/8/8/8/8/8":
              if fen == FEN_START:
                  return
              else:
                  sub_fen = fen.split()[0]
  
          self.persp.filter_panel.add_sub_fen(sub_fen)
  
      def update_gamelist(self):
          if not self.filtered:
              return
  
          self.board = self.gamemodel.boards[self.boardview.shown].board
  
          self.persp.gamelist.ply = self.board.plyCount
          self.persp.chessfile.set_fen_filter(self.board.asFen())
          self.persp.gamelist.load_games()
  