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

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.border.TitledBorder;

import lu.tudor.santec.gecamed.core.gui.GECAMedLists;
import lu.tudor.santec.gecamed.core.gui.MainFrame;
import lu.tudor.santec.gecamed.core.utils.ManagerFactory;
import lu.tudor.santec.gecamed.office.ejb.entity.beans.Physician;
import lu.tudor.santec.gecamed.office.ejb.session.beans.OfficeManagerBean;
import lu.tudor.santec.gecamed.office.ejb.session.interfaces.OfficeManagerInterface;

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

/**
 * This dialog is for selecting a doctor.
 * It recieves optional a Patient object to read out
 * the patients doctor and select this doctor as default
 * 
 * After ok is pressed, the selected physician is copied into
 * the field selectedPhysian
 * if cancel, the field is null.
 * 
 * @author Martin Heinemann martin.heinemann@tudor.lu
 *
 *@Version
 * <br>$Log: PhysicianChooserDialog.java,v $
 * <br>Revision 1.8  2008-09-25 09:43:10  heinemann
 * <br>fixed copyrights
 * <br>
 * <br>Revision 1.7  2008-01-15 13:08:51  hermen
 * <br>updated Javadoc and refactured code
 * <br>
 * 
 */
public class PhysicianChooserDialog extends JDialog {

    private static final long serialVersionUID = 1L;
    
    private JLabel message = new JLabel("Select a Physician"); 
    
    private JButton okButton = null;
    
    private JButton cancelButton = null;
    
    private static PhysicianChooserDialog physicianChooser = new PhysicianChooserDialog();
    
    private JPanel panel = null;
    
    private JList list = null;
    
    private CellConstraints cc = new CellConstraints();
    
    private OfficeManagerInterface officeManager;

	private Integer physicianId;
	
	private Physician selectedPhysician = null;
	
	private List<Physician> allPhysicians;
    
    /**
     * private constructor for Singleton
     */
    private PhysicianChooserDialog() {
        /* ========================================================= */
        super(MainFrame.getInstance(),true);
        
        this.panel = new JPanel();
        /* --------------------------------------------------------- */
        initFormLayout();
        /* --------------------------------------------------------- */
        initComponent();
        /* --------------------------------------------------------- */
        initActionListener();
        /* --------------------------------------------------------- */
        // gain the focus to the list
        list.requestFocus();
        /* --------------------------------------------------------- */
        /* --------------------------------------------------------- */
        
        /* ========================================================= */
    }

    
    /**
     * Sets the physician that should be preselected in the JList.
     * Important when a physician is selected in condition with
     * a patient. Every patient has a pyhsician set as preferred physician
     * 
     * @param physicianId
     */
    public void setPhysicianId(Integer physicianId) {
    	/* ========================================================= */
    	this.physicianId = physicianId;
    	// select physician
    	if (allPhysicians != null)
	    	for (Physician phys : allPhysicians) {
	    		if (phys.getId().equals(physicianId)) {
	    			this.list.setSelectedValue(phys, true);
	    			return;
	    		}
	    	}
    	/* ========================================================= */
    }
    
    public Integer getPhysicianId() {
    	return this.physicianId;
    }
    
    /**
     * Returns the selected Physician.
     * If Cancel was presses, the result is a null value.
     * 
     * @return
     */
    public Physician getSelectedPhysician() {
    	return this.selectedPhysician;
    }
    
    
    /**
     * Inits the actionlisteners for the buttons and the list
     */
    private void initActionListener() {
        /* =========================================================== */
        okButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                /* =========================================================== */
                // save the selected physician and hide the dialog
            	PhysicianChooserDialog.this.selectedPhysician = 
            		(Physician) PhysicianChooserDialog.this.list.getSelectedValue();
            	// hide
            	PhysicianChooserDialog.this.setVisible(false);
                /* =========================================================== */
            }
        });
        
        cancelButton.addActionListener(new ActionListener() {
           
                public void actionPerformed(ActionEvent e) {
                    /* =========================================================== */
                    // set selectedPhysician to null and hide
                	PhysicianChooserDialog.this.selectedPhysician = null; 
                	// hide
                	PhysicianChooserDialog.this.setVisible(false);
                    /* =========================================================== */
                }
        });
        // add a keyListener to the list --> Enter -> ok
        // esc --> cancel
        list.addKeyListener(new KeyListener() {

            public void keyTyped(KeyEvent e) {
            }

            public void keyPressed(KeyEvent e) {
                /* =========================================================== */
                if (e.getKeyCode() == KeyEvent.VK_ENTER)
                    okButton.doClick();
                if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
                    cancelButton.doClick();
                /* =========================================================== */
            }
            public void keyReleased(KeyEvent e) {
            }
        });
        /* =========================================================== */
    }

    
    /**
     * Inits the components
     */
    private void initComponent() {
        /* =========================================================== */
        // the lable
//        panel.add(message, cc.xy(2, 2));
        /* --------------------------------------------------------- */
        // the list
        list = new JList();
             
        // allow only single selection
        list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        fireFillList();
        
        // Mouselistener
        list.addMouseListener(new MouseListener() {

			public void mouseClicked(MouseEvent e) {
				/* ============================================= */
				if (SwingUtilities.isLeftMouseButton(e))
					if (e.getClickCount() >= 2)
						PhysicianChooserDialog.this.okButton.doClick();
				/* ============================================= */
			}

			public void mousePressed(MouseEvent e) {}
			public void mouseReleased(MouseEvent e) {}
			public void mouseEntered(MouseEvent e) {}
			public void mouseExited(MouseEvent e) {}
        	
        });
        
        
        /* --------------------------------------------------------- */
        // the scroll pane
        JScrollPane scroll = new JScrollPane(list);
        panel.setBorder(new TitledBorder(message.getText()));
        scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        
        panel.add(scroll, cc.xywh(2, 4, 4, 1));
        /* --------------------------------------------------------- */
        // the buttons
        okButton = new JButton("Ok");
        cancelButton = new JButton("Cancel");
        okButton.setPreferredSize(cancelButton.getPreferredSize());
        
        panel.add(okButton, cc.xy(3, 6));
        panel.add(cancelButton, cc.xy(5, 6));
        
        /* --------------------------------------------------------- */
        this.add(panel);
        this.pack();
        
        /* =========================================================== */
    }

    /**
     * Use only this method to obtain the SessionBean
     * 
     * @return
     */
    private OfficeManagerInterface getManager() {
    	if(this.officeManager == null) {
    		this.officeManager = (OfficeManagerInterface) ManagerFactory.getRemote(OfficeManagerBean.class);
    	}
    	return this.officeManager;
    }
    
    
    private void fireFillList() {
        /* =========================================================== */
        Thread t = new Thread() {
            public void run() {
            	/* --------------------------------------------------------- */
                OfficeManagerInterface manager = PhysicianChooserDialog.this.getManager();
                /* --------------------------------------------------------- */
                List<Physician> physicians = GECAMedLists.getListCopy(Physician.class);
                if (physicians != null) {
                	// clean the list
                	PhysicianChooserDialog.this.list.removeAll();
                	PhysicianChooserDialog.this.list.setListData(physicians.toArray());
                	// select the first element
                	try {
                		PhysicianChooserDialog.this.list.setSelectedIndex(0);
					} catch (Exception e) {}
                	// save the objects
                	PhysicianChooserDialog.this.allPhysicians = physicians;
//                	PhysicianChooserDialog.this.setPhysicianId(
//                			PhysicianChooserDialog.this.physicianId);
                }
                /* --------------------------------------------------------- */
            }
        };
        t.start();
        /* =========================================================== */
    }

    
    /**
     * Reloads the list's data
     */
    public void reloadList() {
    	this.fireFillList();
    }
    
    
   
    /**
     * shows the Dialog centered on the Screen.
     */
    public void showCentered()
    {
    	MainFrame.showDialogCentered(this);
    	list.requestFocus();
    }
    
    

    /**
     * Inits the FormLayout 
     */
    private void initFormLayout() {
        /* =========================================================== */
        // create the Layout for Panel this

        String panelColumns = "3dlu," +         // 1 //$NON-NLS-1$
                              "fill:120," +     // 2 //$NON-NLS-1$
                              "fill:pref," +    // 3 //$NON-NLS-1$
                              "3dlu," +         // 4 //$NON-NLS-1$
                              "fill:pref," +    // 5 //$NON-NLS-1$
                              "3dlu";           // 6 //$NON-NLS-1$
        
        String panelRows    = "3dlu," +         // 1 //$NON-NLS-1$
                              "fill:pref," +    // 2 //$NON-NLS-1$
                              "3dlu," +         // 3 //$NON-NLS-1$
                              "fill:100dlu," +  // 4 //$NON-NLS-1$
                              "3dlu," +         // 5 //$NON-NLS-1$
                              "fill:pref," +    // 6 //$NON-NLS-1$
                              "3dlu";           // 7 //$NON-NLS-1$
                              
                              
        FormLayout panelLayout = new FormLayout(panelColumns, panelRows);
        this.panel.setLayout(panelLayout);
        /* =========================================================== */
    }

    /**
     * @return
     */
    public static PhysicianChooserDialog getInstance() {
        /* ========================================================= */
    	return PhysicianChooserDialog.physicianChooser;
        /* ========================================================= */
    }
}
