package lu.tudor.santec.gecamed.formeditor.gui.component;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.io.FileInputStream;

import javax.swing.AbstractAction;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JToggleButton;
import javax.swing.filechooser.FileFilter;
import javax.swing.text.JTextComponent;

import lu.tudor.santec.gecamed.core.gui.GECAMedIconNames;
import lu.tudor.santec.gecamed.core.gui.GECAMedModule;
import lu.tudor.santec.gecamed.core.gui.IconFetcher;
import lu.tudor.santec.gecamed.core.gui.widgets.FileChooserPreview;
import lu.tudor.santec.gecamed.core.gui.widgets.NamedComponent;
import lu.tudor.santec.gecamed.formeditor.gui.FormEditorModule;
import lu.tudor.santec.i18n.Translatrix;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;

import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.forms.layout.RowSpec;
import com.jgoodies.forms.layout.Sizes;

public class DefaultOptionPanel extends SettingsBasePanel
{
	private static final long serialVersionUID = 1L;
	
	private static final RowSpec TEXT_AREA_ROWSPEC = new RowSpec(RowSpec.FILL, Sizes.dluY(50), RowSpec.NO_GROW);
	
	
	/* ======================================== */
	// 		MEMBERS
	/* ======================================== */
	
	/** the logger Object for this class */
	private static Logger logger = Logger.getLogger(DefaultOptionPanel.class.getName());
	
	protected static JFileChooser 	fileChooser;
	protected static FileFilter 	imageFileFilter;
	
	
	/* ---------------------------------------- */
	// 		COMPONENTS
	/* ---------------------------------------- */
	
	// named components
	protected NamedComponent captionTextComponent;
	
	
	/* ---------------------------------------- */
	// 		PIC PANEL COMPONENTS
	/* ---------------------------------------- */
	
	protected JPanel 		picPanel;
	
	// text fields
	protected JComponent 	captionText;
	protected NumericField 	scaleHeightField;
	protected NumericField 	scaleWidthField;
	
	// buttons
	protected JButton 		chooseImageButton;
	protected JButton 		unloadImageButton;
	
	
	
	/* ======================================== */
	// 		CONSTRUCTOR
	/* ======================================== */
	
	public DefaultOptionPanel(EditableComponent editableComponent)
	{
		super(editableComponent);
	}
	
	
	
	@Override
	protected void init ()
	{
		// start value
		captionText = editableComponent.createCaptionText();
		captionText.addKeyListener(new KeyListener() {
			
			public void keyTyped(KeyEvent e) {}
			public void keyPressed(KeyEvent e) {}
			
			public void keyReleased(KeyEvent e) {
				if (captionText instanceof JTextComponent) {
					editableComponent.setText(((JTextComponent)captionText).getText());
				}
			}
		});
		if (captionText instanceof JTextComponent) {
			((JTextComponent)captionText).setText(editableComponent.getText());
		}
		
		JComponent c;
		RowSpec spec;
		if (captionText instanceof JTextArea)
		{
			c = new JScrollPane(captionText);
			spec = TEXT_AREA_ROWSPEC;
		}
		else
		{
			c = captionText;
			spec = DEFAULT_ROW_SPEC;
		}
		
		captionTextComponent = new NamedComponent(
				Translatrix.getTranslationString("formeditor.start_value"), 
				c, true);
		appendRow(captionTextComponent, spec);
		
		// image icon
		if (editableComponent.iconEnabled) 
		{
			picPanel = createPicPanel();
			appendRow(picPanel);
		}
	}
	
	
	
	/* ======================================== */
	// 		HELP METHODS
	/* ======================================== */
	
	protected JPanel createPicPanel () 
	{
		final JComponent component 	= editableComponent.getComponentForOptions();
		final byte[] 	 imgData 	= editableComponent.imgData;
		
		int scaleHeight = editableComponent.getScaleHeight();
		int scaleWidth 	= editableComponent.getScaleWidth();
		
		// ADD THE PANEL TO CONFIG THE IMAGE
		JPanel picPanel = new JPanel(new FormLayout("0px, 16px, 4px, 65px, 5px, 65px, 0px", "2dlu, p, 2dlu, p"));
		picPanel.setOpaque(false);
		
		CellConstraints cc = new CellConstraints();
		
		chooseImageButton = new JButton(new AbstractAction(
				Translatrix.getTranslationString("formeditor.choose_image")) 
		{
			private static final long serialVersionUID = 1L;

			public void actionPerformed(ActionEvent e) 
			{
				chooseImage();
			}
		});
		
		unloadImageButton = new JButton(new AbstractAction("",
				GECAMedModule.getSmallIcon(GECAMedIconNames.CANCEL)) {
			private static final long serialVersionUID = 1L;

			public void actionPerformed(ActionEvent e) 
			{
				editableComponent.setImage(null);
				editableComponent.imgData = null;
				editableComponent.setImage(null);
				unloadImageButton.setEnabled(false);
			}
		});
		unloadImageButton.setEnabled(imgData != null);
		
		JPanel loadPicPanel = new JPanel(new FormLayout("32px, 5px, p:g", "c:32px"));
		loadPicPanel.setOpaque(false);
		loadPicPanel.add(unloadImageButton, cc.xy(1, 1));
		loadPicPanel.add(chooseImageButton, cc.xy(3, 1));
		
		picPanel.add(loadPicPanel, cc.xywh(1, 2, 6, 1));
		
		JToggleButton scaleSmoothButton = new JToggleButton(new AbstractAction("",
				IconFetcher.getScaledIcon(FormEditorModule.class, "decrypted.png", 16)) 
		{
			private static final long serialVersionUID = 1L;

			public void actionPerformed(ActionEvent e) 
			{
				editableComponent.scaleSmooth = ((JToggleButton)e.getSource()).isSelected();
			}
		});
		scaleSmoothButton.setSelected(true);
		editableComponent.scaleSmooth = scaleSmoothButton.isSelected();
		picPanel.add(scaleSmoothButton, cc.xy(2, 4));
		
		scaleWidthField = new NumericField(String.valueOf(scaleWidth));
		scaleWidthField.setEnabled(imgData != null);
		scaleWidthField.addKeyListener(new KeyListener() 
		{
			public void keyReleased(KeyEvent e) 
			{
				scale(true, component);
			}
			
			public void keyPressed(KeyEvent e) {}
			public void keyTyped(KeyEvent e) {}
		});
		picPanel.add(new NamedComponent(
				Translatrix.getTranslationString("formeditor.width"), 
				scaleWidthField), cc.xy(4, 4));
		
		scaleHeightField = new NumericField(String.valueOf(scaleHeight));
		scaleHeightField.setEnabled(imgData != null);
		scaleHeightField.addKeyListener(new KeyListener() 
		{
			public void keyReleased(KeyEvent e) 
			{
				scale(false, component);
//				int 	scaleHeight = editableComponent.getScaleHeight();
//				int 	scaleWidth 	= editableComponent.getScaleWidth();
//				boolean scaleSmooth = editableComponent.scaleSmooth;
//				
//				NumericField tf = (NumericField) e.getSource();
//				int newHeight = (int) tf.getValue();
//				
//				if (newHeight > 0 
//						&& scaleHeight != newHeight) 
//				{
//					if (scaleSmooth) 
//					{
//						/* **********  SCALE THE WIDTH  ********** */
//						scaleWidth = (int) (editableComponent.getImage().getIconWidth() * (tf.getValue() 
//								/ editableComponent.getImage().getIconHeight()));
//						scaleWidthField.setText(String.valueOf(scaleWidth));
//						/* **************************************** */
//					}
//					scaleHeight = newHeight;
//					
//					tf.setBackground(scaleHeight > EditableComponent.MAX_SCALING ? 
//							FormEditorModule.MARK_WRONG_COLOR : Color.WHITE);
//					
//					if (scaleWidth > EditableComponent.MAX_SCALING
//							|| scaleHeight > EditableComponent.MAX_SCALING) {
//						return;
//					}
//					component.repaint();
//				}
			}

			public void keyPressed(KeyEvent e) {}
			public void keyTyped(KeyEvent e) {}
		});
		picPanel.add(new NamedComponent(
				Translatrix.getTranslationString("formeditor.height"), 
				scaleHeightField), cc.xy(6, 4));
		
		
		return picPanel;
	}
	
	
	protected void chooseImage ()
	{
		File f = chooseImageFile();
		if (f != null && f.exists()) 
		{
			try 
			{
				editableComponent.imgData 		= new byte[(int) f.length()];
				FileInputStream fis = new FileInputStream(f);
				fis.read(editableComponent.imgData);
				fis.close();
				
				// create a new icon using the image data
				editableComponent.setImage(new ImageIcon(editableComponent.imgData));
				
				editableComponent.setScaleWidth(editableComponent.getImage().getIconWidth());
				editableComponent.setScaleHeight(editableComponent.getImage().getIconHeight());
				
				scaleWidthField.setEnabled(true);
				scaleWidthField.setText(String.valueOf(editableComponent.getScaleWidth()));
				scaleHeightField.setEnabled(true);
				scaleHeightField.setText(String.valueOf(editableComponent.getScaleHeight()));
				
//				editableComponent.setIcon(editableComponent.icon);
				editableComponent.repaint();
				unloadImageButton.setEnabled(true);
			} 
			catch (Exception ex) 
			{
				logger.log(Level.ERROR, ex.getMessage(), ex);
			}
		}
	}

	
	protected File chooseImageFile () 
	{
		if (fileChooser == null) 
		{
			fileChooser = new JFileChooser();
		}
		
		fileChooser.setAccessory(new FileChooserPreview(fileChooser));
		
		if (imageFileFilter == null) 
		{
			imageFileFilter = new FileFilter() 
			{
				@Override
				public String getDescription() 
				{
					return ".bmp, .png, .jpg, .gif, .xbm";
				}				
				@Override
				public boolean accept(File f) 
				{
					return f.isDirectory()
							|| f.getName().endsWith(".png")
							|| f.getName().endsWith(".jpg")
							|| f.getName().endsWith(".jpeg")
							|| f.getName().endsWith(".gif")
							|| f.getName().endsWith(".xbm");
				}
			};
		}
		
		fileChooser.setFileFilter(imageFileFilter);
		
		File file = chooseFile();
		fileChooser.setAccessory(null);
		
		return file;
	}
	
	
	protected File chooseFile () 
	{
		if (fileChooser == null) 
		{
			fileChooser = new JFileChooser();
		}
		int button = fileChooser.showOpenDialog(editableComponent.model.getView());
		
		if (button == JFileChooser.APPROVE_OPTION) 
		{
			File file = fileChooser.getSelectedFile();
			fileChooser.setFileFilter(null);
			
			return file;
		} 
		else 
		{
			return null;
		}
	}
	
	
	private void scale (boolean widthChanged, JComponent component)
	{
		int 			scaleHeight = editableComponent.getScaleHeight();
		int 			scaleWidth 	= editableComponent.getScaleWidth();
		boolean 		scaleSmooth = editableComponent.scaleSmooth;
		int 			newValue;
		int 			oldValue;
		int 			orgWidth;
		int 			orgHeight;
		NumericField 	textField;
		
		if (widthChanged)
		{
			textField 	= scaleWidthField;
			oldValue 	= scaleWidth;
		}
		else 
		{
			textField 	= scaleHeightField;
			oldValue 	= scaleHeight;
		}
		newValue = textField.getInt();
		
		if (newValue > 0 && oldValue != newValue)
		{
			orgWidth 	= editableComponent.getImage().getIconWidth();
			orgHeight	= editableComponent.getImage().getIconHeight();
			
			if (widthChanged)
			{
				if (scaleSmooth) 
				{
					scaleHeight = (int) ((double)orgHeight * ((double)newValue / (double)orgWidth));
					scaleHeightField.setText(String.valueOf(scaleHeight));
				}
				scaleWidth = newValue;
			}
			else
			{
				if (scaleSmooth) 
				{
					scaleWidth = (int) ((double)orgWidth * ((double)newValue / (double)orgHeight));
					scaleWidthField.setText(String.valueOf(scaleWidth));
				}
				scaleHeight = newValue;
			}
			
			textField.setBackground(newValue > EditableComponent.MAX_SCALING ? 
					FormEditorModule.MARK_WRONG_COLOR : Color.WHITE);
			
			if (scaleWidth > EditableComponent.MAX_SCALING
					|| scaleHeight > EditableComponent.MAX_SCALING)
				return;
			
			editableComponent.setScaleHeight(scaleHeight);
			editableComponent.setScaleWidth(scaleWidth);
			
			component.repaint();
		}
	}
	
	
	
	/* ======================================== */
	// 		GETTER & SETTER
	/* ======================================== */
	
	public static JFileChooser getFileChooser()
	{
		return fileChooser;
	}

	public static FileFilter getImageFileFilter()
	{
		return imageFileFilter;
	}

	public NamedComponent getCaptionTextComponent()
	{
		return captionTextComponent;
	}

	public JComponent getCaptionText()
	{
		return captionText;
	}

	public NumericField getScaleHeightField()
	{
		return scaleHeightField;
	}

	public NumericField getScaleWidthField()
	{
		return scaleWidthField;
	}

	public JButton getChooseImageButton()
	{
		return chooseImageButton;
	}

	public JButton getUnloadImageButton()
	{
		return unloadImageButton;
	}

	public JPanel getPicPanel()
	{
		return picPanel;
	}
}
