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

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Vector;

import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import lu.tudor.santec.gecamed.core.ejb.entity.beans.GECAMedLocale;
import lu.tudor.santec.gecamed.core.ejb.session.beans.ListManagerBean;
import lu.tudor.santec.gecamed.core.ejb.session.interfaces.ListManagerInterface;
import lu.tudor.santec.gecamed.core.gui.GECAMedColors;
import lu.tudor.santec.gecamed.core.gui.GECAMedIconNames;
import lu.tudor.santec.gecamed.core.gui.GECAMedLists;
import lu.tudor.santec.gecamed.core.gui.GECAMedLog;
import lu.tudor.santec.gecamed.core.gui.GECAMedMessage;
import lu.tudor.santec.gecamed.core.gui.GECAMedModule;
import lu.tudor.santec.gecamed.core.gui.GECAMedTab;
import lu.tudor.santec.gecamed.core.gui.MainFrame;
import lu.tudor.santec.gecamed.core.gui.listener.MessageListenerRegister;
import lu.tudor.santec.gecamed.core.gui.utils.filtertablemodel.FilterTableModel;
import lu.tudor.santec.gecamed.core.gui.utils.filtertablemodel.TableFilter;
import lu.tudor.santec.gecamed.core.gui.widgets.HeaderedPanel;
import lu.tudor.santec.gecamed.core.gui.widgets.LocaleChooser;
import lu.tudor.santec.gecamed.core.utils.ManagerFactory;
import lu.tudor.santec.gecamed.usermanagement.ejb.entity.beans.GecamedUser;
import lu.tudor.santec.gecamed.usermanagement.ejb.session.beans.UserAdminBean;
import lu.tudor.santec.gecamed.usermanagement.ejb.session.interfaces.UserAdminInterface;
import lu.tudor.santec.gecamed.usermanagement.gui.AdminModule;
import lu.tudor.santec.i18n.Translatrix;
import lu.tudor.santec.widgets.gui.ButtonFactory;

import org.apache.batik.ext.awt.image.GammaTransfer;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;

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

/**
 * admin Panel to manage the GECAMED users with 
 * the ability to create,delete and modify them.
 *
 * @version
 * <br>$Log: UserManagementPanel.java,v $
 * <br>Revision 1.32  2013-12-27 18:09:26  donak
 * <br>Cleanup of imports
 * <br>
 * <br>Revision 1.31  2013-07-15 06:18:37  ferring
 * <br>logging changed
 * <br>
 * <br>Revision 1.30  2013-02-19 12:07:34  ferring
 * <br>GECAMedLists changed. Will now automatically load list of all beans
 * <br>
 * <br>Revision 1.29  2011-11-29 09:40:35  ferring
 * <br>"add user"-bug fixed
 * <br>
 * <br>Revision 1.28  2010-06-24 13:06:29  hermen
 * <br>Incomplete - # 523: Null pointer exception while saving a password change
 * <br>http://santec.tudor.lu/trac/gecamed/ticket/523
 * <br>
 * <br>Revision 1.27  2010-04-08 10:56:40  hermen
 * <br>enhanced logging
 * <br>
 * <br>Revision 1.26  2010-04-06 10:00:02  hermen
 * <br>fixed filtering and adding of new users
 * <br>
 * <br>Revision 1.25  2010-03-12 14:17:42  hermen
 * <br>cleanup of panel layouts and icons
 * <br>
 * <br>Revision 1.24  2009-06-02 12:52:59  hermen
 * <br>added search for user/physician
 * <br>
 * <br>Revision 1.23  2009-05-07 08:26:44  hermen
 * <br>handle password changing without restarting
 * <br>
 * <br>Revision 1.22  2009-03-20 10:20:05  hermen
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.21  2008-12-08 09:15:23  hermen
 * <br>reloads user-list in physician admin tab if a new user is created
 * <br>
 * <br>Revision 1.20  2008-09-25 09:43:10  heinemann
 * <br>fixed copyrights
 * <br>
 * <br>Revision 1.19  2008-07-04 13:38:58  heinemann
 * <br>fixed generic casting that the new eclipse does not want to accept.
 * <br>
 * <br>Revision 1.18  2008-01-15 10:18:39  hermen
 * <br>updated Javadoc and refactured code
 * <br>
 *
 */
public class UserManagementPanel extends GECAMedTab implements ActionListener {

	private static final long serialVersionUID = 1L;
	
	/**
	 * static logger for this class
	 */
	
	private static UserManagementPanel usermanagementpanel;
	private static Logger logger = Logger.getLogger(UserManagementPanel.class
			.getName());
	
	private final String[] columnName = {
		Translatrix.getTranslationString("um.id"),
		Translatrix.getTranslationString("um.login"),
		Translatrix.getTranslationString("um.name"),
		Translatrix.getTranslationString("um.language"),
		Translatrix.getTranslationString("um.lastmodification"),
		Translatrix.getTranslationString("um.modifiedby"),
		Translatrix.getTranslationString("um.password"),
		""
		};
	
	private final Class<?>[] columnsClasses = {
		Integer.class,
		String.class,
		String.class,
		GECAMedLocale.class,
		String.class,
		String.class,
		String.class,
		String.class
		};
	
	private JTable userTable;
	private UserAdminInterface manager;
	private UserTableModel userTableModel;
	private JButton addButton;
	private JButton saveButton;
	private JButton deleteButton;
	private int editRow = -1;
	private RolePanel rolePanel;
	private GecamedUser lastSelectedUser;
	private GECAMedLocale[] localeArray;
	private HashMap<Integer, GecamedUser> usersById = new HashMap<Integer, GecamedUser>();

	private JTextField filterField;

	private JPanel centerPanel;
	private JSplitPane splitPane;
	
	
	public UserManagementPanel() {
		this.setOpaque(false);
		buildPanel();
		loadUsers();
	}
	
	
	private GecamedUser getSelectedUser ()
	{
		return userTableModel.getUser(userTableModel.filteredToModel(
				userTable.getSelectedRow()));
	}
	

	/**
     * adds the components to the panel
     */
    private void buildPanel()
    {

    	this.setTitle(Translatrix.getTranslationString("admin.usermanagement"));
    	this.setIcon(AdminModule.getIcon(AdminModule.ICON_USERMANAGEMENT));

        // initialize Components
        initComponents();
        
       
		// -------------------------------------------------------
		// the view will consist of one Splitpanes.
		// -------------------------------------------------------
		this.splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
		splitPane.setOneTouchExpandable(false);
		splitPane.setOpaque(false);
        
        JPanel topPanel=new JPanel(new BorderLayout());
        topPanel.setOpaque(false);
        
        JPanel searchPanel=new JPanel(new BorderLayout());
        searchPanel.setOpaque(false);
        
        FormLayout layout = new FormLayout("3dlu, fill:pref:grow, 3dlu, pref", 
        		"pref");
        CellConstraints cc = new CellConstraints();
        this.setLayout(layout);
        JPanel filterPanel = new JPanel(new BorderLayout());
        filterPanel.setOpaque(false);
        
        searchPanel.add(new JLabel("Search: "), BorderLayout.WEST);
        
        filterField = new JTextField();
        filterField.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
        	userTableModel.getLoginFilter().setFilter(filterField.getText());
        	userTableModel.setFilteringEnabled((filterField.getText().length() > 0), 7);
        	userTableModel.fireTableDataChanged();
        	try {
        	    userTable.setRowSelectionInterval(0,0);
        	} catch (Exception ee) {
        	}
            }
        });
      
        searchPanel.add(filterField,BorderLayout.CENTER);
        
        this.add(filterPanel, cc.xy(2, 1));

        topPanel.add(searchPanel,BorderLayout.NORTH);
        
        JScrollPane jsp = new JScrollPane(userTable);
        jsp.setBackground(GECAMedColors.c_ScrollPaneBackground);
        jsp.getViewport().setOpaque(false);

        topPanel.add(jsp, BorderLayout.CENTER);

        JPanel bb = new JPanel(new FormLayout("pref, 4dlu", "pref,1dlu,pref,1dlu,pref,1dlu,pref:grow"));
        bb.setOpaque(false);
        bb.add(this.saveButton, cc.xy(1, 1));
        bb.add(this.addButton, cc.xy(1, 3));
        bb.add(this.deleteButton, cc.xy(1, 5));
  

        topPanel.add(bb, BorderLayout.EAST);
        
        this.rolePanel = new RolePanel(this);
       
        
        splitPane.setTopComponent(topPanel);
        splitPane.setBottomComponent(rolePanel);
		splitPane.setDividerSize(8);
		splitPane.setDividerLocation(300);
		
		
		filterPanel.add(splitPane, BorderLayout.CENTER);

    }

    /**
     * initialises the Components
     */
    private void initComponents()
    {
    	 // Get the type manager
		try {
			this.manager = (UserAdminInterface) ManagerFactory.getRemote(UserAdminBean.class);
			this.localeArray = ((ListManagerInterface) ManagerFactory.getRemote(ListManagerBean.class))
					.getGECAMedLocales();
	    } catch (Exception e) {
	    	logger.log(Level.WARN, "lookup for UserAdminBean/remote failed", e);
		}
	    this.userTableModel = new UserTableModel();
	    
	    this.userTable = new JTable(userTableModel);
    	
	    UserCellRenderer renderer = new UserCellRenderer();
		this.userTable.getColumnModel().getColumn(0).setCellRenderer(renderer);
		this.userTable.getColumnModel().getColumn(1).setCellRenderer(renderer);
		this.userTable.getColumnModel().getColumn(2).setCellRenderer(renderer);

		LocaleChooser localeChooser = new LocaleChooser(localeArray);
		this.userTable.getColumnModel().getColumn(3).setCellEditor(new DefaultCellEditor(localeChooser));
		this.userTable.getColumnModel().getColumn(3).setCellRenderer(localeChooser.getTableCellRenderer());

		this.userTable.getColumnModel().getColumn(4).setCellRenderer(renderer);
		this.userTable.getColumnModel().getColumn(5).setCellRenderer(renderer);

		PasswordCellEditor pwce = new PasswordCellEditor(userTableModel);
		this.userTable.getColumnModel().getColumn(6).setCellRenderer(pwce);
		this.userTable.getColumnModel().getColumn(6).setCellEditor(pwce);

		this.userTable.getColumnModel().getColumn(0).setMaxWidth(30);
		this.userTable.getColumnModel().getColumn(3).setMaxWidth(120);
		this.userTable.getColumnModel().getColumn(3).setMinWidth(120);
		this.userTable.getColumnModel().getColumn(4).setMaxWidth(150);
		this.userTable.getColumnModel().getColumn(4).setMinWidth(150);
		this.userTable.getColumnModel().getColumn(5).setMaxWidth(120);
		this.userTable.getColumnModel().getColumn(5).setMinWidth(120);
		this.userTable.getColumnModel().getColumn(6).setMaxWidth(120);
		this.userTable.getColumnModel().getColumn(6).setMinWidth(120);
		
		// hidden search col.
		this.userTable.getColumnModel().getColumn(7).setWidth(0);
		this.userTable.getColumnModel().getColumn(7).setMinWidth(0);
		this.userTable.getColumnModel().getColumn(7).setMaxWidth(0);
		
		this.userTable.setRowHeight(20);
		this.userTable.getSelectionModel().addListSelectionListener(new ListSelectionListener(){
			public void valueChanged(ListSelectionEvent e) {
				if (e.getValueIsAdjusting())
					return;

				int 		selectedRow  = userTableModel.filteredToModel(userTable.getSelectedRow());
				GecamedUser selectedUser = getSelectedUser();
				
			/*	if (selectedRow != -1 && selectedRow != editRow) {
					if (lastSelectedUser != null && lastSelectedUser.hasChanges()) {
						int n = JOptionPane.showConfirmDialog(
							    MainFrame.getInstance(),
							    Translatrix.getTranslationString("um.savequestion") + "\n" +
							    		lastSelectedUser.getLogin() + " (" + lastSelectedUser.getName() + ")",
							    Translatrix.getTranslationString("admin.usermanagement"),
							    JOptionPane.YES_NO_OPTION);
							if (n == JOptionPane.YES_OPTION) {
								saveUser(lastSelectedUser);
							}
					}
					editRow = selectedRow;
				}*/
				
				if (selectedUser != null)
				{
					rolePanel.setUser(selectedUser);
					lastSelectedUser = selectedUser;
				}
			}
    	});

		this.addButton = ButtonFactory.createNarrowButton(GECAMedModule.getIcon(GECAMedIconNames.ADD_LINE));
		this.addButton.setToolTipText(Translatrix.getTranslationString("um.addUser"));
		this.addButton.addActionListener(this);
		this.addButton.setHorizontalTextPosition(JLabel.RIGHT);
		this.addButton.setHorizontalAlignment(JLabel.LEFT);

		this.saveButton = ButtonFactory.createNarrowButton(GECAMedModule.getIcon(GECAMedIconNames.SAVE));
		this.saveButton.setToolTipText(Translatrix.getTranslationString("um.saveUser"));
		this.saveButton.addActionListener(this);
		this.saveButton.setHorizontalTextPosition(JLabel.RIGHT);
		this.saveButton.setHorizontalAlignment(JLabel.LEFT);

		this.deleteButton = ButtonFactory.createNarrowButton(GECAMedModule.getIcon(GECAMedIconNames.REMOVE_LINE));
		this.deleteButton.setToolTipText(Translatrix.getTranslationString("um.deleteUser"));
		this.deleteButton.addActionListener(this);
		this.deleteButton.setHorizontalTextPosition(JLabel.RIGHT);
		this.deleteButton.setHorizontalAlignment(JLabel.LEFT);
		
		usermanagementpanel=this;
    }

    public void loadUsers() {
		setWaitCursor(true);
		new Thread() {
			public void run() {
//				try {
//					/* ------------------------------------------------------- */
//					// check if there are users in GECAMedLists
//					if (GECAMedLists.getArray(GecamedUser.class) == null) {
//						/* ------------------------------------------------------- */
//						// load from database
//						Collection<GecamedUser> users = manager.getUserList();
//						// save in GECAMedLists
//						GECAMedLists.storeList(GecamedUser.class, users.toArray(new GecamedUser[users.size()]));
//						// set data to tablemodel
//						userTableModel.setUsers(users);
//						/* ------------------------------------------------------- */
//					} else {
//						/* ------------------------------------------------------- */
//						List<GecamedUser> users = new ArrayList<GecamedUser>();
//						Object[] listData = GECAMedLists.getArray(GecamedUser.class);
//						if (listData != null)
//							for (Object obj : listData)
//								users.add((GecamedUser) obj);
//						/* ------------------------------------------------------- */
//						userTableModel.setUsers(users);
//						/* ------------------------------------------------------- */
//					}
					List<GecamedUser> users	= GECAMedLists.getListCopy(GecamedUser.class);
					usersById = GECAMedLists.getIdMapReference(GecamedUser.class);
					userTableModel.setUsers(users);
					
					userTable.setRowSelectionInterval(0,0);
//				} catch (FinderException e) {
//					logger.log(Level.WARN, "fetching Users failed", e);
//				}
			}
		}.start();
		setWaitCursor(false);
	}


	/**
	 * sets the Mousecursor of the MainFrame to a WaitCursor and Back
	 *
	 * @param on true=waitcursor false=normalcursor
	 */
	public void setWaitCursor(boolean on) {
		if (on) {
			this.userTable.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
		} else {
			this.userTable.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
		}
	}

	/* (non-Javadoc)
	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	public void actionPerformed(ActionEvent e) {
		if (e.getSource().equals(this.addButton)) {
			addUser();
		} else if (e.getSource().equals(this.saveButton)) {
			GecamedUser selectedUser = getSelectedUser();
			saveUser(selectedUser != null ? selectedUser : lastSelectedUser);
		} else if (e.getSource().equals(this.deleteButton)) {
			int row = this.userTableModel.filteredToModel(this.userTable.getSelectedRow());
			GecamedUser user = this.userTableModel.getUser(row);
			int n = JOptionPane.showConfirmDialog(
				    MainFrame.getInstance(),
				    Translatrix.getTranslationString("um.deletequestion") + "\n" +
				    user.getLogin() + " (" + user.getName() + ")",
				    Translatrix.getTranslationString("admin.usermanagement"),
				    JOptionPane.YES_NO_OPTION);
					if (n == JOptionPane.YES_OPTION) {
						if (user.isPersistent()) {
						try {
							manager.deleteUser(user.getId());
							this.userTableModel.deleteUser(row);
							GECAMedLog.system(AdminModule.MODULE_NAME, "Delete User", "user: " + user.toString() + " has been deleted", null);
						} catch (Throwable ee) {
							// TODO show better Error 
							JOptionPane.showMessageDialog(MainFrame.getInstance(),
									"The user could not be deleted because there is other data referring to him.",
								    "Error deleting User!",
								    JOptionPane.ERROR_MESSAGE);
						}
					}
				}
		} 
	}

	/**
	 * save the given user
	 * @param user
	 */
	public void saveUser(GecamedUser user ) {
		for(GecamedUser usr : userTableModel.getModifiedUsers())
		{
			if (usr == null) return;
    	    
			try {
				boolean newUser = ! usr.isPersistent();

				GecamedUser savedUser = manager.saveUser(usr);
				usr.setId(savedUser.getId());
				usr.setHasChanges(savedUser.hasChanges());
				usermanagementpanel.setModified(savedUser.hasChanges());
				
				userTableModel.fireTableDataChanged();

				if (newUser) {
					GECAMedLog.system(AdminModule.MODULE_NAME, "Create User", "user: " + user.toString() + " has been created");
				} else {
					GECAMedLog.system(AdminModule.MODULE_NAME, "Update User", "user: " + user.toString() + " has been changed");
				}
				
				//* ------------------------------------------------------- */
				// fire message
				/* ------------------------------------------------------- */
				GECAMedMessage mes = new GECAMedMessage(AdminModule.getInstance(),
														MessageListenerRegister.MESSAGE_USER_CHANGED,
														null,
														user);
				MainFrame.fireGECAMedMessage(mes);

			
			} catch (Exception e1) {
				MainFrame.reportServerError(e1);
			}
		}
		userTableModel.clearModifiedUsers();
	    	
	}
	
	public void addUser() {
    	//To avoid inserting more than one line at a time
		if(userTableModel.getValueAt(0, 0)!=null)
		{
			filterField.setText("");
	    	userTableModel.getLoginFilter().setFilter(filterField.getText());
			userTableModel.setFilteringEnabled((filterField.getText().length() > 0), 1);
			userTableModel.fireTableDataChanged();
			
			GecamedUser newUser = new GecamedUser();
			
			//Get first locale from the list
			newUser.setGecamedLocale(localeArray[0]);
			
			newUser.setHasChanges(true);
			newUser.setLastModification(new Date());
			newUser.setModifiedBy(MainFrame.getCurrentUserId());
			userTableModel.addUser(newUser);
			userTable.getSelectionModel().setSelectionInterval(0, 0);
			
			userTable.requestFocus();
			userTable.editCellAt(0,1);
			
			usermanagementpanel.setModified(true);
		}
		
	}
	

	public void setModified(Boolean value)
	{
		super.setModified(value);
	}
	
	public void updateTable() {
		this.userTableModel.fireTableDataChanged();
	}


    /**
     * TableModel to display and edit the users.
     * 
     * @author Johannes Hermen johannes.hermen(at)tudor.lu
     *
     * @version
     * <br>$Log: UserManagementPanel.java,v $
     * <br>Revision 1.32  2013-12-27 18:09:26  donak
     * <br>Cleanup of imports
     * <br>
     * <br>Revision 1.31  2013-07-15 06:18:37  ferring
     * <br>logging changed
     * <br>
     * <br>Revision 1.30  2013-02-19 12:07:34  ferring
     * <br>GECAMedLists changed. Will now automatically load list of all beans
     * <br>
     * <br>Revision 1.29  2011-11-29 09:40:35  ferring
     * <br>"add user"-bug fixed
     * <br>
     * <br>Revision 1.28  2010-06-24 13:06:29  hermen
     * <br>Incomplete - # 523: Null pointer exception while saving a password change
     * <br>http://santec.tudor.lu/trac/gecamed/ticket/523
     * <br>
     * <br>Revision 1.27  2010-04-08 10:56:40  hermen
     * <br>enhanced logging
     * <br>
     * <br>Revision 1.26  2010-04-06 10:00:02  hermen
     * <br>fixed filtering and adding of new users
     * <br>
     * <br>Revision 1.25  2010-03-12 14:17:42  hermen
     * <br>cleanup of panel layouts and icons
     * <br>
     * <br>Revision 1.24  2009-06-02 12:52:59  hermen
     * <br>added search for user/physician
     * <br>
     * <br>Revision 1.23  2009-05-07 08:26:44  hermen
     * <br>handle password changing without restarting
     * <br>
     * <br>Revision 1.22  2009-03-20 10:20:05  hermen
     * <br>*** empty log message ***
     * <br>
     * <br>Revision 1.21  2008-12-08 09:15:23  hermen
     * <br>reloads user-list in physician admin tab if a new user is created
     * <br>
     * <br>Revision 1.20  2008-09-25 09:43:10  heinemann
     * <br>fixed copyrights
     * <br>
     * <br>Revision 1.19  2008-07-04 13:38:58  heinemann
     * <br>fixed generic casting that the new eclipse does not want to accept.
     * <br>
     * <br>Revision 1.18  2008-01-15 10:18:39  hermen
     * <br>updated Javadoc and refactured code
     * <br>
     *
     */
    public class UserTableModel extends FilterTableModel {

		private static final long serialVersionUID = 1L;
		private DateFormat df = DateFormat.getDateInstance();
		private Vector<GecamedUser> data;

		private boolean editable;
		private TextFilter loginFilter;
		private Vector <GecamedUser> modifiedUsers;
		
		@SuppressWarnings("unchecked")
		public void setUsers(Collection<GecamedUser> data) {
			if (data != null) {
				this.data = new Vector(data);
			} else {
				this.data = null;
			}
			setTableData(this.data);
			this.fireTableDataChanged();
		}

		public Vector<GecamedUser> getData() {
			return data;
		}
		
		public Vector<GecamedUser> getModifiedUsers() {
			modifiedUsers=new Vector<GecamedUser>();
			for(GecamedUser usr : data)
			{
				if(usr.hasChanges())
				{
					modifiedUsers.addElement(usr);
				}
			}
			return modifiedUsers;
		}
		public void clearModifiedUsers() {
			
			for(GecamedUser usr : this.modifiedUsers )
			{
				if(usr.hasChanges())
				{
					usr.setHasChanges(false);
				}
			}
			this.modifiedUsers.clear();
			
		}

		/* (non-Javadoc)
		 * @see javax.swing.table.AbstractTableModel#getColumnName(int)
		 */
		public String getColumnName(int column) {
			return columnName[column];
		}

		/* (non-Javadoc)
		 * @see javax.swing.table.TableModel#getRowCount()
		 */
		public int getRowCount() {
		    	if (isFiltering()) {
			    return getFilteredRowCount();
			}
			try {
				return data.size();
			} catch (Exception e) {
				return 0;
			}
		}

		/* (non-Javadoc)
		 * @see javax.swing.table.TableModel#getColumnCount()
		 */
		public int getColumnCount() {
		    return 8;
		}

		/* (non-Javadoc)
		 * @see javax.swing.table.AbstractTableModel#getColumnClass(int)
		 */
		public Class<?> getColumnClass(int column) {
			return columnsClasses[column];
		}

		/* (non-Javadoc)
		 * @see javax.swing.table.TableModel#getValueAt(int, int)
		 */
		public Object getValueAt(int rowIndex, int columnIndex) {
		    	if (isFiltering()) {
			    rowIndex = filteredToModel(rowIndex);
			}
			GecamedUser user = data.get(rowIndex);
			try {
				switch (columnIndex) {
				case 0:
					return user.getId();
				case 1:
					return user.getLogin();
				case 2:
					return user.getName();
				case 3:
					try {
			            return user.getGecamedLocale();
					} catch (Exception e) {
						return new GECAMedLocale(Locale.getDefault());
					}
				case 4:
					return df.format(user.getLastModification());
				case 5:
					try {
						return usersById.get(user.getModifiedBy()).getLogin();						
					} catch (Exception e) {
						return "";
					}
				case 6:
					return user.getPasswordhash();
				case 7:
					return user.getLogin() + " " + user.getName();
				default:
					return "";
				}
			} catch (Exception e) {
				return "";
			}
		}



		/* (non-Javadoc)
		 * @see javax.swing.table.AbstractTableModel#setValueAt(java.lang.Object, int, int)
		 */
		@Override
		public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
		    	if (isFiltering()) {
			    rowIndex = filteredToModel(rowIndex);
			}
			GecamedUser user = data.get(rowIndex);
			try {
				switch (columnIndex) {
				case 0:
					user.setId((Integer)aValue);
					break;
				case 1:
					user.setLogin((String) aValue);
					break;
				case 2:
					user.setName((String) aValue);
					break;
				case 3:
					try {
						user.setGecamedLocale((GECAMedLocale) aValue);
					} catch (Exception e) {
						user.setGecamedLocale(null);
					}
					break;
				case 4:
					break;
				case 5:
					break;
				case 6:
					user.setPasswordhash((String) aValue);
					break;
				default:
					break;
				}
			} catch (Exception e) {
			}
			user.setHasChanges(true);
			usermanagementpanel.setModified(true);
			fireTableDataChanged();
			
		}

		/* (non-Javadoc)
		 * @see javax.swing.table.AbstractTableModel#isCellEditable(int, int)
		 */
		public boolean isCellEditable(int rowIndex, int columnIndex) {
		    	if (isFiltering()) {
			    rowIndex = filteredToModel(rowIndex);
			}
			if (editable && columnIndex != 0 && columnIndex != 4 && columnIndex != 5)
				return true;
			else
				return false;
		}

		public GecamedUser getUser(int row) {
		    if (isFiltering()) {
			    row = filteredToModel(row);
			}
			try {
				return data.get(row);
			} catch (Exception e) {
				return null;
			}
		}

		public void addUser(GecamedUser user) {
			this.data.add(0, user);
			setTableData(this.data);
			this.fireTableDataChanged();
		}

		public void deleteUser(int row) {
			this.data.remove(row);
			setTableData(this.data);
			this.fireTableDataChanged();
		}

		public void setEditable(boolean enable) {
			this.editable = enable;
		}
		
		public TableFilter getLoginFilter() {
			if (loginFilter == null) {
		        	this.loginFilter = new TextFilter();
		        	installFilter(loginFilter, 7);
			}
			return loginFilter;
		}

	}
//  ####################################################

    public class TextFilter implements TableFilter {

	private String searchText = "";

	public boolean accept(Object p_Value) {
		/* ====================================================== */
		if (p_Value instanceof String) {
			/* ------------------------------------------------------- */
		    String text 	= (String) p_Value;
			/* ------------------------------------------------------- */
			if (text.toLowerCase().contains(searchText))
				return true;
			/* ------------------------------------------------------- */
		}
		return false;
		/* ====================================================== */
	}

	public void compile() {
		/* ====================================================== */
		
		/* ====================================================== */
	}

	public boolean isFiltering() {
		/* ====================================================== */
		return true;
		/* ====================================================== */
	}

	public void setFilter(Object p_FilterValue) {
		/* ====================================================== */
		if (p_FilterValue instanceof String) 
			this.searchText  = ((String) p_FilterValue).toLowerCase();
		/* ====================================================== */
	}
	
    }

//  ####################################################
    
	/* (non-Javadoc)
	 * @see lu.tudor.santec.gecamed.core.gui.GECAMedTab#preparetoShowup()
	 */
	@Override
	public void preparetoShowup() {
	}

	/**
	 * enable/disable editing of the panel
	 * @param enable
	 */
	public void enablePanel(boolean enable) {
		this.saveButton.setEnabled(enable);
		this.addButton.setEnabled(enable);
		this.deleteButton.setEnabled(enable);
		this.userTableModel.setEditable(enable);
		this.rolePanel.setEditable(enable);
	}
}
