/*
This file is part of JFLICKS.
JFLICKS 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.
JFLICKS 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 JFLICKS. If not, see <http://www.gnu.org/licenses/>.
*/
package org.jflicks.metadata.themoviedb;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.Serializable;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import org.jflicks.job.JobEvent;
import org.jflicks.job.JobListener;
import org.jflicks.metadata.Hit;
import org.jflicks.metadata.SearchEvent;
import org.jflicks.metadata.SearchPanel;
import org.jflicks.util.ProgressBar;
import org.jflicks.util.Util;
import org.jdesktop.swingx.JXPanel;
import org.jdesktop.swingx.painter.ImagePainter;
/**
* This panel simply allows the user to search themoviedb.org and acquire
* images.
*
* @author Doug Barnum
* @version 1.0 - 28 Dec 09
*/
public class TheMovieDBSearch extends SearchPanel implements ActionListener,
ListSelectionListener, JobListener {
private JTextField searchTextField;
private JButton searchButton;
private JList movieList;
private JList imageList;
private JComboBox posterComboBox;
private JComboBox fanartComboBox;
private JXPanel thumbPanel;
private MovieInfo movieInfo;
private BufferedImage previewBufferedImage;
private JButton applyButton;
private HashMap<String, BufferedImage> hashMap;
private String searchTerms;
/**
* Simple constructor.
*/
public TheMovieDBSearch() {
setHashMap(new HashMap<String, BufferedImage>());
JTextField tf = new JTextField(16);
tf.addActionListener(this);
setSearchTextField(tf);
JButton b = new JButton("Search");
b.addActionListener(this);
setSearchButton(b);
JList moviel = new JList();
moviel.setPrototypeCellValue("01234567890123456789012345678901234567");
moviel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
moviel.setVisibleRowCount(5);
moviel.addListSelectionListener(this);
setMovieList(moviel);
JScrollPane movielistScroller = new JScrollPane(moviel,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
JPanel moviesPanel = new JPanel(new BorderLayout());
moviesPanel.setBorder(BorderFactory.createTitledBorder("Movies Found"));
moviesPanel.add(movielistScroller, BorderLayout.CENTER);
JList imagel = new JList();
imagel.setPrototypeCellValue("01234567890123456789012345678901234567");
imagel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
imagel.setVisibleRowCount(5);
imagel.addListSelectionListener(this);
setImageList(imagel);
JScrollPane imagelistScroller = new JScrollPane(imagel,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
JPanel imagesPanel = new JPanel(new BorderLayout());
imagesPanel.setBorder(
BorderFactory.createTitledBorder("View Images by TYPE - ID"));
imagesPanel.add(imagelistScroller, BorderLayout.CENTER);
JComboBox poster = new JComboBox();
poster.addActionListener(this);
setPosterComboBox(poster);
JPanel posterPanel = new JPanel(new BorderLayout());
posterPanel.setBorder(
BorderFactory.createTitledBorder("Select Poster Image"));
posterPanel.add(poster, BorderLayout.CENTER);
JComboBox fanart = new JComboBox();
fanart.addActionListener(this);
setFanartComboBox(fanart);
JPanel fanartPanel = new JPanel(new BorderLayout());
fanartPanel.setBorder(
BorderFactory.createTitledBorder("Select Fanart Image"));
fanartPanel.add(fanart, BorderLayout.CENTER);
try {
BufferedImage bi =
ImageIO.read(getClass().getResource("thumb_preview.png"));
setPreviewBufferedImage(bi);
} catch (IOException ex) {
setPreviewBufferedImage(null);
}
JXPanel thumb = new JXPanel();
thumb.setPreferredSize(new Dimension(300, 200));
ImagePainter painter = new ImagePainter(getPreviewBufferedImage());
thumb.setBackgroundPainter(painter);
setThumbPanel(thumb);
MovieInfo mi = new MovieInfo();
setMovieInfo(mi);
b = new JButton("Apply");
b.addActionListener(this);
setApplyButton(b);
JPanel searchPanel = new JPanel(new GridBagLayout());
searchPanel.setBorder(
BorderFactory.createTitledBorder("Search themoviedb.org site"));
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.CENTER;
gbc.weightx = 1.0;
gbc.weighty = 0.0;
gbc.insets = new Insets(4, 4, 4, 4);
searchPanel.add(getSearchTextField(), gbc);
gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.CENTER;
gbc.weightx = 0.0;
gbc.weighty = 0.0;
gbc.insets = new Insets(4, 4, 4, 4);
searchPanel.add(getSearchButton(), gbc);
setLayout(new GridBagLayout());
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.CENTER;
gbc.weightx = 1.0;
gbc.weighty = 0.0;
gbc.insets = new Insets(4, 4, 4, 4);
add(searchPanel, gbc);
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 1;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.CENTER;
gbc.weightx = 1.0;
gbc.weighty = 0.5;
gbc.insets = new Insets(4, 4, 4, 4);
add(moviesPanel, gbc);
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 2;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.CENTER;
gbc.weightx = 1.0;
gbc.weighty = 0.5;
gbc.insets = new Insets(4, 4, 4, 4);
add(imagesPanel, gbc);
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 3;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.CENTER;
gbc.weightx = 1.0;
gbc.weighty = 0.0;
gbc.insets = new Insets(4, 4, 4, 4);
add(thumb, gbc);
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 4;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.CENTER;
gbc.weightx = 1.0;
gbc.weighty = 0.0;
gbc.insets = new Insets(4, 4, 4, 4);
add(posterPanel, gbc);
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 5;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.CENTER;
gbc.weightx = 1.0;
gbc.weighty = 0.0;
gbc.insets = new Insets(4, 4, 4, 4);
add(fanartPanel, gbc);
gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.gridheight = 5;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.CENTER;
gbc.weightx = 1.0;
gbc.weighty = 0.0;
gbc.insets = new Insets(4, 4, 4, 4);
add(mi, gbc);
gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 5;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.NONE;
gbc.anchor = GridBagConstraints.CENTER;
gbc.weightx = 1.0;
gbc.weighty = 0.0;
gbc.insets = new Insets(4, 4, 4, 4);
add(getApplyButton(), gbc);
setHit(new Hit());
}
/**
* {@inheritDoc}
*/
public String getSearchTerms() {
return (searchTerms);
}
/**
* {@inheritDoc}
*/
public void setSearchTerms(String s) {
searchTerms = s;
JTextField tf = getSearchTextField();
if (tf != null) {
tf.setText(searchTerms);
}
}
private JTextField getSearchTextField() {
return (searchTextField);
}
private void setSearchTextField(JTextField tf) {
searchTextField = tf;
}
private JButton getSearchButton() {
return (searchButton);
}
private void setSearchButton(JButton b) {
searchButton = b;
}
private JList getMovieList() {
return (movieList);
}
private void setMovieList(JList l) {
movieList = l;
}
private JList getImageList() {
return (imageList);
}
private void setImageList(JList l) {
imageList = l;
}
private JComboBox getPosterComboBox() {
return (posterComboBox);
}
private void setPosterComboBox(JComboBox cb) {
posterComboBox = cb;
}
private JComboBox getFanartComboBox() {
return (fanartComboBox);
}
private void setFanartComboBox(JComboBox cb) {
fanartComboBox = cb;
}
private JXPanel getThumbPanel() {
return (thumbPanel);
}
private void setThumbPanel(JXPanel p) {
thumbPanel = p;
}
private BufferedImage getPreviewBufferedImage() {
return (previewBufferedImage);
}
private void setPreviewBufferedImage(BufferedImage bi) {
previewBufferedImage = bi;
}
private MovieInfo getMovieInfo() {
return (movieInfo);
}
private void setMovieInfo(MovieInfo mi) {
movieInfo = mi;
}
private JButton getApplyButton() {
return (applyButton);
}
private void setApplyButton(JButton b) {
applyButton = b;
}
private HashMap<String, BufferedImage> getHashMap() {
return (hashMap);
}
private void setHashMap(HashMap<String, BufferedImage> hm) {
hashMap = hm;
}
private BufferedImage fetchBufferedImage(Image image) {
BufferedImage result = null;
HashMap<String, BufferedImage> hm = getHashMap();
if ((hm != null) && (image != null)) {
String urlstr = image.getUrlThumb();
if (urlstr != null) {
result = hm.get(urlstr);
if (result == null) {
try {
URL url = new URL(urlstr);
result = ImageIO.read(url);
hm.put(urlstr, result);
} catch (MalformedURLException ex) {
JOptionPane.showMessageDialog(Util.findFrame(this),
"Error: " + ex.getMessage(), "alert",
JOptionPane.ERROR_MESSAGE);
} catch (IOException ex) {
JOptionPane.showMessageDialog(Util.findFrame(this),
"Error: " + ex.getMessage(), "alert",
JOptionPane.ERROR_MESSAGE);
}
}
}
}
return (result);
}
private void searchAction() {
JTextField tf = getSearchTextField();
if (tf != null) {
String terms = tf.getText().trim();
if ((terms != null) && (terms.length() > 0)) {
SearchJob sj = new SearchJob(terms);
ProgressBar pbar = new ProgressBar(this, "Searching...", sj);
pbar.addJobListener(this);
pbar.execute();
} else {
JOptionPane.showMessageDialog(Util.findFrame(this),
"Nothing to search for!!", "alert",
JOptionPane.ERROR_MESSAGE);
}
}
}
private void imageAction() {
JList movielist = getMovieList();
if (movielist != null) {
Movie m = (Movie) movielist.getSelectedValue();
RetrieveJob rj = new RetrieveJob(m.getId());
ProgressBar pbar = new ProgressBar(this, "Fetching Images...", rj);
pbar.addJobListener(this);
pbar.execute();
}
}
private void imageDisplayAction() {
JList imagel = getImageList();
JXPanel panel = getThumbPanel();
if ((panel != null) && (imagel != null)) {
Image image = (Image) imagel.getSelectedValue();
BufferedImage bi = fetchBufferedImage(image);
if (bi != null) {
ImagePainter painter = new ImagePainter(bi);
panel.setBackgroundPainter(painter);
} else {
ImagePainter painter =
new ImagePainter(getPreviewBufferedImage());
panel.setBackgroundPainter(painter);
}
}
}
private void applyAction() {
fireSearchEvent(SearchEvent.UPDATE, getHit());
}
/**
* {@inheritDoc}
*/
public void searchUpdate(SearchEvent event) {
if (event.getSearchType() == SearchEvent.SEARCH_MOVIE) {
setSearchTerms(event.getTerms());
}
}
/**
* We listen for button events which include the search button and
* the user typing the enter key on the search text field.
*
* @param event The given action event.
*/
public void actionPerformed(ActionEvent event) {
if (event.getSource() == getSearchButton()) {
searchAction();
} else if (event.getSource() == getSearchTextField()) {
searchAction();
} else if (event.getSource() == getPosterComboBox()) {
updateHit();
} else if (event.getSource() == getFanartComboBox()) {
updateHit();
} else if (event.getSource() == getApplyButton()) {
applyAction();
}
}
/**
* We listen for selection on the movie list box.
*
* @param event The given list selection event.
*/
public void valueChanged(ListSelectionEvent event) {
if (!event.getValueIsAdjusting()) {
if (event.getSource() == getMovieList()) {
JList l = getMovieList();
MovieInfo mi = getMovieInfo();
if ((l != null) && (mi != null)) {
int index = l.getSelectedIndex();
if (index != -1) {
mi.setMovie((Movie) l.getSelectedValue());
imageAction();
updateHit();
}
}
} else if (event.getSource() == getImageList()) {
imageDisplayAction();
}
}
}
/**
* We need to know the status of the running job. If it's done
* we update our UI based upon the event state.
*
* @param event The given job event instance.
*/
public void jobUpdate(JobEvent event) {
if (event.getType() == JobEvent.COMPLETE) {
Serializable s = event.getState();
if (s instanceof Search) {
Search search = (Search) s;
JList l = getMovieList();
if (l != null) {
Movie[] array = search.getMovies();
if (array != null) {
l.setListData(array);
} else {
l.setModel(new DefaultListModel());
}
JList imagel = getImageList();
imagel.setModel(new DefaultListModel());
}
} else if (s instanceof Movie) {
Movie movie = (Movie) s;
JList imagel = getImageList();
if ((imagel != null) && (movie.hasThumbnails())) {
imagel.setModel(new DefaultListModel());
Artwork art = movie.getArtwork();
if (art != null) {
ArrayList<Image> ilist = new ArrayList<Image>();
Image[] posters = art.getPosters();
if (posters != null) {
JComboBox poster = getPosterComboBox();
if (poster != null) {
poster.removeAllItems();
for (int i = 0; i < posters.length; i++) {
ilist.add(posters[i]);
poster.addItem(posters[i]);
}
}
}
Image[] backs = art.getBackdrops();
if (backs != null) {
JComboBox fanart = getFanartComboBox();
if (fanart != null) {
fanart.removeAllItems();
for (int i = 0; i < backs.length; i++) {
ilist.add(backs[i]);
fanart.addItem(backs[i]);
}
}
}
if (ilist.size() > 0) {
Image[] array =
ilist.toArray(new Image[ilist.size()]);
imagel.setListData(array);
}
}
/*
Image[] thumbs = movie.getThumbnailImages();
if (thumbs != null) {
JComboBox poster = getPosterComboBox();
JComboBox fanart = getFanartComboBox();
if ((poster != null) && (fanart != null)) {
imagel.setModel(new DefaultListModel());
poster.removeAllItems();
fanart.removeAllItems();
ArrayList<Image> ilist = new ArrayList<Image>();
for (int i = 0; i < thumbs.length; i++) {
ilist.add(thumbs[i]);
if (thumbs[i].isPosterType()) {
poster.addItem(thumbs[i]);
} else if (thumbs[i].isBackdropType()) {
fanart.addItem(thumbs[i]);
}
}
if (ilist.size() > 0) {
Image[] array =
ilist.toArray(new Image[ilist.size()]);
imagel.setListData(array);
}
}
} else {
imagel.setModel(new DefaultListModel());
}
*/
} else {
if (imagel != null) {
imagel.setModel(new DefaultListModel());
}
JOptionPane.showMessageDialog(Util.findFrame(this),
"Sorry no images available", "alert",
JOptionPane.INFORMATION_MESSAGE);
}
JXPanel panel = getThumbPanel();
if (panel != null) {
ImagePainter painter =
new ImagePainter(getPreviewBufferedImage());
panel.setBackgroundPainter(painter);
}
}
}
}
private void updateHit() {
Hit h = getHit();
if (h == null) {
h = new Hit();
setHit(h);
}
MovieInfo mi = getMovieInfo();
if (mi != null) {
Movie m = mi.getMovie();
if (m != null) {
h.setId("" + m.getId());
h.setMetadataTitle("TheMovieDB.org");
h.setTitle(m.getTitle());
h.setDescription(m.getOverview());
h.setReleased(m.getReleaseDate());
JComboBox cb = getPosterComboBox();
if (cb != null) {
Image img = (Image) cb.getSelectedItem();
if (img != null) {
//Image real = m.getCoverSizeImageById(id);
/*
int myid = img.getId();
Image real = m.getOriginalSizeImageById(id);
if (real != null) {
h.setPosterURL(real.getUrl());
} else {
real = m.getMidSizeImageById(id);
if (real != null) {
h.setPosterURL(real.getUrl());
} else {
h.setPosterURL(img.getUrl());
}
}
*/
}
}
cb = getFanartComboBox();
if (cb != null) {
Image img = (Image) cb.getSelectedItem();
if (img != null) {
/*
int myid = img.getId();
Image real = m.getOriginalSizeImageById(id);
if (real != null) {
h.setFanartURL(real.getUrl());
} else {
real = m.getPosterSizeImageById(id);
if (real != null) {
h.setFanartURL(real.getUrl());
} else {
h.setFanartURL(img.getUrl());
}
}
*/
}
}
}
}
}
}