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

import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.ButtonGroup;
import javax.swing.DefaultListModel;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.ListCellRenderer;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.filechooser.FileFilter;

import lu.tudor.santec.gecamed.core.ejb.entity.beans.Autocompletion;
import lu.tudor.santec.gecamed.core.ejb.session.beans.AutocompletionBean;
import lu.tudor.santec.gecamed.core.ejb.session.interfaces.AutocompletionInterface;
import lu.tudor.santec.gecamed.core.gui.GECAMedColors;
import lu.tudor.santec.gecamed.core.gui.GECAMedModule;
import lu.tudor.santec.gecamed.core.gui.MainFrame;
import lu.tudor.santec.gecamed.core.gui.widgets.GECAMedBaseDialogImpl;
import lu.tudor.santec.gecamed.core.gui.widgets.KeepSelectionHandler;
import lu.tudor.santec.gecamed.core.utils.ManagerFactory;
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;
import com.l2fprod.common.swing.JLinkButton;

public class AutoCompletionExportDialog extends GECAMedBaseDialogImpl implements ListSelectionListener
{
	/* ======================================== */
	// 		CONSTANTS
	/* ======================================== */
	
	/** the logger Object for this class */
	private static Logger logger = Logger.getLogger(AutoCompletionExportDialog.class.getName());
	
	private static final long serialVersionUID = 1L;
	
	private static final int EXPORT_INVALID = -1;
	private static final int EXPORT_ALL 	= 0;
	private static final int EXPORT_PUBLIC 	= 1;
	private static final int EXPORT_USER 	= 2;
	
	private static final String COLUMN_FORMAT 		= "5px, f:p:g, 5px";
	private static final String ROW_FORMAT 			= " 5px, f:p, " +
													  "10px, f:p, " +
													  " 5px, f:p, " +
													  " 5px, f:p, " +
													  "10px, f:200px:g, " +
													  " 0px, f:p, " +
													  " 5px";
	private static final String BUTTON_PANEL_FORMAT = "f:p,10px:g,f:p";
	
	
	/* ======================================== */
	// 		MEMBERS
	/* ======================================== */
	
	private static JFileChooser fileChooser = new JFileChooser();
	static 
	{
		fileChooser.setFileFilter(new FileFilter()
		{
			@Override
			public String getDescription()
			{
				return ".xml";
			}
			
			@Override
			public boolean accept(File f)
			{
				return f.isDirectory() || f.getName().endsWith(".xml");
			}
		});
	}
	
	private static ListCellRenderer cellRenderer = new ListCellRenderer()
	{
		public Component getListCellRendererComponent(JList list, Object value,
				int index, boolean isSelected, boolean cellHasFocus)
		{
			JLabel cell = new JLabel((String) value);
			cell.setOpaque(true);
			
			Color bg;
			if (isSelected)
				bg = list.getSelectionBackground();
			else if (index % 2 == 0)
				bg = GECAMedColors.c_EvenLineBackground;
			else 
				bg = GECAMedColors.c_OddLineBackground;
			cell.setBackground(bg);
			
			return cell;
		}
	};
	
	private int 				exportSelection = EXPORT_INVALID;
	
	private ButtonGroup 		exportBoxes;
	private JRadioButton 		allCompletionsBox;
	private JRadioButton 		publicCompletionsBox;
	private JRadioButton 		userAndPublicCompletionsBox;
	
	private JList 				contextList;
	private DefaultListModel 	contextListModel;
	
	
	
	/* ======================================== */
	// 		CONSTRUCTOR
	/* ======================================== */
	
	public AutoCompletionExportDialog()
	{
		super(MainFrame.getInstance(), 
				Translatrix.getTranslationString("MultiWordAutoCompletion.IO.exportAutocompletions"), 
				OK_CANCEL_BUTTON_MODE);
		
		CellConstraints cc = new CellConstraints();
		
		
		/* ---------------------------------------- */
		// 		DESCRIPTION
		/* ---------------------------------------- */
		
		JLabel description = new JLabel(
				Translatrix.getTranslationString("MultiWordAutoCompletion.IO.exportDescription"));
		description.setOpaque(false);
		
		
		/* ---------------------------------------- */
		// 		RADIO BUTTONS
		/* ---------------------------------------- */
		
		allCompletionsBox = new JRadioButton(new AbstractAction(
				Translatrix.getTranslationString("MultiWordAutoCompletion.IO.exportAll"))
		{
			private static final long serialVersionUID = 1L;

			public void actionPerformed (ActionEvent e)
			{
				exportSelection = EXPORT_ALL;
				selectionChanged();
			}
		});
		allCompletionsBox.setOpaque(false);
		
		publicCompletionsBox = new JRadioButton(new AbstractAction(
				Translatrix.getTranslationString("MultiWordAutoCompletion.IO.exportPublic"))
		{
			private static final long serialVersionUID = 1L;

			public void actionPerformed (ActionEvent e)
			{
				exportSelection = EXPORT_PUBLIC;
				selectionChanged();
			}
		});
		publicCompletionsBox.setOpaque(false);
		
		userAndPublicCompletionsBox = new JRadioButton(new AbstractAction(
				Translatrix.getTranslationString("MultiWordAutoCompletion.IO.exportUser"))
		{
			private static final long serialVersionUID = 1L;

			public void actionPerformed (ActionEvent e)
			{
				exportSelection = EXPORT_USER;
				selectionChanged();
			}
		});
		userAndPublicCompletionsBox.setOpaque(false);

		exportBoxes = new ButtonGroup();
		exportBoxes.add(allCompletionsBox);
		exportBoxes.add(publicCompletionsBox);
		exportBoxes.add(userAndPublicCompletionsBox);
		
		
		/* ---------------------------------------- */
		// 		CONTEXT LIST
		/* ---------------------------------------- */
		
		contextListModel 	= new DefaultListModel();
		contextList 		= new JList(contextListModel);
		contextList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
		contextList.setCellRenderer(cellRenderer);
		contextList.addListSelectionListener(this);
		KeepSelectionHandler.keepSelection(contextList);
		
		JScrollPane listScroller = new JScrollPane(contextList);
		listScroller.setOpaque(false);
		
		JLinkButton selectAllButton = new JLinkButton(new AbstractAction(
				Translatrix.getTranslationString("core.selectAll"))
		{
			private static final long serialVersionUID = 1L;

			public void actionPerformed(ActionEvent e)
			{
				int size = contextList.getModel().getSize();
				if (size > 0)
					contextList.setSelectionInterval(0, size-1);
			}
		});
		selectAllButton.setOpaque(false);
		
		JLinkButton deselectAllButton = new JLinkButton(new AbstractAction(
				Translatrix.getTranslationString("core.selectNone"))
		{
			private static final long serialVersionUID = 1L;

			public void actionPerformed(ActionEvent e)
			{
				contextList.clearSelection();
			}
		});
		deselectAllButton.setOpaque(false);
		
		FormLayout 	selectButtonsLayout = new FormLayout(BUTTON_PANEL_FORMAT);
		JPanel 		selectButtonsPanel 	= new JPanel(selectButtonsLayout);
		selectButtonsLayout.appendRow(new RowSpec(Sizes.PREFERRED));
		selectButtonsPanel.setOpaque(false);
		selectButtonsPanel.add(selectAllButton, 	cc.xy(1, 1));
		selectButtonsPanel.add(deselectAllButton, 	cc.xy(3, 1));
		
		
		/* ---------------------------------------- */
		// 		DEFINE THE MAIN PANEL
		/* ---------------------------------------- */
		
		mainPanel.setLayout(new FormLayout(COLUMN_FORMAT, ROW_FORMAT));
		
		int row = 0;
		mainPanel.add(description, 					cc.xy(2, row+=2));
		mainPanel.add(allCompletionsBox, 			cc.xy(2, row+=2));
		mainPanel.add(publicCompletionsBox, 		cc.xy(2, row+=2));
		mainPanel.add(userAndPublicCompletionsBox, 	cc.xy(2, row+=2));
		mainPanel.add(listScroller, 				cc.xy(2, row+=2));
		mainPanel.add(selectButtonsPanel, 			cc.xy(2, row+=2));
	}
	
	
	
	/* ======================================== */
	// 		METHODS
	/* ======================================== */
	
	private void refresh ()
	{
		if (allCompletionsBox.isSelected())
			exportSelection = EXPORT_ALL;
		else if (publicCompletionsBox.isSelected())
			exportSelection = EXPORT_PUBLIC;
		else if (userAndPublicCompletionsBox.isSelected())
			exportSelection = EXPORT_USER;
		else 
			exportSelection = EXPORT_INVALID;
		
		AutocompletionInterface manager = (AutocompletionInterface) ManagerFactory.getRemote(AutocompletionBean.class);
		List<String> completions = manager.getContexts();
		
		contextListModel.clear();
		for (String context : completions)
			contextListModel.addElement(context);
		
		selectionChanged();
		
		this.pack();
		this.setLocationRelativeTo(getOwner());
	}
	
	
	private void selectionChanged ()
	{
		if (contextList.getSelectedIndex() >= 0
				&& exportSelection != EXPORT_INVALID)
			 okButton.setEnabled(true);
		else okButton.setEnabled(false);
	}
	
	
	@Override
	public void setVisible(boolean b)
	{
		if (b)
			refresh();
		super.setVisible(b);
	}
	
	
	@Override
	public void okActionCalled()
	{
		AutocompletionInterface manager = (AutocompletionInterface) ManagerFactory.getRemote(AutocompletionBean.class);
		Object[] selectedContexts = contextList.getSelectedValues();
		
		List<Autocompletion> completions = new LinkedList<Autocompletion>();
		switch (exportSelection)
		{
		case EXPORT_ALL:
			for (Object context : selectedContexts)
				completions.addAll(manager.getCompletions((String) context));
			break;

		case EXPORT_PUBLIC:
			for (Object context : selectedContexts)
				completions.addAll(manager.getCompletions((String) context, null));
			break;

		case EXPORT_USER:
			int userId = GECAMedModule.getCurrentUser().getId();
			for (Object context : selectedContexts)
				completions.addAll(manager.getCompletions((String) context, userId));
			break;

		default:
			return;
		}
		
		if (fileChooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION)
		{
			try
			{
				File file = fileChooser.getSelectedFile();
				if (!file.exists())
						file.createNewFile();
				
				if (AutoCompletionIOManager.exportCompletions(completions, file))
					super.okActionCalled();
			} 
			catch (IOException e)
			{
				logger.log(Level.ERROR, e.getMessage(), e);
			}
		}
	}
	
	
	public void valueChanged(ListSelectionEvent e)
	{
		selectionChanged();
	}
}