/*******************************************************************************
 * 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.labo.gui;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPasswordField;
import javax.swing.SwingConstants;

import lu.tudor.santec.gecamed.core.gui.GECAMedColors;
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.MainFrame;
import lu.tudor.santec.gecamed.core.gui.widgets.PasswordChangeDialog;
import lu.tudor.santec.i18n.Relocalizable;
import lu.tudor.santec.i18n.Translatrix;

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

public class PasswordDialog extends JDialog implements ActionListener,
													   ItemListener,
													   Relocalizable
	{
	/**
	 * 
	 */

	private	String			m_TitleKey;
	
	private JLabel			m_Message;
	private String			m_MessageKey;
	private String[] 		m_MessageFiller;

	private JCheckBox		m_ShowTyping;
	private JLabel			m_PasswordLabel;
	private JPasswordField	m_Password;
	private JButton			m_OkayButton;
	private JButton 		m_CancelButton;
		
	private boolean			m_Canceled;
	private boolean			m_PasswordMatched;
	private String			m_PasswordHash;
	
//---------------------------------------------------------------------------
//***************************************************************************
//* Constants	                                                            *
//***************************************************************************
//---------------------------------------------------------------------------
	
	private static final long serialVersionUID = 1L;

	private final static int  c_IconTextGap   		= 10;
	private final static char c_ClearText			 = '\u0000';
	private final static char c_EchoCharacter		 = '\u2022';

	private final static String c_Columns		= "3dlu,fill:max(50dlu;pref)," +
												  "3dlu,fill:max(50dlu;pref):grow," +
												  "3dlu,fill:max(50dlu;pref):grow,3dlu";

	private final static String c_Rows			= "3dlu,fill:pref:grow," +
	  											  "3dlu,fill:pref," +
	  											  "3dlu,fill:pref," +
	  											  "10dlu,fill:pref,3dlu";

	//=======================================================================
	//= I18N Strings
	//=======================================================================

	private final static String c_Title				= "PasswordDialog.Title";
	private final static String c_Message			= "PasswordDialog.Message";
	private final static String c_ShowTyping		= "PasswordDialog.ShowTyping";
	private final static String c_PasswordLabel		= "PasswordDialog.PasswordLabel";

//---------------------------------------------------------------------------
//***************************************************************************
//* Constructor	                                                            *
//***************************************************************************
//---------------------------------------------------------------------------

public PasswordDialog ()
	{
	super (MainFrame.getInstance(),Translatrix.getTranslationString(c_Title),true);	
	m_Canceled 		  = false;
	m_PasswordMatched = false;
	this.buildDialog();
	}
	
//---------------------------------------------------------------------------
//***************************************************************************
//* Primitives	                                                            *
//***************************************************************************
//---------------------------------------------------------------------------

private void buildDialog ()
	{
	CellConstraints	l_Constraints;
	FormLayout		l_Layout;	
	
	m_TitleKey 		= c_Title;
	m_MessageKey	= c_Message;
	m_MessageFiller = null;
		
	this.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
	this.getContentPane().setBackground(GECAMedColors.c_GECAMedBackground);

	l_Constraints  = new CellConstraints();

	l_Layout = new FormLayout(c_Columns, c_Rows);
	this.setLayout (l_Layout);
	
	m_Message 		  = new JLabel ();
	m_Message.setVerticalTextPosition(SwingConstants.TOP);
	m_Message.setHorizontalTextPosition(SwingConstants.RIGHT);
	m_Message.setIconTextGap(c_IconTextGap);
	m_Message.setIcon (IconFetcher.getIcon(IconFetcher.class,GECAMedIconNames.LOCKED));
	
	m_PasswordLabel = new JLabel ();
	
	m_ShowTyping    = new JCheckBox ();
	m_ShowTyping.setSelected(false);
	m_ShowTyping.setBackground(GECAMedColors.c_GECAMedBackground);
	m_ShowTyping.addItemListener(this);
	
	m_Password		= new JPasswordField ();
	m_Password.setEchoChar(c_EchoCharacter);
	
	m_OkayButton	= new JButton ();
	m_OkayButton.setIcon(GECAMedModule.getSmallIcon(GECAMedIconNames.OK));
	m_OkayButton.addActionListener(this);
	
	m_CancelButton	= new JButton ();
	m_CancelButton.setIcon(GECAMedModule.getSmallIcon(GECAMedIconNames.CANCEL));
	m_CancelButton.addActionListener(this);
	
	this.relocalize();
	
	this.add (m_Message,  		l_Constraints.xywh(2, 2, 5, 1));
	this.add (m_ShowTyping, 	l_Constraints.xywh(4, 4, 3, 1));
	this.add (m_PasswordLabel, 	l_Constraints.xywh(2, 6, 1, 1));
	this.add (m_Password, 		l_Constraints.xywh(4, 6, 3, 1));
	this.add (m_OkayButton,		l_Constraints.xywh(4, 8, 1, 1));
	this.add (m_CancelButton,	l_Constraints.xywh(6, 8, 1, 1));
	
	this.getRootPane().setDefaultButton (m_OkayButton);
	}
	
//---------------------------------------------------------------------------	
/**
 * returns the translation string for the specified key. If filler array
 * was specified and translation string contained placeholders, then returned
 * transaltion string will already have the placeholders replaced with values
 * specified in filler.
 * @param p_Key specifies the key of the translation string to retrieve.
 * @param p_Filler specifies the values to substitue placeholders in translation
 * string.
 * @return The translation string matchin p_Key where placeholders (if any) have
 * been replaced by values specified in p_Filler.
 */
//---------------------------------------------------------------------------	

private String getTranslationString (String p_Key, String[] p_Filler)
	{
	if (p_Filler == null)
		 return Translatrix.getTranslationString(p_Key);
	else return Translatrix.getTranslationString(p_Key,p_Filler);
	}

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

private boolean checkPassword (String p_Password)
	{
	String	l_PasswordHash;
		
	if ((m_PasswordHash == null) || (p_Password == null)) return false;
		
	try	{
		l_PasswordHash = PasswordChangeDialog.getEncodedHash (p_Password);
		}
	catch (Exception p_Exception)
		{
		l_PasswordHash = null;	
		}
		
	return m_PasswordHash.equals(l_PasswordHash);
	}

//---------------------------------------------------------------------------
//***************************************************************************
//* Class Body	                                                            *
//***************************************************************************
//---------------------------------------------------------------------------	
/**
 * sets the title of this progress dialog.
 * @param p_TitleKey specifies the key of the translation string to be used
 * as dialog title.
 */
//---------------------------------------------------------------------------	

public void setTitle (String p_TitleKey)
	{
	m_TitleKey = p_TitleKey;
	super.setTitle(Translatrix.getTranslationString(m_TitleKey));
	}

//---------------------------------------------------------------------------	
/**
 * sets the message of this progress dialog.
 * @param p_MessageKey specifies the key of the translation string to be used
 * as dialog message.
 * @param p_Filler specifies the values to be used to substitue placeholders
 * in message string . Specify <code>null</code> if message translation string does
 * not contain any placeholders.
 */
//---------------------------------------------------------------------------	

public void setMessage (String p_MessageKey, String[] p_Filler)
	{
	m_MessageKey 	= p_MessageKey;
	m_MessageFiller = p_Filler;
	
	m_Message.setText(this.getTranslationString (m_MessageKey,m_MessageFiller));
	}

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

public void setIcon (ImageIcon p_Icon)
	{
	if (p_Icon != null)	m_Message.setIcon (p_Icon);
	}

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

public void setPasswordHash (String p_PasswordHash)
	{
	m_PasswordHash = p_PasswordHash;	
	m_PasswordMatched = false;
	}

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

public String getPassword ()
	{
	return String.valueOf(m_Password.getPassword());
	}

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

public boolean wasCanceled ()
	{
	return m_Canceled;	
	}

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

public boolean passwordMatched ()
	{
	return m_PasswordMatched;	
	}

//---------------------------------------------------------------------------
	
public void relocalize()
	{
	this.setTitle(Translatrix.getTranslationString(m_TitleKey));
	
	if (m_Message != null)
		m_Message.setText(this.getTranslationString (m_MessageKey,m_MessageFiller));

	if (m_ShowTyping != null)
		m_ShowTyping.setText(Translatrix.getTranslationString(c_ShowTyping));
	
	if (m_PasswordLabel != null)
		m_PasswordLabel.setText(Translatrix.getTranslationString(c_PasswordLabel));
	
	if (m_OkayButton != null)
		m_OkayButton.setText(Translatrix.getTranslationString("core.ok"));
	
	if (m_CancelButton != null) 
		m_CancelButton.setText(Translatrix.getTranslationString("core.cancel"));
	}

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

public void actionPerformed (ActionEvent p_ActionEvent)
	{
	if (p_ActionEvent.getSource().equals(m_OkayButton))
		{
		m_PasswordMatched = this.checkPassword(String.valueOf(m_Password.getPassword()));	
		m_Canceled 		  = false;
		this.setVisible(false);
		}
	else if (p_ActionEvent.getSource().equals(m_CancelButton))	
		{
		m_Canceled = true;
		this.setVisible(false);
		}
	}

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

public void itemStateChanged(ItemEvent p_ItemEvent)
	{
	if (p_ItemEvent.getSource().equals(m_ShowTyping))
		{
		if (m_ShowTyping.isSelected())
			 m_Password.setEchoChar(c_ClearText);
		else m_Password.setEchoChar(c_EchoCharacter);
		}	
	}

@Override
public void setVisible(boolean b) {
	if (b)
		m_Password.requestFocus();
		
	super.setVisible(b);
}

public void markPasswordWrong()
{
	m_Password.setBackground(new Color(255, 180, 180, 255));
	m_Password.setSelectionStart(0);
	m_Password.setSelectionEnd(m_Password.getPassword().length);
}

//---------------------------------------------------------------------------
//***************************************************************************
//* End of Class                                                            *
//***************************************************************************
//---------------------------------------------------------------------------
	}
