package siprp.clientes;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.JFileChooser;
import javax.swing.JPanel;

import com.evolute.utils.dataui.ControllableComponent;

public class ImagePanel extends JPanel implements MouseListener, ControllableComponent
{

	private static final long serialVersionUID = 1L;

	public static final int WIDTH_THUMBNAIL = 64;
	
	public static final int HEIGHT_THUMBNAIL = 64;
	
	public static final int WIDTH_FULL = 512;
	
	public static final int HEIGHT_FULL = 512;
	
	private final int w;
	
	private final int h;
	
	private boolean thumb = false;
	
	private BufferedImage scaledImage = null;
	
	private BufferedImage image = null;
	
	public ImagePanel( boolean thumbnail )
	{
		thumb = thumbnail;
		w = thumb ? WIDTH_THUMBNAIL : WIDTH_FULL;
		h = thumb ? HEIGHT_THUMBNAIL : HEIGHT_FULL;
		this.setSize( new Dimension(w,h) );
		this.setPreferredSize( new Dimension(w,h) );
		this.setOpaque( false );
		this.setLayout( new BorderLayout() );
		this.addMouseListener( this );
		this.setToolTipText( "Alterar logotipo " );
		fill( null );
	}
	
	public void fill( Object object )
	{
		byte[] array = (byte[]) object;
		image = null;
		scaledImage = null;
		try
		{
			if( array != null )
			{
				ByteArrayInputStream input = new ByteArrayInputStream( array );
				scaledImage = ImageIO.read( input );
				input = new ByteArrayInputStream( array );
				image = ImageIO.read( input );
			}
		} catch( IOException e )
		{
			e.printStackTrace();
		}
		refresh();
	}
	
	private void changeImage( File file )
	{
		image = null;
		scaledImage = null;
		try
		{
			if( file != null && file.exists() )
			{
				scaledImage = ImageIO.read( file );
				image = ImageIO.read( file );
			}
		} catch( IOException e )
		{
			e.printStackTrace();
		}
		refresh();
	}
	
	private void scaleImage()
	{
		if( scaledImage != null )
		{
			this.setBorder( BorderFactory.createEmptyBorder() );
			if( scaledImage.getWidth() > w )
			{
				AffineTransform af = AffineTransform.getScaleInstance( ( (double) w) / ( (double) scaledImage.getWidth() ), ( (double) w ) / ( (double) scaledImage.getWidth() ) );
				AffineTransformOp afOp = new AffineTransformOp( af, AffineTransformOp.TYPE_BILINEAR );
				scaledImage = afOp.filter( scaledImage, null );
			}
			if( scaledImage.getHeight() > h )
			{
				AffineTransform af = AffineTransform.getScaleInstance( ( (double) h) / ( (double) scaledImage.getHeight() ), ( (double) h ) / ( (double) scaledImage.getHeight() ) );
				AffineTransformOp afOp = new AffineTransformOp( af, AffineTransformOp.TYPE_BILINEAR );
				scaledImage = afOp.filter( scaledImage, null );
			}
		}
		else
		{
			this.setBorder( BorderFactory.createLineBorder( Color.GRAY, 1 ) );
		}
	}
	
	private void refresh()
	{
		scaleImage();
		repaint();
	}
	
	@Override
	public boolean imageUpdate( Image img, int infoflags, int x, int y, int w, int h )
	{
		boolean loaded = !imageUpdate( img, infoflags, x, y, w, h );
		if( !loaded )
		{
			refresh();
		}
		return !loaded;
	}
	
	@Override
	protected void paintComponent( Graphics g )
	{
		super.paintComponent( g );
		if( scaledImage != null )
		{
			int shiftX = ( w - scaledImage.getWidth() ) / 2;
			int shiftY = ( h - scaledImage.getHeight() ) / 2;
			g.drawImage( scaledImage, 0 + shiftX, 0 + shiftY, w - shiftX, h - shiftY, this );
		}
	}

	@Override
	public void mouseClicked( MouseEvent e )
	{
		if( this.isEnabled() )
		{
			JFileChooser fc = new JFileChooser();
			int returned = fc.showOpenDialog( this );
			if( JFileChooser.APPROVE_OPTION == returned )
			{
				changeImage( fc.getSelectedFile() );
			}
			
		}
	}

	@Override
	public void mouseEntered( MouseEvent e )
	{
		this.setCursor( new Cursor( Cursor.HAND_CURSOR ) );
	}

	@Override
	public void mouseExited( MouseEvent e )
	{
		this.setCursor( new Cursor( Cursor.DEFAULT_CURSOR ) );
	}

	@Override
	public void mousePressed( MouseEvent e )
	{
	}

	@Override
	public void mouseReleased( MouseEvent e )
	{
	}

	@Override
	public void clear()
	{
		fill( null );
	}

	@Override
	public Object save()
	{
		byte [] result = null;
		try
		{
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			ImageIO.write( image, "PNG", out );
			result = out.toByteArray();
		}
		catch( IOException e )
		{
			e.printStackTrace();
		}
		return result;
	}
	
}
