package net.psammead.commonist.ui;

import java.awt.*;
import java.awt.event.*;
import java.io.*;

import javax.swing.*;

import net.psammead.commonist.*;
import net.psammead.commonist.data.*;
import net.psammead.commonist.util.*;
import net.psammead.util.ui.*;

/** a data editor with a thumbnail preview for an image File */
public class ImageUI extends JPanel {
	/** action events this UI sends */
	public interface Callback {
		void updateSelectStatus();
	}
	
	// components
	private JTextField	nameEditor;
	private JTextArea	descriptionEditor;
	private JTextField	categoriesEditor;
	private JCheckBox	uploadEditor;
	
	// state
	private File	file;
	private String	programHeading;
	private Image	programIcon;
	
	/** the icon may be null for no thumbnail */
	public ImageUI(File file, Icon icon, int thumbnailMaxSize, String programHeading, Image programIcon, final Callback callback) {
		this.file	= file;
		
		this.programHeading	= programHeading;
		this.programIcon	= programIcon;
		
		Dimension	thumbDimension	= new Dimension(thumbnailMaxSize, thumbnailMaxSize);

		//------------------------------------------------------------------------------
		
		JLabel imageView	= new JLabel(null, null, JLabel.CENTER);
		imageView.setBackground(Color.decode("#eeeeee"));
//		imageView.setBorder(
//			BorderFactory.createBevelBorder(BevelBorder.RAISED)
//		);
		imageView.setOpaque(true);
		/*### fehlt
		imageView.setToolTipText(
			file.Name + " (" + TextUtil.human(file.length()) + " bytes)"
		);
		*/
		imageView.setHorizontalTextPosition(JLabel.CENTER);
		imageView.setVerticalTextPosition(JLabel.CENTER);
		imageView.setPreferredSize(thumbDimension);
		imageView.setMinimumSize(thumbDimension);
		imageView.setMaximumSize(thumbDimension);
	
		JLabel nameLabel		= new JLabel(Messages.text("image.name"));
		JLabel descriptionLabel	= new JLabel(Messages.text("image.description"));
		JLabel categoriesLabel	= new JLabel(Messages.text("image.categories"));
		JLabel uploadLabel		= new JLabel(Messages.text("image.upload"));
	
		nameEditor			= new JTextField(Constants.INPUT_FIELD_WIDTH);
		descriptionEditor	= new JTextArea(Constants.INPUT_FIELD_HEIGHT, Constants.INPUT_FIELD_WIDTH);
		categoriesEditor	= new JTextField(Constants.INPUT_FIELD_WIDTH);
		uploadEditor		= new JCheckBox((Icon)null, false);
		
		descriptionEditor.setLineWrap(true);
		descriptionEditor.setWrapStyleWord(true);
		
		JScrollPane descriptionScroll	= new JScrollPane(descriptionEditor, 
				JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
		
		categoriesEditor.setToolTipText(Messages.text("image.categories.tooltip"));
	
//		setBorder(
//			BorderFactory.createCompoundBorder(
//				//BorderFactory.createCompoundBorder(
//					BorderFactory.createRaisedBevelBorder(),
//				//	BorderFactory.createLoweredBevelBorder()
//				//),
//				BorderFactory.createEmptyBorder(2,0,2,0)
//			)
//		);
		setBorder(BorderFactory.createEmptyBorder(2,0,5,0));
	
		//------------------------------------------------------------------------------
		//## layout
		
		setLayout(new GridBagLayout());
		
		// labels and editors
		
		add(uploadLabel,		new GridBagConstraints2().pos(0,0).size(1,1).weight(0,0).anchorEast().fillNone().insets(0,4,0,4));
		add(uploadEditor,		new GridBagConstraints2().pos(1,0).size(1,1).weight(1,0).anchorWest().fillHorizontal().insets(0,0,0,0));			
		
		add(nameLabel,			new GridBagConstraints2().pos(0,1).size(1,1).weight(0,0).anchorEast().fillNone().insets(0,4,0,4));
		add(nameEditor,			new GridBagConstraints2().pos(1,1).size(1,1).weight(1,0).anchorWest().fillHorizontal().insets(0,0,0,0));
		
		add(descriptionLabel, 	new GridBagConstraints2().pos(0,2).size(1,1).weight(0,0).anchorNorthEast().fillNone().insets(0,4,0,4));
		add(descriptionScroll,	new GridBagConstraints2().pos(1,2).size(1,1).weight(1,1).anchorWest().fillBoth().insets(0,0,0,0));
		
		add(categoriesLabel,	new GridBagConstraints2().pos(0,3).size(1,1).weight(0,0).anchorEast().fillNone().insets(0,4,0,4));
		add(categoriesEditor,	new GridBagConstraints2().pos(1,3).size(1,1).weight(1,0).anchorWest().fillHorizontal().insets(0,0,0,0));
		
		// image
		add(imageView,			new GridBagConstraints2().pos(2,0).size(1,4).weight(0,0).anchorSouthWest().fillNone().insets(0,4,0,4));
		
		//------------------------------------------------------------------------------
		//## wiring
		
		// update select status on upload checkbox changes
		uploadEditor.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent ev) {
				callback.updateSelectStatus();
			}
		});
		
		// open full size view on click
		imageView.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent ev) {
				// LMB only
				if ((ev.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) == 0)	return;
				//if (imageView.Icon != null)
				displayFullImage();
			}
		});
		
		//------------------------------------------------------------------------------
		//## init
		
		imageView.setToolTipText(Messages.message("image.tooltip", new Object[] { file.getName(), TextUtil.human(file.length()) }));
		imageView.setIcon(icon);
		imageView.setText(icon == null ? Messages.text("image.nothumb") : null);
		
		nameEditor.setText(fixImageName(file.getName()));
		descriptionEditor.setText("");
		categoriesEditor.setText("");
		uploadEditor.setSelected(false);
	}
	
	@Override
	public Dimension getMaximumSize() {
		return new Dimension(
			super.getMaximumSize().width,
			super.getPreferredSize().height
		);
	}

	/** returns true when this file should be uploaded */
	public boolean isUploadSelected() {
		return uploadEditor.isSelected();
	}
	
	/** sets whether this file should be uploaded */
	public void setUploadSelected(boolean selected) {
		uploadEditor.setSelected(selected);
	}
	
	/** gets all data edit in this UI */
	public ImageData getData() {
		return new ImageData(
				file,
				fixImageName(nameEditor.getText()),
				descriptionEditor.getText(),
				categoriesEditor.getText(),
				uploadEditor.isSelected());
	}
	
	private void displayFullImage() {
		FullImageWindow.display(file, programHeading, programIcon);
	}
	
	/** trims a String and changes its first letter to upper case */
	private String fixImageName(String imageName) {
		// spaces at the start or end of filenames are not allowed
		String	str	= imageName.trim();
		if (str.length() < 1)	return str;
		StringBuilder	b	= new StringBuilder(str);
		b.setCharAt(0, Character.toUpperCase(str.charAt(0)));
		return b.toString();
	}
}
