/*******************************************************************************
 * This file is part of GECAMed.
 * 
 * GECAMed is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License (L-GPL) as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * GECAMed is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License (L-GPL)
 * along with GECAMed.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * GECAMed is Copyrighted by the Centre de Recherche Public Henri Tudor (http://www.tudor.lu)
 * (c) CRP Henri Tudor, Luxembourg, 2008
 *******************************************************************************/
package lu.tudor.santec.gecamed.billing.gui.suffix;

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;

import javax.swing.AbstractCellEditor;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JToggleButton;
import javax.swing.SwingUtilities;
import javax.swing.event.MenuKeyEvent;
import javax.swing.event.MenuKeyListener;

import lu.tudor.santec.gecamed.billing.ejb.entity.beans.Suffix;
import lu.tudor.santec.i18n.Translatrix;

/**
 * @author nmac
 */

//***************************************************************************
//* Class Definition and Members                                            *
//***************************************************************************

public class SuffixChooser extends JPanel implements ActionListener,
													 KeyListener,
													 MenuKeyListener
    {
     
	private AbstractCellEditor	m_Editor;
	private JPopupMenu			m_Popup = null; 
	private String				m_Suffixes;
	private boolean				m_Canceled;
	
	
	private static Hashtable <Character, JToggleButton> m_SuffixLookup = null;
     
	private static final long serialVersionUID = 1L;
 	
//***************************************************************************
//* Constructor(s)                                                          *
//***************************************************************************

public SuffixChooser (AbstractCellEditor p_Editor, Collection <Suffix> p_Suffixes) 
    {
	this.setLayout(new GridLayout(0, getColumnsForSuffixes(p_Suffixes.size())));
		
	m_Editor = p_Editor;
	if (m_SuffixLookup == null) m_SuffixLookup = new Hashtable <Character, JToggleButton> ();
	
	populateSuffixChooser (p_Suffixes);
    
	m_Popup = new JPopupMenu(); 
	m_Popup.setLightWeightPopupEnabled(true);
	m_Popup.add(this);
	m_Popup.addMenuKeyListener(this);
    }

//---------------------------------------------------------------------------

private int getColumnsForSuffixes(int size)
	{
	Double	sqrt;
	
	if (size < 5)
		return size;
	
	sqrt	= Double.valueOf(Math.sqrt(size));
	
	if (sqrt.doubleValue() % 1 == 0)
		return sqrt.intValue();
	
	for (int i = sqrt.intValue(); i > 1; i--)
	{
		if (size % i == 0)
			return size / Integer.valueOf(i);
	}
	
	return sqrt.intValue();
	}

//***************************************************************************
//* Class Primitives                                                        *
//***************************************************************************

public void updateUI() 
	{
	super.updateUI();
	setEnabled(isEnabled());

	if (m_Popup != null) SwingUtilities.updateComponentTreeUI(m_Popup);
	}

//---------------------------------------------------------------------------

public void populateSuffixChooser (Collection <Suffix> p_Suffixes)
	{
	Iterator <Suffix>	l_SuffixIterator;
	Suffix				l_Suffix;
	JToggleButton		l_Button;
	
	String				l_Letter;
	String				l_ToolTipKey;
	
	if (p_Suffixes == null) return;
	
	l_SuffixIterator = p_Suffixes.iterator();
	while (l_SuffixIterator.hasNext())		
		{
		l_Suffix = l_SuffixIterator.next();
		l_Letter = l_Suffix.getLetter().toString();
		
		l_ToolTipKey = "SuffixChooser.Suffix_" + l_Letter;
		
		l_Button = new JToggleButton (l_Letter);
		l_Button.addKeyListener (this);
		l_Button.setToolTipText(Translatrix.getTranslationString(l_ToolTipKey));
		
		this.add(l_Button);
		m_SuffixLookup.put (l_Suffix.getLetter(),l_Button);		
		}
	}

//---------------------------------------------------------------------------

private void processKeyChar (char p_Character)
	{
	switch (p_Character)    
		{
		case KeyEvent.VK_ENTER  : m_Canceled = false;
								  m_Popup.setVisible(false);
								  m_Editor.stopCellEditing();
								  break;
								
		case KeyEvent.VK_ESCAPE : m_Canceled = true;
								  m_Popup.setVisible(false);
								  m_Editor.stopCellEditing();
								  break;
		
		case KeyEvent.VK_DELETE : m_Canceled = true;
								  m_Suffixes = "";
		  						  m_Popup.setVisible(false);
		  						  m_Editor.stopCellEditing();
								  break;
		
		default	: this.toggleSuffix (p_Character);
		}							
	}

//---------------------------------------------------------------------------

//***************************************************************************
//* Class Body		                                                       *
//***************************************************************************
//---------------------------------------------------------------------------

public void setChosenSuffixes (String p_Suffixes)
	{
	char [] 				l_Suffixes;
	int						l_Index;
	Character				l_Suffix;
	
	Enumeration <Character>	l_Keys;
	JToggleButton			l_Button;
		
	l_Keys = m_SuffixLookup.keys();	
	
	while (l_Keys.hasMoreElements())
		{
		l_Suffix = l_Keys.nextElement();
		l_Button = m_SuffixLookup.get(l_Suffix);
		l_Button.setSelected(false);
		}

	if (p_Suffixes == null) return;
	
	m_Suffixes = p_Suffixes;
	l_Suffixes = m_Suffixes.toCharArray();
	
	for (l_Index = 0; l_Index < l_Suffixes.length; l_Index++)
		{
		l_Suffix = Character.valueOf (l_Suffixes[l_Index]);
		if (m_SuffixLookup.containsKey(l_Suffix))
			{
			l_Button = m_SuffixLookup.get(l_Suffix);
			l_Button.setSelected(true);
			}
		}
	}

//---------------------------------------------------------------------------

public String getChosenSuffixes ()
	{
	Enumeration <Character>	l_Keys;
	Character				l_Suffix;
	JToggleButton			l_Button;
	String					l_ChosenSuffixes;
	
	if (m_Canceled) return m_Suffixes; 
	
	l_Keys = m_SuffixLookup.keys();	
	l_ChosenSuffixes = new String ();
	
	while (l_Keys.hasMoreElements())
		{
		l_Suffix = l_Keys.nextElement();
		l_Button = m_SuffixLookup.get(l_Suffix);
		if (l_Button.isSelected()) l_ChosenSuffixes += l_Suffix.toString();
		}
	
	return l_ChosenSuffixes;
	}

//---------------------------------------------------------------------------

public void actionPerformed (ActionEvent p_Event)
	{
	JButton		l_Source;
	
	if (p_Event.getSource() instanceof JButton)
		{
		l_Source = (JButton) p_Event.getSource();		
		m_Popup.show (l_Source,0,l_Source.getHeight());
		m_Canceled = false;
		}
	}

//---------------------------------------------------------------------------

public void toggleSuffix (Character p_Suffix)
	{
	Character		l_Typed;
	JToggleButton	l_Button;
	
	l_Typed = Character.toUpperCase (p_Suffix);
	if (m_SuffixLookup.containsKey (l_Typed))
		{
		l_Button = m_SuffixLookup.get (l_Typed);  
		l_Button.setSelected(!l_Button.isSelected());
		}
	}

//---------------------------------------------------------------------------

public void menuKeyPressed(MenuKeyEvent p_Event) 
	{
	if(!p_Event.isConsumed())
		{
		this.processKeyChar (p_Event.getKeyChar());    
		}	
	}

//---------------------------------------------------------------------------

public void menuKeyReleased(MenuKeyEvent p_Event) 
	{
	}

//---------------------------------------------------------------------------

public void menuKeyTyped(MenuKeyEvent p_Event) 
	{
	}

//---------------------------------------------------------------------------

public void keyPressed(KeyEvent p_Event) 
	{
	if(!p_Event.isConsumed())
		{
		this.processKeyChar (p_Event.getKeyChar());    
		}	
	}

//---------------------------------------------------------------------------

public void keyReleased(KeyEvent p_Event) 
	{
	}

//---------------------------------------------------------------------------

public void keyTyped(KeyEvent p_Event) 
	{
	}

//---------------------------------------------------------------------------

//***************************************************************************
//* End of Class                                                            *
//***************************************************************************

}

