
import java.awt.*;
import java.awt.image.*;
import java.io.File;
import javax.swing.*;
import javax.swing.border.*;

import se.datadosen.jalbum.*;
import se.datadosen.util.Colors;

public class FramePreviewPanel extends JPanel
{
	private static final String TITLE = "Frame Preview";

	private JAlbumFrame window;
	private AlbumBean engine;

	private JLabel lblPreview = new JLabel( "", JLabel.HORIZONTAL );
	private BPPStyleSheet styleSheet = null;

	private BufferedImage backgroundImage = null;
	private int tileWidth;
	private int tileHeight;

	public FramePreviewPanel(JAlbumFrame window, AlbumBean engine)
	{
		super( new BorderLayout( 0, 0 ) );
		this.window = window;
		this.engine = engine;

		add( lblPreview, BorderLayout.CENTER );
		setPreviewPanelTitle( TITLE );
		styleSheet = new BPPStyleSheet( engine );
	}

	private void setPreviewPanelTitle(String title)
	{
		Border border = BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder(title), BorderFactory.createEmptyBorder( 10, 10, 10, 10 ) );

		setBorder( border );
	}

	protected void paintComponent( Graphics g )
	{
		super.paintComponent( g );

		if( backgroundImage==null )
			return;

		//Rectangle bounds = new Rectangle(g.getClipBounds());
		Rectangle bounds = new Rectangle(0, 0, getWidth(), getHeight());
		int width = tileWidth;
		int height = tileHeight;

		bounds.setLocation((int) bounds.getX() + 10, (int) bounds.getY() + 20);
		bounds.setSize((int) bounds.getWidth() - 10, (int) bounds.getHeight() - 20);
		for( double x=bounds.getX(); x<bounds.getWidth(); x += tileWidth )
		{
			for( double y=bounds.getY(); y<bounds.getHeight(); y += tileHeight )
			{
				if( x+tileWidth>bounds.getWidth() )
					width = (int) (bounds.getWidth() - x);
				else
					width = tileWidth;
				if( y+tileHeight>bounds.getHeight() )
					height = (int) (bounds.getHeight() - y);
				else
					height = tileHeight;

				if( tileWidth>width || tileHeight>height )
					g.drawImage( backgroundImage.getSubimage(0, 0, width, height), (int)x, (int)y, width, height, this );
				else
					g.drawImage( backgroundImage, (int)x, (int)y, width, height, this );
			}
		}
	}

	public void setCurrentPreview( int applyLevel, String frameName )
	{
		if( backgroundImage!=null )
			backgroundImage.flush();
		if( lblPreview.getIcon()!=null )
			((ImageIcon)lblPreview.getIcon()).getImage().flush();

		setPreviewPanelTitle( getBorderTitle( applyLevel, frameName ) );
		setupBackground( applyLevel );
		setupPreview( applyLevel );

		tileHeight = backgroundImage.getHeight();
		tileWidth = backgroundImage.getWidth();

		revalidate();
		repaint();
	}

	private void setupPreview( int applyLevel )
	{
		try
		{
			BPPFrameHandler frameHandler = new BPPFrameHandler( engine, applyLevel );
			File imageFile = new File( frameHandler.skinDirectory, Constants.SKIN_FRAME_CONFIG_DIR + "preview.jpg" );
			AlbumImage albumImage = new AlbumImage( imageFile, engine );

			if( applyLevel!=BPPFrameHandler.APPLY_LEVEL_SLIDE && applyLevel!=BPPFrameHandler.APPLY_LEVEL_MOVIE_SLIDE )
				albumImage = albumImage.scaleToThumbnail();
			albumImage = albumImage.applyFilter( frameHandler, engine.getSkinVariables() );
			lblPreview.setIcon( new ImageIcon( albumImage.getImage() ) );
		}
		catch( Exception e )
		{
			e.printStackTrace();
			window.messageBox( "Can not display a preview for the currently selected frame! Please check the logs..." );
		}
	}

	private void setupBackground( int applyLevel )
	{
		try
		{
			styleSheet.updateVars();

			File bgImage = styleSheet.extractStyleSheetBackgroundImage( null, applyLevel );

			if( bgImage!=null && bgImage.exists() )
			{
				ImageIcon image = new ImageIcon( bgImage.toURL() );

				backgroundImage = new BufferedImage( image.getIconWidth(), image.getIconHeight(), BufferedImage.TYPE_INT_RGB );
				Graphics2D g2d = backgroundImage.createGraphics();

				g2d.drawImage(image.getImage(), 0, 0, this);
				g2d.dispose();
				return;
			}

			String bgColor = styleSheet.extractStyleSheetBackgroundColor( null, applyLevel );

			if( bgColor==null || bgColor.trim().equals( "" ) )
				bgColor = "white";
			backgroundImage = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);

			Graphics2D g2d = ((BufferedImage)backgroundImage).createGraphics();
			g2d.setComposite(AlphaComposite.SrcOver);
			g2d.setColor(Colors.getHTMLColor( bgColor ));
			g2d.fillRect(0,0,100,100);
			g2d.dispose();
		}
		catch( Exception e )
		{
			e.printStackTrace();
			window.messageBox( "Can not set the background for the currently selected frame preview! Please check the logs..." );
		}
	}

	private String getBorderTitle(int applyLevel, String frameName)
	{
		String result = "";

		switch( applyLevel )
		{
			case BPPFrameHandler.APPLY_LEVEL_SLIDE:
				result = "Slide - ";
				break;
			case BPPFrameHandler.APPLY_LEVEL_MOVIE_SLIDE:
				result = "Movie Slide - ";
            	break;
			case BPPFrameHandler.APPLY_LEVEL_THUMBNAIL:
				result = "Thumbnail (Index) - ";
				break;
			case BPPFrameHandler.APPLY_LEVEL_FOLDER:
				result = "Folder Thumbnail (Index) - ";
				break;
			default:
				throw new IllegalArgumentException("The 'applyLevel' parameter is not valid!");
		}

		return result + TITLE + " [" + frameName + "]";
	}
}
