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

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.util.List;
import java.util.Vector;

import javax.jms.JMSException;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

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.utils.ManagerFactory;
import lu.tudor.santec.gecamed.waitingroom.ejb.entity.beans.Room;
import lu.tudor.santec.gecamed.waitingroom.ejb.session.beans.WaitingroomManagerBean;
import lu.tudor.santec.gecamed.waitingroom.ejb.session.interfaces.WaitingroomManager;
import lu.tudor.santec.i18n.Translatrix;
import lu.tudor.santec.settings.SettingsPlugin;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;

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

/**
 * Global Admin Settings for the Waitingrooms to show/edit some general settings of the Waitingrooms.
 * 
 * @author nmac / jhermen / Thorsten Roth thorsten.roth(at)tudor.lu
 *
 * @version
 * <br>$Log: WaitingroomAdminSettingsPlugin.java,v $
 * <br>Revision 1.9  2013-12-27 18:09:24  donak
 * <br>Cleanup of imports
 * <br>
 * <br>Revision 1.8  2013-07-15 06:18:35  ferring
 * <br>logging changed
 * <br>
 * <br>Revision 1.7  2012-04-12 13:20:00  troth
 * <br>Add translation.
 * <br>
 * <br>Revision 1.6  2011-11-07 15:35:24  troth
 * <br>Fix some GUI Bugs.
 * <br>
 * <br>Revision 1.5  2011-10-24 11:15:54  troth
 * <br>Ticket #899: add new enhancement - Configuration of the minimum width of a column waiting room.
 * <br>
 * <br>Revision 1.4  2011-10-21 12:14:43  troth
 * <br>Ticket #898: add new function 'arrangement of the waiting rooms in any order'.
 * <br>
 */
public class WaitingroomAdminSettingsPlugin extends SettingsPlugin implements ComponentListener, ActionListener, ChangeListener {
	private static final long serialVersionUID = 1L;

	/**
	 * static logger for this class
	 */
	private static Logger  		logger = Logger.getLogger(WaitingroomAdminSettingsPlugin.class.getName());
	
	public static final String 	NAME = "WaitingroomModuleAdminSettings";
	
	public static final String 	AUTO_IMPORT_ENABLED = "AUTO_IMPORT_ENABLED";
	
	public static final String 	WR_MIN_SIZE = "WR_MIN_SIZE";

	private WaitingroomManager 	wrManager;

	private JList 				wrList;
	
	private Vector<Room> 		wrListModel = new Vector<Room>();

	private JButton 			addButton;

	private JButton 			editButton;

	private JButton 			deleteButton;
	
	private JButton 			upButton;

	private JButton 			downButton;

	private JCheckBox 			autoimportEnabled;

	private JLabel 				autoimportEnabledLabel;

	private JPanel 				importSub;

	private static final int 	MIN_SIZE_MIN = 100;
	
	private static final int 	MIN_SIZE_MAX = 500;
	
	private static final int 	MIN_SIZE_INIT = 300;
	
	private JSlider 			minSizeSlider;

	private boolean changes;
	

	/**
	 * 
	 */
	public WaitingroomAdminSettingsPlugin() {
		/* ================================================== */
		super(NAME);
		this.setStationaryValues();
		buildPanel();
		/* ================================================== */
	}

	/**
	 * @param p_Name
	 */
	public WaitingroomAdminSettingsPlugin(String p_Name) {
		/* ================================================== */
		super(p_Name);
		this.setStationaryValues();
		buildPanel();
		/* ================================================== */
	}

	/**
	 * 
	 */
	private void buildPanel() {
		/* ================================================== */
		try {
			wrManager = (WaitingroomManager) ManagerFactory
			.getRemote(WaitingroomManagerBean.class);
		} catch (Exception e) {
			logger.log(Level.WARN, "error getting Waitingroom manager" , e);
		}
		
		// -----------------------------------------------------
		// global settings for rooms
		// -----------------------------------------------------
		setLabel(Translatrix.getTranslationString("waitingroom"));

		this.wrListModel = new Vector<Room>();
		this.wrList = new JList(this.wrListModel);
		
		JPanel panel = createSubPanel(Translatrix.getTranslationString("waitingroom.settings.RoomsPanel")); 
		panel.setLayout(new BorderLayout());
		JScrollPane jsp = new JScrollPane(this.wrList);
		panel.add(jsp, BorderLayout.CENTER);

		ButtonStackBuilder bsb = new ButtonStackBuilder();
		this.addButton = new JButton(
			Translatrix.getTranslationString("waitingroom.add.waitingroom"),
			IconFetcher.getSmallIcon(GECAMedIconNames.class, GECAMedIconNames.ADD));
		this.addButton.addActionListener(this);
		bsb.addGridded(this.addButton);
		this.editButton = new JButton(
			Translatrix.getTranslationString("waitingroom.edit"), 
			GECAMedModule.getSmallIcon(GECAMedIconNames.EDIT));
		this.editButton.addActionListener(this);
		bsb.addGridded(this.editButton);
		this.deleteButton = new JButton(
			Translatrix.getTranslationString("waitingroom.remove"), 
			GECAMedModule.getSmallIcon(GECAMedIconNames.REMOVE));
		this.deleteButton.addActionListener(this);
		bsb.addGridded(this.deleteButton);
		this.upButton = new JButton(GECAMedModule.getSmallIcon(GECAMedModule.UP));
        this.upButton.addActionListener(this);
        bsb.addGridded(this.upButton);
        this.downButton = new JButton(GECAMedModule.getSmallIcon(GECAMedModule.DOWN));
        this.downButton.addActionListener(this);
        bsb.addGridded(this.downButton);
		
		panel.add(bsb.getPanel(), BorderLayout.EAST);
		
		addSubPanel(panel);
		
		// -----------------------------------------------------
		// global settings for waiting room min size
		// -----------------------------------------------------
		int initValue = MIN_SIZE_INIT;
		if(getValue(WR_MIN_SIZE) != null)
			initValue = (Integer) getValue(WR_MIN_SIZE);
		
		minSizeSlider = new JSlider(JSlider.HORIZONTAL, MIN_SIZE_MIN, MIN_SIZE_MAX, initValue);
		minSizeSlider.addChangeListener(this);

		//Turn on labels at major tick marks.
		minSizeSlider.setMajorTickSpacing(50);
		minSizeSlider.setMinorTickSpacing(10);
		minSizeSlider.setPaintTicks(true);
		minSizeSlider.setPaintLabels(true);
		
		JPanel minSizePanel = createSubPanel(Translatrix.getTranslationString("waitingroom.settings.MinsizePanel"));
		minSizePanel.setLayout(new BorderLayout());
		minSizePanel.add(minSizeSlider, BorderLayout.CENTER);
		
        addSubPanel(minSizePanel);
		
		// -----------------------------------------------------
		// global settings for Import
		// -----------------------------------------------------
		CellConstraints cc = new CellConstraints();
		FormLayout importSubLayout = 
		    new FormLayout("2dlu, left:pref:grow, 2dlu, pref, 2dlu,", "2dlu, pref, 2dlu");
		importSub = createSubPanel(Translatrix.getTranslationString("waitingroom.settings.ImportPanel"));
		importSub.setLayout(importSubLayout);
		this.autoimportEnabledLabel = new JLabel(Translatrix.getTranslationString("waitingroom.settings.autoimportEnabled"));
        this.autoimportEnabled = new JCheckBox();
        importSub.add(this.autoimportEnabledLabel, cc.xy(2,2));
        importSub.add(this.autoimportEnabled, cc.xy(4,2));
		
        addSubPanel(importSub);
		
		this.addComponentListener(this);
		relocalize();
		setIcon(IconFetcher.getScaledIcon(WaitingroomModule.class, WaitingroomModule.WAITINGROOM_ICON, 32));
		/* ================================================== */
	}
	
	
	public void revertToDefaults() {
		/* ================================================== */	
		this.autoimportEnabled.setSelected((Boolean) getDefault(AUTO_IMPORT_ENABLED));
		this.minSizeSlider.setValue((Integer) getDefault(WR_MIN_SIZE));
		reflectSettings();
		super.revertToDefaults();
		/* ================================================== */
	}

	/* (non-Javadoc)
	 * @see lu.tudor.santec.settings.SettingsPlugin#updateSettings()
	 */
	public void updateSettings() {
		/* ================================================== */
	    	setValue(AUTO_IMPORT_ENABLED, this.autoimportEnabled.isSelected());
	    	setValue(WR_MIN_SIZE, this.minSizeSlider.getValue());
	    	
	    	if (changes) {
	    		saveRoomOrder();	    		
	    	}
	    	
	    	super.updateSettings();
		/* ================================================== */
	}

	private void saveRoomOrder() {
		for (Room room : wrListModel) {
			room.setOrderId(wrListModel.indexOf(room));
			WaitingroomModule.getInstance().saveRoom(room);	
		}
	}

	public void reflectSettings() {
		/* ================================================== */
	    super.reflectSettings();
		
		this.autoimportEnabled.setSelected((Boolean) getValue(AUTO_IMPORT_ENABLED));
		
		this.minSizeSlider.setValue((Integer) getValue(WR_MIN_SIZE));
		
		int currentLocation = wrList.getSelectedIndex();	
			
		this.wrListModel.removeAllElements();
		List<Room> rooms = wrManager.getAllRooms();
	    if (rooms != null) {
	        for (Room room : rooms) {
	        	this.wrListModel.add(room);
	        }	    	    
	    }
	    this.wrList.setListData(wrListModel);
	    
	    if(this.wrListModel.size() > currentLocation)
	    	this.wrList.setSelectedIndex(currentLocation);
	    else
	    	this.wrList.setSelectedIndex(0);
		/* ================================================== */
	}

	public void relocalize() {
		/* ================================================== */
		super.relocalize();
		setLabel(Translatrix.getTranslationString("waitingroom"));
		/* ================================================== */
	}

	public void setStationaryValues() {
		/* ================================================== */
	    	setStationary(AUTO_IMPORT_ENABLED, true);
	    	setStationary(WR_MIN_SIZE, MIN_SIZE_INIT);
		/* ================================================== */
	}

	public void componentHidden(ComponentEvent e) {}
	public void componentMoved(ComponentEvent e) {}
	public void componentResized(ComponentEvent e) {}
	public void componentShown(ComponentEvent e) {
		/* ====================================================== */
		reflectSettings();
		/* ====================================================== */
	}

	/* (non-Javadoc)
	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	public void actionPerformed(ActionEvent e) {
	    
		changes = true;
		
		if (e.getSource().equals(this.addButton)) 
	    {
			/* ================================================== */
			WaitingroomEditDialog ed = new WaitingroomEditDialog();
			ed.showDialog(new Room());
			if (ed.getRoom() != null)
			{
				ed.getRoom().setOrderId(wrListModel.size() + 1);
				WaitingroomModule.getInstance().saveRoom(ed.getRoom());
			}
			/* ================================================== */
	    } else if (e.getSource().equals(this.deleteButton))
	    {
	    	/* ================================================== */
        	try {
        		/* --------------------------------------------- */
        		Room room = (Room) wrList.getSelectedValue();
        		if (room != null) {
        			logger.info("Deleting Waitingroom " + room);
        		    wrManager.deleteRoom(room);
        		}
        		/* --------------------------------------------- */
        	} catch (Exception ee) {
        		/* --------------------------------------------- */
        		logger.warn("Error Deleting Waitingroom ", ee);
        		/* --------------------------------------------- */
        	}
        	/* ================================================== */
	    } else if (e.getSource().equals(this.editButton))
	    {
	    	Room room = (Room) wrList.getSelectedValue();
	    	if (room != null) {
	    		WaitingroomEditDialog ed = new WaitingroomEditDialog();
	    		ed.showDialog(room);
	    		if (ed.getRoom() != null)
	    			WaitingroomModule.getInstance().saveRoom(ed.getRoom());		    
	    	}
	    } else if (e.getSource().equals(this.upButton))
	    {
	    	int currentLocation = wrList.getSelectedIndex();
            Room room = (Room)  wrList.getModel().getElementAt(currentLocation);
            
            if(room != wrListModel.firstElement()){
                
                // remove element at selected location:
            	wrListModel.remove(room);
                
                // add it to selected location - 1:
            	wrListModel.add((currentLocation-1), room);
                wrList.setSelectedIndex((currentLocation-1));
                
                wrList.repaint();
                
                saveRoomOrder();
            }
	    } else if (e.getSource().equals(this.downButton))
	    {
	    	int currentLocation = wrList.getSelectedIndex();
            Room room = (Room)  wrList.getModel().getElementAt(currentLocation);
            
            if(room != wrListModel.lastElement()){
                
                // remove element at selected location:
            	wrListModel.remove(room);
                
                // add it to selected location - 1:
            	wrListModel.add((currentLocation+1), room);
                wrList.setSelectedIndex((currentLocation+1));
                
                wrList.repaint();
                
                saveRoomOrder();
            }
	    }
	   reflectSettings();
	}

	/* (non-Javadoc)
	 * @see javax.swing.event.ChangeListener#stateChanged(javax.swing.event.ChangeEvent)
	 */
	public void stateChanged(ChangeEvent e)
	{
		setValue(WR_MIN_SIZE, this.minSizeSlider.getValue());
		WaitingroomManager manager = (WaitingroomManager) ManagerFactory.getRemote(WaitingroomManagerBean.class);
		try {
			logger.info("changed Waitingroom Minimum Size");
			manager.sendRoomUpdateMessage();
		} catch (JMSException ex) {
			logger.log(Level.WARN, "Error: Send Waitingroom update message." , ex);
		}
	}
}