content: package tim.prune.gui;
  
  import java.awt.Color;
  import java.awt.Dimension;
  import java.awt.Graphics;
  import java.awt.Image;
  import javax.swing.ImageIcon;
  import javax.swing.JPanel;
  import javax.swing.SwingUtilities;
  
  import tim.prune.I18nManager;
  import tim.prune.data.Photo;
  
  /**
   * GUI component for showing photo thumbnail
   */
  public class PhotoThumbnail extends JPanel
  {
  	private Photo _photo = null;
  	private Image _thumbnail = null;
  	private boolean _loadingImage = false;
  	private boolean _loadFailed = false;
  	private boolean _inPanel = false;
  	/** String to show before photo is loaded */
  	private static final String LOADING_STRING = I18nManager.getText("details.photo.loading") + " ...";
  
  
  	/**
  	 * Constructor
  	 */
  	public PhotoThumbnail()
  	{
  		this(true);
  	}
  
  	/**
  	 * Constructor
  	 * @param inPanel true if thumbnail is inside panel
  	 */
  	public PhotoThumbnail(boolean inPanel)
  	{
  		setOpaque(true);
  		_inPanel = inPanel;
  	}
  
  	/**
  	 * Set the Photo
  	 * @param inPhoto Photo object to show thumbnail for
  	 */
  	public void setPhoto(Photo inPhoto)
  	{
  		// Check whether the photo has changed
  		if (_photo != inPhoto)
  		{
  			_photo = inPhoto;
  			_thumbnail = null;
  			_loadFailed = false;
  		}
  		repaint();
  	}
  
  	/**
  	 * Force a refresh / reload
  	 */
  	public void refresh()
  	{
  		_thumbnail = null;
  		_loadFailed = false;
  	}
  
  	/**
  	 * Override paint method
  	 * @see javax.swing.JComponent#paint(java.awt.Graphics)
  	 */
  	public void paint(Graphics inG)
  	{
  		super.paint(inG);
  		if (_photo != null)
  		{
  			// read thumbnail in separate thread
  			if (_thumbnail == null && !_loadingImage && !_loadFailed)
  			{
  				_loadingImage = true;
  				new Thread(this::run).start();
  			}
  			// if loading, display message
  			if (_loadingImage)
  			{
  				inG.setColor(Color.BLACK);
  				inG.drawString(LOADING_STRING, 10, 30);
  			}
  			else if (_thumbnail != null && !_loadFailed)
  			{
  				// Copy scaled, smoothed (and rotated) image into scaled
  				int usableWidth = getParent().getWidth()-10;
  				int usableHeight = (_inPanel?usableWidth:getHeight()-10);
  				Image scaled = ImageUtils.rotateImage(_thumbnail, usableWidth, usableHeight, _photo.getRotationDegrees());
  				int scaleWidth = scaled.getWidth(null);
  				int scaleHeight = scaled.getHeight(null);
  				// Draw scaled / rotated image to component
  				int horizOffset = (getWidth() - scaleWidth) / 2;
  				int vertOffset = (getHeight() - scaleHeight) / 2;
  				inG.drawImage(scaled, horizOffset, vertOffset, scaleWidth, scaleHeight, null);
  				// Special resize behaviour when locked inside details panel
  				if (_inPanel && (getHeight() < getWidth() || getHeight() > usableWidth))
  				{
  					Dimension newsize = new Dimension(usableWidth, usableWidth);
  					setPreferredSize(newsize);
  					setSize(newsize);
  					invalidate();
  					// Schedule a relayout because the size has changed
  					SwingUtilities.invokeLater(() -> {
  						try {Thread.sleep(200);} catch (InterruptedException e) {}
  						getParent().getParent().getParent().validate();
  					});
  				}
  			}
  		}
  	}
  
  
  	/**
  	 * Run method, for loading image in separate thread
  	 */
  	public void run()
  	{
  		if (_inPanel)
  		{
  			_thumbnail = null;
  			// try to use exif thumbnail
  			if (_photo.getExifThumbnail() != null)
  			{
  				// Use exif thumbnail
  				Image image = new ImageIcon(_photo.getExifThumbnail()).getImage();
  				_thumbnail = ImageUtils.createScaledImage(image, image.getWidth(null), image.getHeight(null));
  			}
  			// Maybe there's no thumbnail, maybe the load of the thumbnail failed
  			if (_thumbnail == null)
  			{
  				// no exif thumbnail available, going to have to read whole thing
  				int picWidth = _photo.getWidth();
  				int picHeight = _photo.getHeight();
  				if (picWidth > -1 && picHeight > -1)
  				{
  					// Just set a "reasonable" thumbnail size for now
  					final int DEFAULT_THUMB_SIZE = 400;
  					// calculate maximum thumbnail size
  					Dimension thumbSize = ImageUtils.getThumbnailSize(picWidth, picHeight, DEFAULT_THUMB_SIZE, DEFAULT_THUMB_SIZE);
  					// Make icon to load image into
  					Image image = _photo.createImageIcon().getImage();
  					// save scaled, smoothed thumbnail for reuse
  					_thumbnail = ImageUtils.createScaledImage(image, thumbSize.width, thumbSize.height);
  				}
  				else {
  					_loadFailed = true;
  				}
  			}
  		}
  		else {
  			_thumbnail = _photo.createImageIcon().getImage();
  		}
  		_loadingImage = false;
  		repaint();
  	}
  }
  