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 implements UI {
	/** action events this UI sends */
	public interface Callback {
		void updateSelectStatus();
	}
	
	// components
	private JPanel		panel;
	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, String programHeading, Image programIcon, final Callback callback) {
		this.file	= file;
		
		this.programHeading	= programHeading;
		this.programIcon	= programIcon;
		
		Dimension	thumbDimension	= new Dimension(
				Constants.THUMBNAIL_SIZE, 
				Constants.THUMBNAIL_SIZE); 

		//------------------------------------------------------------------------------
		
		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);
		
		// hack, but works: no longer necessary with the scrollPane
		//descriptionEditor.setBorder(nameEditor.getBorder());	
		descriptionEditor.setBorder(null);
		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"));
	
		JPanel filler	= new JPanel();
		filler.setPreferredSize(new Dimension(0,0));
		
		panel	= new GridBagPanel() {
			public Dimension getMaximumSize() {
				return new Dimension(
					super.getMaximumSize().width,
					super.getPreferredSize().height
				);
			}
		};
//		panel.setBorder(
//			BorderFactory.createCompoundBorder(
//				//BorderFactory.createCompoundBorder(
//					BorderFactory.createRaisedBevelBorder(),
//				//	BorderFactory.createLoweredBevelBorder()
//				//),
//				BorderFactory.createEmptyBorder(2,0,2,0)
//			)
//		);
		panel.setBorder(BorderFactory.createEmptyBorder(2,0,5,0));
	
		//------------------------------------------------------------------------------
		//## layout
		
		// filler
		panel.add(filler, "at 0/0 size 2/1 weight 0/0.5 anchor center fill vertical insets 0/0/0/0");
		
		// labels and editors
		
		panel.add(uploadLabel,			"at 0/1 size 1/1 weight 0/0 anchor east fill none insets 0/4/0/4");
		panel.add(uploadEditor,			"at 1/1 size 1/1 weight 0/0 anchor west fill horizontal insets 0/0/0/0");
		
		panel.add(nameLabel,			"at 0/2 size 1/1 weight 0/0 anchor east fill none insets 0/4/0/4");
		panel.add(nameEditor,			"at 1/2 size 1/1 weight 0/0 anchor west fill horizontal insets 0/0/0/0");
		
		panel.add(descriptionLabel, 	"at 0/3 size 1/1 weight 0/0 anchor northeast fill none insets 0/4/0/4");
		panel.add(descriptionScroll,	"at 1/3 size 1/1 weight 0/0 anchor west fill horizontal insets 0/0/0/0");
		
		panel.add(categoriesLabel,		"at 0/4 size 1/1 weight 0/0 anchor east fill none insets 0/4/0/4");
		panel.add(categoriesEditor,		"at 1/4 size 1/1 weight 0/0 anchor west fill horizontal insets 0/0/0/0");
		
		// image
		panel.add(imageView,			"at 2/0 size 1/5 weight 1/1 anchor southwest fill none 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() {
			public void mouseClicked(MouseEvent ev) {
				//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);
	}
	
	/** UI: returns the JComponent this UI controls */
	public JComponent getComponent() {
		return panel;
	}

	/** 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();
	}
}
