package moviescraper.doctord.view;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import moviescraper.doctord.model.Movie;
import moviescraper.doctord.model.dataitem.Thumb;
import moviescraper.doctord.view.CustomComponents.AsyncImageComponent;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.imgscalr.Scalr;
import org.imgscalr.Scalr.Method;
public class ArtWorkPanel extends JPanel implements ComponentListener {
private static final long serialVersionUID = 9061046066424044803L;
private AsyncImageComponent lblPosterIcon;
private AsyncImageComponent lblFanartIcon;
private static final String artworkTooltip = "Double click to change image.";
//initial max sizes = values can change when window is resized
private static int maximumPosterSizeX = 400;
private static int maximumPosterSizeY = 500;
private static int maximumFanartSizeX = 400;
private static int maximumFanartSizeY = 135;
private Dimension oldSize;
private boolean updatingPosterAndFanartSizes = false;
private GUIMain guiMain;
public ArtWorkPanel(GUIMain guiMain) {
//artworkPanel.setMinimumSize(new Dimension(379,675));
this.guiMain = guiMain;
//this.setPreferredSize(new Dimension(maximumPosterSizeX + 100, (maximumPosterSizeY + maximumFanartSizeY) * 2));
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
addComponentListener(this);
//set up the poster
lblPosterIcon = new AsyncImageComponent(null, false, null, false, true, false);
lblPosterIcon.setPreferredSize(new Dimension(maximumPosterSizeX, maximumPosterSizeY));
lblPosterIcon.setToolTipText(artworkTooltip);
lblPosterIcon.setAlignmentX(Component.LEFT_ALIGNMENT);
lblPosterIcon.setAlignmentY(Component.CENTER_ALIGNMENT);
lblPosterIcon.addMouseListener(new MouseListenerShowArtPicker(false));
//set up the fanart
lblFanartIcon = new AsyncImageComponent(null, false, null, false, true, false);
lblFanartIcon.setPreferredSize(new Dimension(maximumFanartSizeX, maximumFanartSizeY));
lblFanartIcon.setToolTipText(artworkTooltip);
lblFanartIcon.setAlignmentX(Component.LEFT_ALIGNMENT);
lblFanartIcon.setAlignmentY(Component.BOTTOM_ALIGNMENT);
lblFanartIcon.addMouseListener(new MouseListenerShowArtPicker(true));
add(lblPosterIcon);
//add a little bit of space between the poster and the fanart
add(Box.createRigidArea(new Dimension(0,5)));
add(lblFanartIcon);
oldSize = getBounds().getSize();
}
public void clearPictures() {
clearFanart();
clearPoster();
}
public void clearFanart() {
lblFanartIcon.clear();
}
public void clearPoster() {
lblPosterIcon.clear();
}
private void updatePosterAndFanartSizes(){
updatingPosterAndFanartSizes = true;
if(lblFanartIcon != null)
{
Dimension newSize = calculateDimensionFit(lblFanartIcon.getWidth(), lblFanartIcon.getHeight(), maximumPosterSizeX, maximumFanartSizeY);
lblFanartIcon.setPreferredSize(newSize);
lblFanartIcon.repaint();
}
}
public static BufferedImage resizeToFanart(BufferedImage image) {
Dimension dimensionFit = calculateDimensionFit(image.getWidth(), image.getHeight(),
maximumFanartSizeX, maximumFanartSizeY);
return resizePicture(image, dimensionFit.width, dimensionFit.height);
}
/**
* Calculate the max size we can resize an image while fitting within maxWidth and maxHeight
* and still maintaining the aspect ratio
* @param imageWidth - the width of the image to resize
* @param imageHeight - the height of the image to resize
* @param maxWidth - the maximum width the image can be
* @param maxHeight - the maximum height the image can be
* @return A Dimension object with the calculated width and heights set on it
*/
private static Dimension calculateDimensionFit(int imageWidth, int imageHeight,
int maxWidth, int maxHeight)
{
double aspectRatio = Math.min((double) maxWidth / (double) imageWidth,
(double) maxHeight / (double) imageHeight);
return new Dimension((int)(imageWidth * aspectRatio), (int)(imageHeight * aspectRatio));
}
public static BufferedImage resizeToPoster(BufferedImage image) {
Dimension dimensionFit = calculateDimensionFit(image.getWidth(), image.getHeight(),
maximumPosterSizeX, maximumPosterSizeY);
return resizePicture(image, dimensionFit.width, dimensionFit.height);
}
public static BufferedImage resizePicture(BufferedImage image, int newWidth, int newHeight) {
if(image != null && newWidth > 0 && newHeight > 0)
return Scalr.resize(image, Method.QUALITY, newWidth, newHeight, Scalr.OP_ANTIALIAS);
else return image;
}
public void updateView(boolean forceUpdatePoster, GUIMain gui) {
boolean posterFileUpdateOccured = false;
boolean fanartFileUpdateOccured = false;
int indexOfShownMovie = gui.getFileDetailPanel().currentListIndexOfDisplayedMovie;
if(!forceUpdatePoster && gui.getCurrentlySelectedMovieFileList().size() > 0)
{
// try to get the poster from a local file, if it exists
//Maybe there is a file in the directory just called folder.jpg
File potentialOtherPosterJpg = new File(Movie.getFileNameOfPoster(gui.getCurrentlySelectedMovieFileList().get(indexOfShownMovie), true));
File potentialOtherFanartJpg = new File(Movie.getFileNameOfFanart(gui.getCurrentlySelectedMovieFileList().get(indexOfShownMovie), true));
//the poster would be called moviename-poster.jpg
File standardPosterJpg = new File(Movie.getFileNameOfPoster(gui.getCurrentlySelectedMovieFileList().get(indexOfShownMovie), false));
File standardFanartJpg = new File(Movie.getFileNameOfFanart(gui.getCurrentlySelectedMovieFileList().get(indexOfShownMovie), false));
if (gui.getCurrentlySelectedPosterFileList().get(indexOfShownMovie).exists()) {
try {
lblPosterIcon.setIcon(new Thumb(gui.getCurrentlySelectedPosterFileList().get(indexOfShownMovie)), new Dimension(maximumPosterSizeX, maximumPosterSizeY));
posterFileUpdateOccured = true;
} catch (IOException e) {
e.printStackTrace();
}
}
if(gui.getCurrentlySelectedFanartFileList().get(indexOfShownMovie).exists())
{
try {
lblFanartIcon.setIcon(new Thumb(gui.getCurrentlySelectedFanartFileList().get(indexOfShownMovie)), new Dimension(maximumFanartSizeX, maximumFanartSizeY));
fanartFileUpdateOccured = true;
} catch (IOException e) {
e.printStackTrace();
}
}
//well we didn't find a poster file we were expecting, try to see if there is any file named poster.jpg in there
if(gui.getCurrentlySelectedMovieFileList().get(indexOfShownMovie).isDirectory() && potentialOtherPosterJpg.exists() && !posterFileUpdateOccured)
{
try {
lblPosterIcon.setIcon(new Thumb(potentialOtherPosterJpg), new Dimension(maximumPosterSizeX, maximumPosterSizeY));
posterFileUpdateOccured = true;
} catch (IOException e) {
e.printStackTrace();
}
}
//well we didn't find a fanart file we were expecting, try to see if there is any file named fanart.jpg in there
if(gui.getCurrentlySelectedMovieFileList().get(indexOfShownMovie).isDirectory() && potentialOtherFanartJpg.exists() && !fanartFileUpdateOccured)
{
try {
lblFanartIcon.setIcon(new Thumb(potentialOtherFanartJpg), new Dimension(maximumFanartSizeX, maximumFanartSizeY));
fanartFileUpdateOccured = true;
} catch (IOException e) {
e.printStackTrace();
}
}
//just in case, also check to see if one called moviename-poster.jpg is there, even if we were expecting a poster.jpg due to the preference we set
if(standardPosterJpg.exists() && !posterFileUpdateOccured)
{
try {
lblPosterIcon.setIcon(new Thumb(standardPosterJpg), new Dimension(maximumPosterSizeX, maximumPosterSizeY));
posterFileUpdateOccured = true;
} catch (IOException e) {
e.printStackTrace();
}
}
//just in case, also check to see if one called moviename-fanart.jpg is there, even if we were expecting a poster.jpg due to the preference we set
if(standardFanartJpg.exists() && !fanartFileUpdateOccured)
{
try {
lblFanartIcon.setIcon(new Thumb(standardFanartJpg), new Dimension(maximumFanartSizeX, maximumFanartSizeY));
fanartFileUpdateOccured = true;
} catch (IOException e) {
e.printStackTrace();
}
}
}
// otherwise read it from the URL specified by the object since we couldn't find any local file
if (gui.movieToWriteToDiskList.size() > 0 && gui.movieToWriteToDiskList.get(indexOfShownMovie) != null && gui.movieToWriteToDiskList.get(indexOfShownMovie).hasPoster() && !posterFileUpdateOccured) {
try {
if(gui.getFileDetailPanel().currentMovie.getPosters().length > 0 )
{
lblPosterIcon.setIcon(gui.getFileDetailPanel().currentMovie.getPosters()[0], new Dimension(maximumPosterSizeX, maximumPosterSizeY));
posterFileUpdateOccured = true;
}
} catch (Exception e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null, ExceptionUtils.getStackTrace(e),"Unhandled Exception",JOptionPane.ERROR_MESSAGE);
}
}
//try to read the fanart from the url since we couldn't find any local file
if (gui.movieToWriteToDiskList.size() > 0 && gui.movieToWriteToDiskList.get(indexOfShownMovie) != null && gui.movieToWriteToDiskList.get(indexOfShownMovie).hasFanart() && !fanartFileUpdateOccured) {
if(gui.getFileDetailPanel().currentMovie.getFanart().length > 0)
{
lblFanartIcon.setIcon(gui.getFileDetailPanel().currentMovie.getFanart()[0], new Dimension(maximumFanartSizeX, maximumFanartSizeY));
fanartFileUpdateOccured = true;
}
}
}
@Override
public void componentHidden(ComponentEvent e) {}
@Override
public void componentMoved(ComponentEvent e) {}
@Override
public void componentResized(ComponentEvent e) {
Dimension newSize = e.getComponent().getBounds().getSize();
double oldSizeToNewSizeScaleWidth = (double) newSize.width / (double) oldSize.width;
if(oldSize.width != 0 && oldSize.height != 0 && !updatingPosterAndFanartSizes )
{
maximumPosterSizeX *= oldSizeToNewSizeScaleWidth;
maximumFanartSizeX = maximumPosterSizeX;
maximumFanartSizeY = newSize.height - maximumPosterSizeY - 25;
updatePosterAndFanartSizes();
}
oldSize = newSize;
updatingPosterAndFanartSizes = false;
}
@Override
public void componentShown(ComponentEvent e) {}
private final class MouseListenerShowArtPicker implements MouseListener {
/**
* Set this to true in the constructor if this is supposed to be used for fanart picker.
* Could have done some kind of subclass thing, but this was just easier.
*/
boolean forFanartInsteadOfPosters;
private static final String posterPickerDialogName = "Pick New Primary Poster";
private static final String fanartPickerDialogName = "Pick New Primary Fanart";
public MouseListenerShowArtPicker(boolean forFanartInsteadOfPosters) {
this.forFanartInsteadOfPosters = forFanartInsteadOfPosters;
}
private String getDialogName()
{
if(forFanartInsteadOfPosters)
return fanartPickerDialogName;
else return posterPickerDialogName;
}
private Thumb[] getCorrectArtArray(Movie movie)
{
if(forFanartInsteadOfPosters)
return movie.getFanart();
else return movie.getPosters();
}
@Override
public void mouseClicked(MouseEvent event) {
if (event.getClickCount() == 2) {
Movie currentMovie = guiMain.getFileDetailPanel().getCurrentMovie();
if(currentMovie != null)
{
Thumb [] artToPick = getCorrectArtArray(currentMovie);
if (artToPick != null
&& currentMovie.getPosters().length > 1) {
Thumb artFromUserSelection = ScrapeAmalgamatedProgressDialog.showArtPicker(artToPick,
getDialogName(),!forFanartInsteadOfPosters);
if(forFanartInsteadOfPosters)
currentMovie.moveExistingFanartToFront(artFromUserSelection);
else currentMovie.moveExistingPosterToFront(artFromUserSelection);
guiMain.getFileDetailPanel().updateView(true, false);
}
}
}
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
}
}