/** Instantiates a new tv show settings panel. */
  public TvShowSettingsPanel() {
    setLayout(
        new FormLayout(
            new ColumnSpec[] {
              FormFactory.RELATED_GAP_COLSPEC,
              ColumnSpec.decode("default:grow"),
              FormFactory.RELATED_GAP_COLSPEC,
              FormFactory.DEFAULT_COLSPEC,
            },
            new RowSpec[] {
              FormFactory.RELATED_GAP_ROWSPEC,
              FormFactory.DEFAULT_ROWSPEC,
              FormFactory.RELATED_GAP_ROWSPEC,
              RowSpec.decode("default:grow"),
            }));

    {
      JPanel panelTvShowDataSources = new JPanel();

      panelTvShowDataSources.setBorder(
          new TitledBorder(
              null,
              BUNDLE.getString("Settings.tvshowdatasource"),
              TitledBorder.LEADING,
              TitledBorder.TOP,
              null,
              null)); //$NON-NLS-1$
      add(panelTvShowDataSources, "2, 2, fill, top");
      panelTvShowDataSources.setLayout(
          new FormLayout(
              new ColumnSpec[] {
                FormFactory.RELATED_GAP_COLSPEC,
                FormFactory.DEFAULT_COLSPEC,
                FormFactory.RELATED_GAP_COLSPEC,
                ColumnSpec.decode("max(40dlu;default)"),
                FormFactory.RELATED_GAP_COLSPEC,
                ColumnSpec.decode("max(44dlu;default):grow"),
                FormFactory.RELATED_GAP_COLSPEC,
                FormFactory.DEFAULT_COLSPEC,
                FormFactory.RELATED_GAP_COLSPEC,
              },
              new RowSpec[] {
                FormFactory.RELATED_GAP_ROWSPEC,
                RowSpec.decode("160px:grow"),
                FormFactory.RELATED_GAP_ROWSPEC,
                FormFactory.DEFAULT_ROWSPEC,
                FormFactory.RELATED_GAP_ROWSPEC,
                FormFactory.DEFAULT_ROWSPEC,
                FormFactory.RELATED_GAP_ROWSPEC,
              }));

      JScrollPane scrollPane = new JScrollPane();
      panelTvShowDataSources.add(scrollPane, "2, 2, 5, 1, fill, fill");

      tableTvShowSources = new JTable();
      tableTvShowSources.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
      scrollPane.setViewportView(tableTvShowSources);

      JPanel panelTvShowSourcesButtons = new JPanel();
      panelTvShowDataSources.add(panelTvShowSourcesButtons, "8, 2, default, top");
      panelTvShowSourcesButtons.setLayout(
          new FormLayout(
              new ColumnSpec[] {
                FormFactory.RELATED_GAP_COLSPEC, FormFactory.DEFAULT_COLSPEC,
              },
              new RowSpec[] {
                FormFactory.DEFAULT_ROWSPEC,
                FormFactory.RELATED_GAP_ROWSPEC,
                FormFactory.DEFAULT_ROWSPEC,
              }));

      JButton btnAdd = new JButton(BUNDLE.getString("Button.add")); // $NON-NLS-1$
      btnAdd.addActionListener(
          new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
              File file =
                  TmmUIHelper.selectDirectory(
                      BUNDLE.getString("Settings.tvshowdatasource.folderchooser")); // $NON-NLS-1$
              if (file != null && file.exists() && file.isDirectory()) {
                settings.getTvShowSettings().addTvShowDataSources(file.getAbsolutePath());
              }
            }
          });

      panelTvShowSourcesButtons.add(btnAdd, "2, 1, fill, top");

      JButton btnRemove = new JButton(BUNDLE.getString("Button.remove")); // $NON-NLS-1$
      btnRemove.addActionListener(
          new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
              int row =
                  tableTvShowSources.convertRowIndexToModel(tableTvShowSources.getSelectedRow());
              if (row != -1) { // nothing selected
                String path = Globals.settings.getTvShowSettings().getTvShowDataSource().get(row);
                String[] choices = {
                  BUNDLE.getString("Button.continue"), BUNDLE.getString("Button.abort")
                }; //$NON-NLS-1$
                int decision =
                    JOptionPane.showOptionDialog(
                        null,
                        String.format(
                            BUNDLE.getString("Settings.tvshowdatasource.remove.info"), path),
                        BUNDLE.getString("Settings.datasource.remove"),
                        JOptionPane.YES_NO_OPTION,
                        JOptionPane.PLAIN_MESSAGE,
                        null,
                        choices,
                        BUNDLE.getString("Button.abort")); // $NON-NLS-1$
                if (decision == 0) {
                  setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
                  Globals.settings.getTvShowSettings().removeTvShowDataSources(path);
                  setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
                }
              }
            }
          });
      panelTvShowSourcesButtons.add(btnRemove, "2, 3, fill, top");

      JLabel lblDvdOrder = new JLabel(BUNDLE.getString("Settings.dvdorder")); // $NON-NLS-1$
      panelTvShowDataSources.add(lblDvdOrder, "2, 4, right, default");

      cbDvdOrder = new JCheckBox("");
      panelTvShowDataSources.add(cbDvdOrder, "4, 4");

      lblImageCache = new JLabel(BUNDLE.getString("Settings.imagecacheimport")); // $NON-NLS-1$
      panelTvShowDataSources.add(lblImageCache, "2, 6, right, default");

      chckbxImageCache = new JCheckBox("");
      panelTvShowDataSources.add(chckbxImageCache, "4, 6");

      lblImageCacheHint =
          new JLabel(BUNDLE.getString("Settings.imagecacheimporthint")); // $NON-NLS-1$
      TmmFontHelper.changeFont(lblImageCacheHint, 0.833);
      panelTvShowDataSources.add(lblImageCacheHint, "6, 6, 3, 1");
    }

    JPanel panel = new JPanel();
    add(panel, "2, 4, fill, fill");
    panel.setLayout(
        new FormLayout(
            new ColumnSpec[] {
              FormFactory.RELATED_GAP_COLSPEC,
              FormFactory.DEFAULT_COLSPEC,
              FormFactory.RELATED_GAP_COLSPEC,
              FormFactory.DEFAULT_COLSPEC,
              FormFactory.RELATED_GAP_COLSPEC,
              FormFactory.DEFAULT_COLSPEC,
              FormFactory.RELATED_GAP_COLSPEC,
            },
            new RowSpec[] {
              FormFactory.RELATED_GAP_ROWSPEC,
              FormFactory.DEFAULT_ROWSPEC,
              FormFactory.RELATED_GAP_ROWSPEC,
            }));

    JLabel lblTraktTv = new JLabel(BUNDLE.getString("Settings.trakt")); // $NON-NLS-1$
    panel.add(lblTraktTv, "2, 2");

    chckbxTraktTv = new JCheckBox("");
    panel.add(chckbxTraktTv, "4, 2");
    btnClearTraktTvShows =
        new JButton(BUNDLE.getString("Settings.trakt.cleartvshows")); // $NON-NLS-1$
    btnClearTraktTvShows.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            int confirm =
                JOptionPane.showOptionDialog(
                    null,
                    BUNDLE.getString("Settings.trakt.cleartvshows.hint"),
                    BUNDLE.getString("Settings.trakt.cleartvshows"),
                    JOptionPane.YES_NO_OPTION,
                    JOptionPane.QUESTION_MESSAGE,
                    null,
                    null,
                    null); //$NON-NLS-1$
            if (confirm == JOptionPane.YES_OPTION) {
              TmmTask task = new ClearTraktTvTask(false, true);
              TmmTaskManager.getInstance().addUnnamedTask(task);
            }
          }
        });
    panel.add(btnClearTraktTvShows, "6, 2");

    initDataBindings();

    // column headings
    tableTvShowSources
        .getColumnModel()
        .getColumn(0)
        .setHeaderValue(BUNDLE.getString("Settings.source")); // $NON-NLS-1$

    if (!Globals.isDonator()) {
      chckbxTraktTv.setSelected(false);
      chckbxTraktTv.setEnabled(false);
      btnClearTraktTvShows.setEnabled(false);
    }
  }
  /**
   * Instantiates a new movie information panel.
   *
   * @param movieSelectionModel the movie selection model
   */
  public MovieInformationPanel(MovieSelectionModel movieSelectionModel) {
    this.movieSelectionModel = movieSelectionModel;

    setLayout(
        new FormLayout(
            new ColumnSpec[] {
              ColumnSpec.decode("450px:grow"),
            },
            new RowSpec[] {
              RowSpec.decode("fill:default:grow"),
            }));

    splitPaneVertical = new JSplitPane();
    splitPaneVertical.setBorder(null);
    splitPaneVertical.setResizeWeight(0.9);
    splitPaneVertical.setContinuousLayout(true);
    splitPaneVertical.setOneTouchExpandable(true);
    splitPaneVertical.setOrientation(JSplitPane.VERTICAL_SPLIT);
    add(splitPaneVertical, "1, 1, fill, fill");

    panelTop = new JPanel();
    panelTop.setBorder(null);
    splitPaneVertical.setTopComponent(panelTop);
    panelTop.setLayout(
        new FormLayout(
            new ColumnSpec[] {
              FormFactory.RELATED_GAP_COLSPEC,
              ColumnSpec.decode("200px:grow"),
              FormFactory.RELATED_GAP_COLSPEC,
              FormFactory.DEFAULT_COLSPEC,
            },
            new RowSpec[] {
              RowSpec.decode("fill:default"), RowSpec.decode("top:pref:grow"),
            }));

    JPanel panelMovieHeader = new JPanel();
    panelTop.add(panelMovieHeader, "2, 1, 3, 1, fill, top");
    panelMovieHeader.setBorder(null);
    panelMovieHeader.setLayout(new BorderLayout(0, 0));

    JPanel panelMovieTitle = new JPanel();
    panelMovieHeader.add(panelMovieTitle, BorderLayout.NORTH);
    panelMovieTitle.setLayout(new BorderLayout(0, 0));
    lblMovieName = new JLabel("");
    TmmFontHelper.changeFont(lblMovieName, 1.33, Font.BOLD);
    panelMovieTitle.add(lblMovieName);

    JPanel panelRatingTagline = new JPanel();
    panelMovieHeader.add(panelRatingTagline, BorderLayout.CENTER);
    panelRatingTagline.setLayout(
        new FormLayout(
            new ColumnSpec[] {
              FormFactory.DEFAULT_COLSPEC,
              FormFactory.DEFAULT_COLSPEC,
              FormFactory.DEFAULT_COLSPEC,
              FormFactory.UNRELATED_GAP_COLSPEC,
              ColumnSpec.decode("25px:grow"),
            },
            new RowSpec[] {
              FormFactory.LINE_GAP_ROWSPEC, RowSpec.decode("24px"), FormFactory.DEFAULT_ROWSPEC,
            }));

    lblRating = new JLabel("");
    panelRatingTagline.add(lblRating, "2, 2, left, center");

    lblVoteCount = new JLabel("");
    panelRatingTagline.add(lblVoteCount, "3, 2, left, center");

    panelRatingStars = new StarRater(10, 1);
    panelRatingTagline.add(panelRatingStars, "1, 2, left, top");
    panelRatingStars.setEnabled(false);

    lblTop250 = new JLabel("");
    panelRatingTagline.add(lblTop250, "5, 2, left, default");

    lblTagline = new JLabel();
    panelRatingTagline.add(lblTagline, "1, 3, 5, 1, default, center");

    panelMovieLogos = new JPanel();
    panelMovieHeader.add(panelMovieLogos, BorderLayout.EAST);

    lblCertificationImage = new JLabel();
    panelMovieLogos.add(lblCertificationImage);

    JLayeredPane layeredPaneImages = new JLayeredPane();
    panelTop.add(layeredPaneImages, "1, 2, 4, 1, fill, fill");
    layeredPaneImages.setLayout(
        new FormLayout(
            new ColumnSpec[] {
              ColumnSpec.decode("max(10px;default)"),
              ColumnSpec.decode("left:120px:grow"),
              ColumnSpec.decode("default:grow(10)"),
            },
            new RowSpec[] {
              RowSpec.decode("max(10px;default)"),
              RowSpec.decode("top:180px:grow"),
              RowSpec.decode("fill:80px:grow(3)"),
            }));

    lblMovieBackground = new ImageLabel(false, true);
    lblMovieBackground.setAlternativeText(BUNDLE.getString("image.notfound.fanart")); // $NON-NLS-1$
    lblMovieBackground.enableLightbox();
    layeredPaneImages.add(lblMovieBackground, "1, 1, 3, 3, fill, fill");

    lblMoviePoster = new ImageLabel();
    lblMoviePoster.setAlternativeText(BUNDLE.getString("image.notfound.poster")); // $NON-NLS-1$
    lblMoviePoster.enableLightbox();
    layeredPaneImages.setLayer(lblMoviePoster, 1);
    layeredPaneImages.add(lblMoviePoster, "2, 2, fill, fill");

    lblWatchedImage = new JLabel();
    lblWatchedImage.setOpaque(false);
    layeredPaneImages.setLayer(lblWatchedImage, 2);
    layeredPaneImages.add(lblWatchedImage, "2, 2, left, top");

    JPanel panelGenres = new MovieGenresPanel(movieSelectionModel);
    layeredPaneImages.setLayer(panelGenres, 2);
    layeredPaneImages.add(panelGenres, "2, 2, 2, 2, right, bottom");

    JPanel panelLogos = new JPanel();
    panelLogos.setOpaque(false);
    layeredPaneImages.setLayer(panelLogos, 2);
    layeredPaneImages.add(panelLogos, "2, 2, 2, 2, right, top");
    panelLogos.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));

    lblMediaLogoResolution = new JLabel("");
    panelLogos.add(lblMediaLogoResolution);

    lblMediaLogoVideoCodec = new JLabel("");
    panelLogos.add(lblMediaLogoVideoCodec);

    lblMediaLogoAudio = new JLabel("");
    panelLogos.add(lblMediaLogoAudio);

    JPanel panelBottom = new JPanel();
    panelBottom.setLayout(
        new FormLayout(
            new ColumnSpec[] {
              ColumnSpec.decode("300px:grow"),
            },
            new RowSpec[] {
              FormFactory.LINE_GAP_ROWSPEC, RowSpec.decode("fill:min:grow"),
            }));

    tabbedPaneMovieDetails = new JTabbedPane(JTabbedPane.TOP);
    panelBottom.add(tabbedPaneMovieDetails, "1, 2, fill, fill");
    splitPaneVertical.setBottomComponent(panelBottom);

    panelDetails = new MovieDetailsPanel(movieSelectionModel);
    tabbedPaneMovieDetails.addTab(
        BUNDLE.getString("metatag.details"), null, panelDetails, null); // $NON-NLS-1$

    panelOverview = new JPanel();
    tabbedPaneMovieDetails.addTab(
        BUNDLE.getString("metatag.plot"), null, panelOverview, null); // $NON-NLS-1$
    panelOverview.setLayout(
        new FormLayout(
            new ColumnSpec[] {
              ColumnSpec.decode("200px:grow"),
            },
            new RowSpec[] {
              FormFactory.LINE_GAP_ROWSPEC, RowSpec.decode("fill:default:grow"),
            }));
    // panelMovieDetails.add(tabbedPaneMovieDetails, "2, 3, fill, fill");

    JScrollPane scrollPaneOverview = new JScrollPane();
    scrollPaneOverview.setBorder(null);
    panelOverview.add(scrollPaneOverview, "1, 2, fill, fill");

    tpOverview = new JTextPane();
    tpOverview.setOpaque(false);
    tpOverview.setEditable(false);
    scrollPaneOverview.setViewportView(tpOverview);

    panelMovieCrew = new MovieCrewPanel(movieSelectionModel);
    tabbedPaneMovieDetails.addTab(
        BUNDLE.getString("metatag.crew"), null, panelMovieCrew, null); // $NON-NLS-1$

    MovieActorPanel panelMovieActors = new MovieActorPanel(movieSelectionModel);
    tabbedPaneMovieDetails.addTab(
        BUNDLE.getString("metatag.cast"), null, panelMovieActors, null); // $NON-NLS-1$

    panelMediaInformation = new MovieMediaInformationPanel(movieSelectionModel);
    tabbedPaneMovieDetails.addTab(
        BUNDLE.getString("metatag.mediainformation"),
        null,
        panelMediaInformation,
        null); //$NON-NLS-1$

    panelMediaFiles = new MovieMediaFilesPanel(movieSelectionModel);
    tabbedPaneMovieDetails.addTab(
        BUNDLE.getString("metatag.mediafiles"), null, panelMediaFiles, null); // $NON-NLS-1$

    final List<MediaFile> mediaFiles = new ArrayList<MediaFile>();
    final ImagePanel panelArtwork = new ImagePanel(mediaFiles);
    tabbedPaneMovieDetails.addTab(
        BUNDLE.getString("metatag.artwork"), null, panelArtwork, null); // $NON-NLS-1$

    panelMovieTrailer = new MovieTrailerPanel(movieSelectionModel);
    tabbedPaneMovieDetails.addTab(
        BUNDLE.getString("metatag.trailer"), null, panelMovieTrailer, null); // $NON-NLS-1$

    // beansbinding init
    initDataBindings();

    // manual coded binding
    PropertyChangeListener propertyChangeListener =
        new PropertyChangeListener() {
          public void propertyChange(PropertyChangeEvent propertyChangeEvent) {
            String property = propertyChangeEvent.getPropertyName();
            Object source = propertyChangeEvent.getSource();
            // react on selection of a movie and change of a movie
            if (source instanceof MovieSelectionModel
                || (source instanceof Movie && MEDIA_FILES.equals(property))) {
              Movie movie = null;
              if (source instanceof MovieSelectionModel) {
                movie = ((MovieSelectionModel) source).getSelectedMovie();
              }
              if (source instanceof Movie) {
                movie = (Movie) source;
              }

              if (movie != null) {
                if (movie.getTop250() > 0) {
                  lblTop250.setText("Top 250: #" + movie.getTop250());
                } else {
                  lblTop250.setText("");
                }
                lblMovieBackground.setImagePath(movie.getArtworkFilename(MediaFileType.FANART));
                lblMoviePoster.setImagePath(movie.getArtworkFilename(MediaFileType.POSTER));

                synchronized (mediaFiles) {
                  mediaFiles.clear();
                  for (MediaFile mediafile : movie.getMediaFiles()) {
                    if (mediafile.isGraphic()) {
                      mediaFiles.add(mediafile);
                    }
                  }
                  panelArtwork.rebuildPanel();
                }
              }
            }
            if ((source.getClass() == Movie.class && FANART.equals(property))) {
              Movie movie = (Movie) source;
              lblMovieBackground.clearImage();
              lblMovieBackground.setImagePath(movie.getArtworkFilename(MediaFileType.FANART));
            }
            if ((source.getClass() == Movie.class && POSTER.equals(property))) {
              Movie movie = (Movie) source;
              lblMoviePoster.clearImage();
              lblMoviePoster.setImagePath(movie.getArtworkFilename(MediaFileType.POSTER));
            }
            if ((source.getClass() == Movie.class && TOP250.equals(property))) {
              Movie movie = (Movie) source;
              if (movie.getTop250() > 0) {
                lblTop250.setText(
                    BUNDLE.getString("metatag.top250") + ": #" + movie.getTop250()); // $NON-NLS-1$
              } else {
                lblTop250.setText("");
              }
            }
          }
        };

    movieSelectionModel.addPropertyChangeListener(propertyChangeListener);
  }