package lu.tudor.santec.gecamed.core.gui.widgets;

import ij.plugin.BrowserLauncher;

import java.awt.Component;
import java.awt.Font;
import java.awt.Window;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.font.TextAttribute;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ScrollPaneConstants;

import lu.tudor.santec.gecamed.core.gui.GECAMedColors;
import lu.tudor.santec.gecamed.core.gui.utils.GECAMedGuiUtils;
import lu.tudor.santec.i18n.Translatrix;

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

public class GECAMedBaseDialogImpl extends GECAMedBaseDialog {

	private static final long serialVersionUID = 1L;

	private static final String NEW_LINE = System.getProperty("line.separator");
	
	protected JPanel mainPanel = new JPanel();
	
	public static final Pattern link = Pattern.compile("\\(?\\b(http://|www[.])[-A-Za-z0-9+&amp;@#/%?=~_()|!:,.;]*[-A-Za-z0-9+&amp;@#/%=~_()|]");
	
	
//	@Deprecated
//	public GECAMedBaseDialogImpl(String title) {
//		/* ================================================== */
//		super(title, false);
//		/* ================================================== */
//	}
	
	public GECAMedBaseDialogImpl (JDialog parent, String title, int buttonMode, JPanel mainPanel)
	{
		super (parent, title, buttonMode);
		init(mainPanel);
	}
	
	public GECAMedBaseDialogImpl (JFrame parent, String title, int buttonMode, JPanel mainPanel)
	{
		super (parent, title, buttonMode);
		init(mainPanel);
	}
	
	protected GECAMedBaseDialogImpl (JDialog parent, String title, int buttonMode)
	{
		super (parent, title, buttonMode);
		init(mainPanel);
	}
	
	protected GECAMedBaseDialogImpl (JFrame parent, String title, int buttonMode)
	{
		super (parent, title, buttonMode);
		init(mainPanel);
	}
	
	private void init (JPanel mainPanel)
	{
		this.mainPanel = mainPanel;
		this.mainPanel.setOpaque(false);
		super.addMainPanel(this.mainPanel);
	}
	
	
	
	
	
	public static int showMessageDialog (Component parentComponent, String title, String message, int buttonMode)
	{
		return showMessageDialog(parentComponent, title, message, buttonMode, null, false).buttonOption;
	}
	
	
	public static int showMessageDialog (Component parentComponent, String title, String message, int buttonMode, Icon icon)
	{
		return showMessageDialog(parentComponent, title, message, buttonMode, icon, false).buttonOption;
	}
	
	
	public static GECAMedBaseDialogImpl getNewInstance (Component parent, String title, int buttonMode, JPanel mainPanel)
	{
		Window					window = getParentWindow(parent);
		GECAMedBaseDialogImpl	dialog;
		
		if (mainPanel == null)
			mainPanel = new JPanel();
		
		// create the dialog
		if (window instanceof JDialog)
			dialog	= new GECAMedBaseDialogImpl((JDialog)window, title, buttonMode, mainPanel);
		else // if (window instanceof JFrame)
			dialog	= new GECAMedBaseDialogImpl((JFrame)window, title, buttonMode, mainPanel);
		dialog.setResizingOptions(RESIZING_NONE);
		
		return dialog;
	}
	
	public static ButtonOption showMessageDialog (Component parentComponent, String title, String message, 
			int buttonMode, Icon icon, boolean addApplyToAllBox)
	{
		return showMessageDialog(parentComponent, title, message, buttonMode, icon, addApplyToAllBox, null);
	}
	
	@SuppressWarnings("unchecked")
	public static ButtonOption showMessageDialog (Component parentComponent, String title, String message, 
			int buttonMode, Icon icon, boolean addApplyBox, String applyBoxMsg)
	{
		Map<TextAttribute, Object> 	attributes;
		final JLabel 				label;
		JScrollPane 				scroller;
		JPanel 						mainPanel 	= new JPanel();
		JCheckBox					applyBox;
		CellConstraints				cc 			= new CellConstraints();
		final GECAMedBaseDialogImpl dialog;
		
		// define the panel and add the message
		mainPanel.setBackground(GECAMedColors.c_GECAMedBackground);
		mainPanel.setLayout(new FormLayout(
				"10px, f:p, 5px, f:p:g, 10px",
				"10px, f:min(p; 400px):g, 10px"));
		
		// format message
		message = (message.startsWith("<html>") ? "" : "<html>") + 
				message.replaceAll("<br>"+NEW_LINE, "<br>")
				.replaceAll(NEW_LINE, "<br>");
		
		label = new JLabel(message);
		label.addMouseListener(new MouseAdapter() {

			@Override
			public void mouseClicked(MouseEvent e) {
				try {
					Matcher m = link.matcher(label.getText());
					while(m.find()) {
						String urlStr = m.group();
						try {
							if (urlStr.startsWith("(") && urlStr.endsWith(")")) {
								urlStr = urlStr.substring(1, urlStr.length() - 1);
							}
							System.out.println(urlStr);
							BrowserLauncher.openURL(urlStr);								
						} catch (Throwable e2) {
							System.out.println("Error opening url: " + urlStr);
						}
					}
				} catch (Throwable e2) {
					System.out.println("Error parsing link text: " + label.getText());
				}
			}
		});
		
		
		label.setOpaque(false);
		attributes = (Map<TextAttribute, Object>) label.getFont().getAttributes();
		attributes.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_REGULAR);
		label.setFont(new Font(attributes));
		scroller = new JScrollPane(label);
		scroller.setOpaque(false);
//		scroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
		scroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
		scroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
		scroller.getViewport().setOpaque(false);
		scroller.setBorder(BorderFactory.createEmptyBorder());
		if (icon == null)
		{
			mainPanel.add(scroller, cc.xyw(2, 2, 3));
		} 
		else
		{
			mainPanel.add(scroller, cc.xy(4, 2));
			
			JLabel iconlabel = new JLabel(icon);
			iconlabel.setOpaque(false);
			mainPanel.add(iconlabel, cc.xy(2, 2));
		}
		
		dialog = getNewInstance(parentComponent, title, buttonMode, mainPanel);
		
		// add apply (to all) check box, if true
		if (addApplyBox)
		{
			applyBox = new JCheckBox(Translatrix.getTranslationString("core.applyToAll"));
			applyBox.setOpaque(false);
			dialog.addButton(applyBox);
		}
		else
			applyBox = null;
		
		// set apply check box message
		if(applyBoxMsg != null) applyBox.setText(applyBoxMsg);
		
		// show the dialog
		dialog.setResizingOptions(RESIZING_NONE);
		dialog.pack();
//		dialog.setLocationRelativeTo(dialog.getOwner());
//		dialog.setVisible(true);
		dialog.showCenteredDialog();
//		MainFrame.showDialogCentered(dialog);
		
		
		int 	buttonOption= dialog.getButtonOption();
		boolean applyToAll 	= addApplyBox ? applyBox.isSelected() : false;
		
		return new ButtonOption(buttonOption, applyToAll);
	}
	
	public static String showInputMessageDialog (Component parentComponent, String title, String message, String startText)
	{
		JLabel 		label 		= new JLabel(message);
		JTextField 	textField 	= new JTextField(startText != null ? startText : "");
		FormLayout 	layout 		= new FormLayout("5px, f:p:g, 5px", "5px, f:p:g, 10px, f:p, 5px");
		JPanel 		mainPanel 	= new JPanel(layout);
		CellConstraints cc 		= new CellConstraints();
		
		GECAMedGuiUtils.changeFont(textField, TextAttribute.SIZE, 18);
		
		mainPanel.add(label, 		cc.xy(2, 2));
		mainPanel.add(textField, 	cc.xy(2, 4));
		
		GECAMedBaseDialogImpl dialog;
		Window owner = getParentWindow(parentComponent);
		if (owner instanceof JDialog)
			dialog = new GECAMedBaseDialogImpl((JDialog) owner, title, OK_CANCEL_BUTTON_MODE, mainPanel);
		else
			dialog = new GECAMedBaseDialogImpl((JFrame) owner, title, OK_CANCEL_BUTTON_MODE, mainPanel);
		
		dialog.pack();
		dialog.setLocationRelativeTo(owner);
		dialog.setVisible(true);
		
		String inputText;
		if (dialog.buttonOption == OK_OPTION)
			inputText = textField.getText();
		else
			inputText = null;
		
		return inputText;
	}
	
	
	public static class ButtonOption 
	{
		public int 		buttonOption;
		public boolean 	applyToAll;
		
		public ButtonOption (int buttonOption, boolean applyToAll)
		{
			this.buttonOption 	= buttonOption;
			this.applyToAll 	= applyToAll;
		}
	}
}