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

import java.awt.Color;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Iterator;
import java.util.Vector;

import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.TableColumnModelEvent;
import javax.swing.event.TableColumnModelListener;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumnModel;

import lu.tudor.santec.gecamed.patient.ejb.entity.beans.Patient;

/**
 * editable TableHeader for the patient search table that shows a Textfield
 * or Combobox on right-clicking the tableheader. this field can be used to 
 * search in the specified column of the table.  
 * 
 *
 * @author Johannes Hermen johannes.hermen(at)tudor.lu
 *
 * @version
 * <br>$Log: PatientSearchTableHeader.java,v $
 * <br>Revision 1.8  2013-06-10 08:22:01  ferring
 * <br>eSante POC
 * <br>
 * <br>Revision 1.7  2010-05-04 14:54:44  hermen
 * <br>suspended search via richt click on table header
 * <br>
 * <br>Revision 1.6  2008-09-25 09:43:07  heinemann
 * <br>fixed copyrights
 * <br>
 * <br>Revision 1.5  2008-01-23 08:30:09  hermen
 * <br>*** empty log message ***
 * <br>
 *
 */
public class PatientSearchTableHeader extends MouseAdapter 
       implements TableColumnModelListener, FocusListener
{
       private JTableHeader        tableHeader;
       private JComponent          editingComponent;
       private TableColumnModel    columnModel;
       private int                 editingColumn = -1;
       private JTable table;
       private Vector<PropertyChangeListener> propertyListeners = new Vector<PropertyChangeListener>();
       
       public PatientSearchTableHeader(JTable tbl) {
    	   table = tbl;
           // Table Header need to detect double clicks
           tableHeader = tbl.getTableHeader();
           tableHeader.addMouseListener(this);
           
           // Need to know if column events occur
           columnModel = tbl.getColumnModel(); 
           columnModel.addColumnModelListener(this);
           
       } 

       /* (non-Javadoc)
     * @see java.awt.event.FocusListener#focusGained(java.awt.event.FocusEvent)
     */
    public void focusGained(FocusEvent e) { }
       

       /* (non-Javadoc)
     * @see java.awt.event.FocusListener#focusLost(java.awt.event.FocusEvent)
     */
    public void focusLost(FocusEvent e) {
           endEditing();
       }
       
       /* Any column event need to end editing, things get ugly if header of
          column being edited is moved or resized */
       
       /* (non-Javadoc)
     * @see javax.swing.event.TableColumnModelListener#columnAdded(javax.swing.event.TableColumnModelEvent)
     */
    public void columnAdded(TableColumnModelEvent e) {
           endEditing();
     }

       /* (non-Javadoc)
     * @see javax.swing.event.TableColumnModelListener#columnMarginChanged(javax.swing.event.ChangeEvent)
     */
    public void columnMarginChanged(ChangeEvent e) {
           endEditing();
    }

     /* (non-Javadoc)
     * @see javax.swing.event.TableColumnModelListener#columnMoved(javax.swing.event.TableColumnModelEvent)
     */
    public void columnMoved(TableColumnModelEvent e) {
           endEditing();
     }

       /* (non-Javadoc)
     * @see javax.swing.event.TableColumnModelListener#columnRemoved(javax.swing.event.TableColumnModelEvent)
     */
    public void columnRemoved(TableColumnModelEvent e) {
           endEditing();
    }
       
       /* (non-Javadoc)
     * @see javax.swing.event.TableColumnModelListener#columnSelectionChanged(javax.swing.event.ListSelectionEvent)
     */
    public void columnSelectionChanged(ListSelectionEvent e) { }
    /* One column event, that we don't need to edit editing over*/    
       
    //TODO suspended search via richt click on table header
       public void mouseClicked(MouseEvent me) {
//    	   endEditing();
//    	   int col = tableHeader.columnAtPoint(me.getPoint());
//    	   if (col != -1) {
//    		   // If this is a roght click... 
//    		   if (me.getButton() == MouseEvent.BUTTON3) {
//               // ... see if it's in the header, if so...
//            	   resetTableHeaders();
//                   editingColumn = col; 
//                   // ... add JTextField to the header ...
//                   
//                   editingComponent = getEditingcomponent(col);
//                   
//                   // Need to know when the JTextField looses focus
//                   editingComponent.addFocusListener(this);
//                   
//                   tableHeader.add(editingComponent);                   
//                   // ... resize the JTextField to overlay the Header column
//                   editingComponent.setBounds(tableHeader.getHeaderRect(col));
//                   editingComponent.requestFocus();
//               }
//           }
       } 
       
     /**
     * stop editing the column......
     */
    public void endEditing() {
            // If where are done editing, make sure we really editing...
            if (editingColumn != -1) {
            	String text = "";
            	if (editingComponent instanceof JTextField) {
            		text = ((JTextField)editingComponent).getText();
            	} else if (editingComponent instanceof JComboBox) {
            		text = ((JComboBox)editingComponent).getSelectedItem().toString();
            	}
            	
            	if (text.equals("")) {
                    columnModel.getColumn(editingColumn).setHeaderValue( table.getModel().getColumnName(editingColumn));
            	} else {
//            		 ... Set the Header value to the value of the JTextField ...
                    columnModel.getColumn(editingColumn).setHeaderValue("<html><b>" + table.getModel().getColumnName(editingColumn)+": " + text +"</b></html>");
            	}
                // ... remove the JTextField and refesh header column area ...
               tableHeader.remove(editingComponent);
               tableHeader.repaint(tableHeader.getHeaderRect(editingColumn));
               fireSearchChanged(editingColumn, text);
               editingColumn = -1;
            } 
       }
       
    /**
     * reset table headers to not do any search
     */
    public void resetTableHeaders() {
    	   int columnAnz = columnModel.getColumnCount()-1;
    	   for (int i = 0; i < columnAnz; i++) {
    		   columnModel.getColumn(i).setHeaderValue(table.getModel().getColumnName(i));
    	   }
    	   tableHeader.repaint();
       }
       
     /**
      * register a listener for header changes
     * @param pcl
     */
    public void addPropertyChangeListener(PropertyChangeListener pcl) {
    	   this.propertyListeners.add(pcl);
       }
       
    /**
     * remove a listener for header changes
    * @param pcl
    */
   public void removePropertyChangeListener(PropertyChangeListener pcl) {
    	   this.propertyListeners.remove(pcl);
       }
       
   
	 /** 
	  * fire a tableheaderchanged event on all listeners
	 * @param column
	 * @param newValue
	 */
   private void fireSearchChanged(Integer column, String newValue) {
    	   for (Iterator iter = this.propertyListeners.iterator(); iter.hasNext();) {
			PropertyChangeListener element = (PropertyChangeListener) iter.next();
			element.propertyChange(new PropertyChangeEvent(column, table.getModel().getColumnName(column), "", newValue));
		}
       }
       
       
    /**
     * get the editing component for the specified column
     * @param column
     * @return
     */
    private JComponent getEditingcomponent(int column) {
    	   
    	   switch (column) {
			case PatientListPanel.COLUMN_PHONE:
		           final JComboBox jcb = new JComboBox();  
		           jcb.addItem("");
		           for (int i = 0; i < Patient.STATES.length; i++) {
		        	   jcb.addItem(Patient.STATES[i]);
		           }
		           jcb.addItemListener(new ItemListener() {
					public void itemStateChanged(ItemEvent e) {
						endEditing();
					}
		           });
		           jcb.addKeyListener(new KeyListener() {
						public void keyTyped(KeyEvent e) {
							if (e.getKeyCode() == KeyEvent.VK_ENTER)
								e.consume();
						}
						public void keyPressed(KeyEvent e) {
							if (e.getKeyCode() == KeyEvent.VK_ENTER) 
								e.consume();
						}
						public void keyReleased(KeyEvent e) {
							if (e.getKeyCode() == KeyEvent.VK_ENTER) {
								jcb.transferFocus();
								e.consume();
							}
						}
		           });
		           return jcb;
			default:
		           final JTextField jtf = new JTextField();  
		           jtf.setForeground(Color.BLUE);
		           jtf.addKeyListener(new KeyListener() {
						public void keyTyped(KeyEvent e) {
							if (e.getKeyCode() == KeyEvent.VK_ENTER)
								e.consume();
						}
						public void keyPressed(KeyEvent e) {
							if (e.getKeyCode() == KeyEvent.VK_ENTER) 
								e.consume();
						}
						public void keyReleased(KeyEvent e) {
							if (e.getKeyCode() == KeyEvent.VK_ENTER) {
								jtf.transferFocus();
								e.consume();
							}
						}
		           });
		           return jtf;
			}
       }
}
