/*
 * AdvancedSearch.java, 1 juin 2006
 * 
 * This file is part of FilmZ.
 *
 * Copyright © 2006 Johan Cwiklinski
 *
 * File :               AdvancedSearch.java
 * Author's email :     johan@x-tnd.be
 * Author's Website :   http://www.x-tnd.be/
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 * 
 */

/**
 * 
 */
package be.xtnd.films.gui;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.swing.AbstractCellEditor;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableColumnModel;

import be.xtnd.commons.MessagesCommons;
import be.xtnd.commons.db.ResultSetTableModelFactory;
import be.xtnd.commons.gui.EscapeInternalFrame;
import be.xtnd.commons.gui.MainGui;
import be.xtnd.commons.gui.TableSorter;
import be.xtnd.films.Film;
import be.xtnd.films.plugins.RechercheWeb;
import be.xtnd.gui.FilmzMain;
import be.xtnd.gui.Menus;

import com.jeta.forms.components.panel.FormPanel;
import com.jeta.forms.components.separator.TitledSeparator;
import com.toedter.calendar.JYearChooser;
import com.toedter.components.JSpinField;

/**
 * @author Johan Cwiklinski
 *
 */
public class AdvancedSearch extends Films{
	/** Nom de la fenêtre */
	public static final String LIST_NAME = "recherche_avancee";
	private JTable directors_search, types_search, origins_search, actors_search;
	private String[] cols_headers = {"type", "mode", "valeur", "chercher"};
	private Object[][] directors_content, types_content, origins_content, actors_content;
    private Border headerBorder = UIManager.getBorder("TableHeader.cellBorder");
    private Color couleur, police_couleur;
	private static final String DIRECTORS = "directors";
	private static final String TYPES = "types";
	private static final String ORIGINS = "origins";
	private static final String ACTORS = "actors";
	private JComboBox search_type, search_mode;

	/**
	 * 
	 *
	 */
	public AdvancedSearch(){
		super();
		new Liste();
	}
	
	private void drawTable(JTable t, Object[][] datas, String name){
		t.setModel(new SearchTableModel(cols_headers, datas));
		t.addMouseListener(new MouseAdapter(){
			public void mousePressed(MouseEvent e){
				JTable tbl = (JTable)e.getComponent();
				if(InputEvent.BUTTON1_MASK != 0)
					tbl.changeSelection(tbl.rowAtPoint(e.getPoint()),0,false,false);
			}			
		});
		t.getTableHeader().setReorderingAllowed(false);
		t.getTableHeader().setVisible(false);
		t.getTableHeader().setPreferredSize(new Dimension(0,0));
		t.getTableHeader().setMaximumSize(new Dimension(0,0));
		t.getColumnModel().getColumn(0).setCellEditor(new DefaultCellEditor(search_type));
		t.getColumnModel().getColumn(0).setPreferredWidth(30);
		t.getColumnModel().getColumn(0).setMinWidth(30);
		t.getColumnModel().getColumn(0).setMaxWidth(50);
		t.getColumnModel().getColumn(1).setCellEditor(new DefaultCellEditor(search_mode));
		t.getColumnModel().getColumn(1).setPreferredWidth(50);
		t.getColumnModel().getColumn(1).setMinWidth(50);
		t.getColumnModel().getColumn(1).setMaxWidth(70);
		t.getColumnModel().getColumn(3).setCellEditor(new ButtonEditor(name));
		t.getColumnModel().getColumn(3).setCellRenderer(new ButtonCellRenderer());
		t.getColumnModel().getColumn(3).setPreferredWidth(30);
		t.getColumnModel().getColumn(3).setMinWidth(30);
		t.getColumnModel().getColumn(3).setMaxWidth(30);	
		t.updateUI();
		MainGui.verifUnicite(LIST_NAME, null);
	} 
	
	/**
	 * 
	 */
	public class Liste extends EscapeInternalFrame{
		private static final long serialVersionUID = 5635082151587360418L;
		private Integer id_selected;
		private JPopupMenu popup;
		/* list header */
		private TitledSeparator chercher_label;
		private JButton search, reinit, add_director, del_director, add_type, del_type,
			add_origin, del_origin, add_actor, del_actor;
		private JToggleButton specials_button;
		private JTabbedPane tabs;
		private JLabel titre_label, date_label, date_debut_label, date_fin_label, 
			duree_label, duree_min_label, duree_max_label, resume_label;
		private JYearChooser date_debut, date_fin;
		private JSpinField duree_min, duree_max;
		private JComboBox date_mode, duree_mode, directors_mode, types_mode, origins_mode, actors_mode;
		private JTextField titre, resume;
		private ArrayList<String> modes_date, modes_duree, modes_search, modes_types;
		/** Ordre de tri des colonnes */
		public List<Object> storeSort = null;
		/** TableSorter de la JTable */
		public TableSorter sorter; 

		/**
		 * Affiche la liste des films avec les paramètres par défaut.
		 *
		 */
		public Liste(){		
			this(new ResultSetTableModelFactory(FilmzMain.db));

			setLocation(MainGui.centerOnDesktop(getSize()));
			setVisible(true);
			MainGui.desktop.add(this);	
		}
		
		/**
		 * Affiche la liste des films à la position spécifiée
		 * @param position point position de la fenêtre à l'affichage
		 */
		public Liste(Point position){
			this(new ResultSetTableModelFactory(FilmzMain.db));

			if(position==null) position = MainGui.centerOnDesktop(getSize());
			setLocation(position);
			setVisible(true);
			MainGui.desktop.add(this);	
		}
		
		/**
		 * Affiche la liste des films avec le ResultSet associé
		 * @param f ResultSetTableModelFactory à afficher
		 * 
		 * @see ResultSetTableModelFactory
		 */
		public Liste(ResultSetTableModelFactory f) {
			setIconifiable(false);
			setClosable(true);
			setResizable(true);
			setMaximizable(true);
			setName(LIST_NAME);
			setSize(550, 450);
			
			modes_date = new ArrayList<String>(3);
			modes_date.add(Messages.getString("window.advanced_search.modes.date.between"));
			modes_date.add(Messages.getString("window.advanced_search.modes.date.before"));
			modes_date.add(Messages.getString("window.advanced_search.modes.date.after"));

			modes_duree = new ArrayList<String>(3);
			modes_duree.add(Messages.getString("window.advanced_search.modes.duree.between"));
			modes_duree.add(Messages.getString("window.advanced_search.modes.duree.inf"));
			modes_duree.add(Messages.getString("window.advanced_search.modes.duree.sup"));

			modes_search = new ArrayList<String>(2);
			modes_search.add(Messages.getString("window.advanced_search.modes.like"));
			modes_search.add(Messages.getString("window.advanced_search.modes.is"));
			
			modes_types = new ArrayList<String>(2);
			modes_types.add(Messages.getString("window.advanced_search.modes.and"));
			modes_types.add(Messages.getString("window.advanced_search.modes.or"));

			film = new Film();
			FormPanel pane = new FormPanel( "be/xtnd/gui/descriptions/advanced_search.jfrm" );
			getContentPane().add(pane);
			
			tabs = pane.getTabbedPane("tabbed");
			tabs.setTitleAt(0, Messages.getString("window.advanced_search.tabs.general"));
			tabs.setTitleAt(1, Messages.getString("window.advanced_search.tabs.directors"));
			tabs.setTitleAt(2, Messages.getString("window.advanced_search.tabs.types"));
			tabs.setTitleAt(3, Messages.getString("window.advanced_search.tabs.origins"));
			tabs.setTitleAt(4, Messages.getString("window.advanced_search.tabs.actors"));
			
			chercher_label = (TitledSeparator)pane.getComponentByName("title_label");
			chercher_label.setText(Messages.getString("window.advanced_search.titles.list"));

			titre_label = pane.getLabel("titre_label");
			titre_label.setText(Messages.getString("window.movies.labels.title"));

			titre = pane.getTextField("titre");
			
			date_label = pane.getLabel("date_label");
			date_label.setText(Messages.getString("window.movies.labels.year"));
			
			date_mode = pane.getComboBox("date_mode");
			commons.buildCombo(date_mode, modes_date);
			date_mode.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e) {
					if(date_mode.getSelectedItem().equals(
							Messages.getString(
									"window.advanced_search.modes.date.between"))){
						date_debut.setEnabled(true);
						date_fin.setEnabled(true);
					}
					if(date_mode.getSelectedItem().equals(
							Messages.getString(
									"window.advanced_search.modes.date.before"))){
						date_debut.setEnabled(false);
						date_fin.setEnabled(true);
					}
					if(date_mode.getSelectedItem().equals(
							Messages.getString(
									"window.advanced_search.modes.date.after"))){
						date_debut.setEnabled(true);
						date_fin.setEnabled(false);
					}						
					if(date_mode.getSelectedIndex() == 0){
						date_debut.setEnabled(false);
						date_fin.setEnabled(false);
					}						
				}
			});
			
			date_debut_label = pane.getLabel("date_debut_label");
			date_debut_label.setText(Messages.getString("window.advanced_search.labels.begin"));
			
			date_debut = (JYearChooser)pane.getComponentByName("date_debut");
			date_debut.setStartYear(0);date_debut.setEndYear(9999);
			date_debut.setPreferredSize(new Dimension(60,20));
			date_debut.setHorizontalAlignment(SwingConstants.RIGHT);
			date_debut.setEnabled(false);
			
			date_fin_label = pane.getLabel("date_fin_label");
			date_fin_label.setText(Messages.getString("window.advanced_search.labels.end"));
			
			date_fin = (JYearChooser)pane.getComponentByName("date_fin");
			date_fin.setStartYear(0);date_fin.setEndYear(9999);
			date_fin.setPreferredSize(new Dimension(60,20));
			date_fin.setHorizontalAlignment(SwingConstants.RIGHT);
			date_fin.setEnabled(false);

			duree_label = pane.getLabel("duree_label");
			duree_label.setText(Messages.getString("window.advanced_search.labels.length"));
			
			duree_mode = pane.getComboBox("duree_mode");
			commons.buildCombo(duree_mode, modes_duree);
			duree_mode.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e) {
					if(duree_mode.getSelectedItem().equals(
							Messages.getString(
									"window.advanced_search.modes.duree.between"))){
						duree_min.setEnabled(true);
						duree_max.setEnabled(true);
					}
					if(duree_mode.getSelectedItem().equals(
							Messages.getString(
									"window.advanced_search.modes.duree.inf"))){
						duree_min.setEnabled(false);
						duree_max.setEnabled(true);
					}
					if(duree_mode.getSelectedItem().equals(
							Messages.getString(
									"window.advanced_search.modes.duree.sup"))){
						duree_min.setEnabled(true);
						duree_max.setEnabled(false);
					}
					if(duree_mode.getSelectedIndex() == 0){
						duree_min.setEnabled(false);
						duree_max.setEnabled(false);
					}
				}
			});
			
			duree_min_label = pane.getLabel("duree_min_label");
			duree_min_label.setText(Messages.getString("window.advanced_search.labels.min"));
			
			duree_min = (JSpinField)pane.getComponentByName("duree_min");
			duree_min.setEnabled(false);
			
			duree_max_label = pane.getLabel("duree_max_label");
			duree_max_label.setText(Messages.getString("window.advanced_search.labels.max"));
			
			duree_max = (JSpinField)pane.getComponentByName("duree_max");
			duree_max.setEnabled(false);
			
			resume_label = pane.getLabel("resume_label");
			resume_label.setText(Messages.getString("window.movies.labels.summary"));
			
			resume = pane.getTextField("resume");
			
			search_type = commons.buildNewCombo(modes_types);
			search_type.removeItemAt(0);
			search_type.setSelectedIndex(1);

			search_mode = commons.buildNewCombo(modes_search);
			search_mode.removeItemAt(0);
			
			directors_mode = pane.getComboBox("directors_mode");
			commons.buildCombo(directors_mode, modes_types);
			directors_mode.removeItemAt(0);
			
			directors_search = pane.getTable("directors_search");
			directors_content = new Object[0][];
			drawTable(directors_search, directors_content, DIRECTORS);
			
			add_director = (JButton)pane.getButton("add_director");
			add_director.setToolTipText(Messages.getString("window.advanced_search.tooltips.add_director"));
			add_director.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e) {
					addDirector(directors_search.getSelectedRow());
				}
			});
			
			del_director = (JButton)pane.getButton("del_director");
			del_director.setToolTipText(Messages.getString("window.advanced_search.tooltips.del"));
			del_director.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e) {
					if(directors_content.length>0)
						delDirector(directors_search.getSelectedRow());
				}
			});
			
			types_mode = pane.getComboBox("types_mode");
			commons.buildCombo(types_mode, modes_types);
			types_mode.removeItemAt(0);

			types_search = pane.getTable("types_search");
			types_content = new Object[0][];
			drawTable(types_search, types_content, TYPES);
			
			add_type = (JButton)pane.getButton("add_type");
			add_type.setToolTipText(Messages.getString("window.advanced_search.tooltips.add_type"));
			add_type.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e) {
					addType(types_search.getSelectedRow());
				}
			});
			
			del_type = (JButton)pane.getButton("del_type");
			del_type.setToolTipText(Messages.getString("window.advanced_search.tooltips.del"));
			del_type.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e) {
					if(types_content.length>0)
						delType(types_search.getSelectedRow());
				}				
			});
			
			origins_mode = pane.getComboBox("origins_mode");
			commons.buildCombo(origins_mode, modes_types);
			origins_mode.removeItemAt(0);

			origins_search = pane.getTable("origins_search");
			origins_content = new Object[0][];
			drawTable(origins_search, origins_content, ORIGINS);
			
			add_origin = (JButton)pane.getButton("add_origin");
			add_origin.setToolTipText(Messages.getString("window.advanced_search.tooltips.add_origin"));
			add_origin.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e) {
					addOrigin(origins_search.getSelectedRow());
				}
			});
			
			del_origin = (JButton)pane.getButton("del_origin");
			del_origin.setToolTipText(Messages.getString("window.advanced_search.tooltips.del"));
			del_origin.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e) {
					if(origins_content.length>0)
						delOrigin(origins_search.getSelectedRow());
				}
			});

			actors_mode = pane.getComboBox("actors_mode");
			commons.buildCombo(actors_mode, modes_types);
			actors_mode.removeItemAt(0);

			actors_search = pane.getTable("actors_search");
			actors_content = new Object[0][];
			drawTable(actors_search, actors_content, ACTORS);

			add_actor = (JButton)pane.getButton("add_actor");
			add_actor.setToolTipText(Messages.getString("window.advanced_search.tooltips.add_actor"));
			add_actor.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e) {
					addActor(actors_search.getSelectedRow());
				}
			});
			
			del_actor = (JButton)pane.getButton("del_actor");
			del_actor.setToolTipText(Messages.getString("window.advanced_search.tooltips.del"));
			del_actor.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e) {
					if(actors_content.length>0)
						delActor(actors_search.getSelectedRow());
				}
			});

			search = (JButton)pane.getButton("search_button");
			search.setText(Messages.getString("window.search.button"));
			search.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					try {
			        	storeSort = sorter.getSortingColumns();
						displayQueryResults(constructQuery());
					} catch (Exception e1) {e1.printStackTrace();}
				}
			});
			
			reinit = (JButton)pane.getButton("reinit_button");
			reinit.setText(Messages.getString("window.search.reinit"));
			reinit.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e) {
					//numeroSearch.setValue(0);
					//genresSearch.setSelectedIndex(0);
					//titreSearch.setText("");
					storeSort = null;
					displayQueryResults(Film.LIST_QUERY);
					/*displayQueryResults(
							(specials_button.isSelected())?Film.LIST_QUERY_SPECIALS:Film.LIST_QUERY
							);*/
				}
			});
			
			specials_button = (JToggleButton)pane.getButton("specials_button");
			specials_button.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e) {
					displayQueryResults(Film.LIST_QUERY);
					/*displayQueryResults(
							(specials_button.isSelected())?Film.LIST_QUERY_SPECIALS:Film.LIST_QUERY
							);*/
				}
			});
			specials_button.setVisible(FilmzMain.isParentalActive());

			table = pane.getTable("liste");
			factory = f;
	    	this.getRootPane().setDefaultButton(search);
			table.getTableHeader().setReorderingAllowed(false);
			table.addMouseListener(new MouseAdapter(){
				public void mousePressed(MouseEvent e){
			  	  	int nModifier = e.getModifiers();
			    	if ((nModifier & InputEvent.BUTTON3_MASK) != 0) {
						id_selected = new Integer(table.getValueAt(table.rowAtPoint(e.getPoint()),0).toString());
						table.changeSelection(table.rowAtPoint(e.getPoint()),0,false,false);
						popup.show((Component)e.getSource(),e.getX(),e.getY());
			      	}
		            if (e.getClickCount() == 2) {// double-click
		            	id_selected = new Integer(table.getValueAt(table.rowAtPoint(e.getPoint()),0).toString());
						if(MainGui.verifUnicite("film_"+id_selected,null)){
							modifieFilm(id_selected);
						}
					}

				}
			});
			displayQueryResults(Film.LIST_QUERY);
			/*displayQueryResults(
					(specials_button.isSelected())?Film.LIST_QUERY_SPECIALS:Film.LIST_QUERY
					);*/
			
			popup = new JPopupMenu();
			JMenu menuTri = new JMenu(Messages.getString("window.table_popup.order"));
			popupEntries(popup, menuTri, Messages.getString("window.table_popup.order.number"),"orderOrdre",null);
			popupEntries(popup, menuTri, Messages.getString("window.table_popup.order.title"),"orderTitle",null);
			popupEntries(popup, menuTri, Messages.getString("window.table_popup.order.type"),"orderGenre",null);
			JMenu menuFiltre = new JMenu(Messages.getString("window.table_popup.filter"));
			popupEntries(popup, menuFiltre, Messages.getString("window.table_popup.order.type"),"filterGenre",null);
			
			popupEntries(popup, Messages.getString("window.table_popup.new"),"new",Menus.NEW_IMAGE);
			popupEntries(popup, Messages.getString("window.table_popup.modif"),"detailled",Menus.FILMZ_ICON);
			popup.addSeparator();
			popupEntries(popup, Messages.getString("window.table_popup.web"),"web",Menus.SEARCH_IMAGE);
			popup.addSeparator();
			popupEntries(popup, Messages.getString("window.table_popup.del"),"del",Menus.DELETE_IMAGE);

			table.add(popup);
			
			JTableHeader head = table.getTableHeader();
			couleur = head.getBackground();
			police_couleur = head.getForeground();

		}
		
		/**
		 * Construit la requête de recherche
		 * 
		 * @return chaîne sql de recherche de film
		 * @throws Exception
		 */
		public String constructQuery() throws Exception{
			boolean search = false;
			/*StringBuffer sb = new StringBuffer(
					(specials_button.isSelected())?Film.BASE_LIST_QUERY_SPECIALS:Film.BASE_LIST_QUERY
					);
			if(!titreSearch.getText().trim().equals("")){
				search=true;
				sb.append(" WHERE (titre LIKE '%"+titreSearch.getText()+"%' OR sous_titre LIKE '%"+titreSearch.getText()+"%')");
			}
			if(numeroSearch.getValue()>0){
				if(search) sb.append(" AND ");
				else sb.append(" WHERE ");
				search=true;
				sb.append((specials_button.isSelected())?Film.TABLE_SPECIALS:Film.TABLE+"."+Film.PK+"="+numeroSearch.getValue());
			}
			if(genresSearch.getSelectedIndex()>0){
				if(search) sb.append(" AND ");
				else sb.append(" WHERE ");
				search=true;
				sb.append("genre='"+genresSearch.getSelectedItem()+"'");				
			}
			sb.append((specials_button.isSelected())?Film.GROUP_BY_SPECIALS:Film.GROUP_BY);
			sb.append(Film.ORDER_BY);*/
			String qry = new String();
			//qry = sb.toString();
			return qry;
		}
		
		private void addDirector(int row){
			directors_content = addLine(directors_content, row);
			drawTable(directors_search, directors_content,DIRECTORS);
			directors_search.changeSelection(row,0,false,false);
		}
		private void addType(int row){
			types_content = addLine(types_content, row);
			drawTable(types_search, types_content,TYPES);
			types_search.changeSelection(row,0,false,false);
		}
		private void addOrigin(int row){
			origins_content = addLine(origins_content, row);
			drawTable(origins_search, origins_content,ORIGINS);
			origins_search.changeSelection(row,0,false,false);
		}
		private void addActor(int row){
			actors_content = addLine(actors_content, row);
			drawTable(actors_search, actors_content,ACTORS);
			actors_search.changeSelection(row,0,false,false);
		}

		private Object[][] addLine(Object[][] datas, int row){
			int in = datas.length+1;
			if(row == -1)row = in - 1;
			Object[][] memo_lignes = datas.clone();
			Object[] o = new Object[]{
					search_type.getSelectedItem(),
					search_mode.getSelectedItem(),
					"", 
					"..."};
			
			datas = new Object[in][];
			for(int i = 0 ; i < in ; i++){
				if(i < row) datas[i] = memo_lignes[i];
				if(i == row) datas[i] = o;
				if(i > row) datas[i] = memo_lignes[i-1];
			}
			return datas;
		}
		
		private void delDirector(int row){
			directors_content = delLine(directors_content, row);
			drawTable(directors_search, directors_content, DIRECTORS);			
			directors_search.changeSelection(row,0,false,false);
		}
		private void delType(int row){
			types_content = delLine(types_content, row);
			drawTable(types_search, types_content,TYPES);			
			types_search.changeSelection(row,0,false,false);
		}
		private void delOrigin(int row){
			origins_content = delLine(origins_content, row);
			drawTable(origins_search, origins_content,ORIGINS);			
			origins_search.changeSelection(row,0,false,false);
		}
		private void delActor(int row){
			actors_content = delLine(actors_content, row);
			drawTable(actors_search, actors_content,ACTORS);			
			actors_search.changeSelection(row,0,false,false);
		}

		private Object[][] delLine(Object[][] datas, int row){
			int in = datas.length-1;
			Object[][] memo_lignes = datas.clone();
			
			datas = new Object[in][];
			for(int i = 0 ; i < memo_lignes.length ; i++){
				if(i < row) datas[i] = memo_lignes[i];
				if(i > row) datas[i-1] = memo_lignes[i];
			}
			return datas;
		}
		
		/**
		 * Affiche les données d'une requête sql dans une JTable
		 * @param q requête à exécuter
		 */
		public void displayQueryResults(final String q) {
			MainGui.statusBar.setText("Contacting database...");

			EventQueue.invokeLater(new Runnable() {
				public void run() {
					try {
						table.setModel(factory.getResultSetTableModel(q));
						
				        sorter = new TableSorter(table.getModel());
				        if(storeSort!=null){
				        	sorter.setSortingColumns(storeSort);
				        }
				        
				        table.setModel(sorter);
				        sorter.setTableHeader(table.getTableHeader());
				        table.getTableHeader().setToolTipText(MessagesCommons.getString("window.messages.tri"));
						
				        TableColumnModel columnModel = table.getColumnModel();
						columnModel.getColumn(0).setPreferredWidth(40);
						columnModel.getColumn(0).setMinWidth(40);
						columnModel.getColumn(0).setMaxWidth(40);
						columnModel.getColumn(3).setPreferredWidth(120);
						columnModel.getColumn(3).setMinWidth(120);
						columnModel.getColumn(3).setMaxWidth(120);
						columnModel.getColumn(4).setPreferredWidth(20);
						columnModel.getColumn(4).setMinWidth(20);
						columnModel.getColumn(4).setMaxWidth(20);						

						setTitle(Messages.getString("window.advanced_search.titles.list")+" ("+table.getRowCount()+")");

						MainGui.verifUnicite(LIST_NAME, null);
						MainGui.statusBar.setText("");
					} catch (SQLException ex) {
						MainGui.statusBar.setText("Error contacting database !");
						JOptionPane.showMessageDialog(Liste.this,
								new String[] { // Display a 2-line message
								ex.getClass().getName() + ": ", ex.getMessage() });
						MainGui.statusBar.setText("");					
					}
				}
			});
		}	
	
		/**
		 * Affiche la fenêtre d'ajout de film
		 * Utile pour appels depuis une classe 
		 * externe (notamment pour le raccourci d'ajout
		 * de film)
		 */
		public void ajoute(){
			nouveauFilm();
		}
		
		@Override
		protected void popupActions(ActionEvent event){
			String command = event.getActionCommand();
			if(command.equals("new")){
				if(MainGui.verifUnicite(NEW_NAME,null)){
					nouveauFilm();
				}
			}else if(command.equals("del")){
				supprimeFilm(id_selected);
			}else if(command.equals("detailled")){
				if(MainGui.verifUnicite("film_"+id_selected,null)){
					modifieFilm(id_selected);
				}
			}else if(command.equals("web")){
				if(MainGui.verifUnicite("web_film_"+id_selected,null)){
					film = new Film(id_selected);
					new RechercheWeb(film.getTitre(), film);
				}				
			}
		}	
	}
	
	class SearchTableModel extends AbstractTableModel {
		private static final long serialVersionUID = -7078895566289532643L;
		private boolean DEBUG = true;
		private String[] columnNames;

		private Object[][] data;

		SearchTableModel(String[] colNames, Object[][] rowsDatas) {
			this.columnNames = colNames;
			this.data = rowsDatas;
		}
		
		/**
		 * @return int
		 */
		public int getColumnCount() {
			return columnNames.length;
		}

		/**
		 * @return int
		 */
		public int getRowCount() {
			return data.length;
		}

		/**
		 * @param col
		 * @return String
		 */
		public String getColumnName(int col) {
			return columnNames[col];
		}

		/**
		 * @param row
		 * @param col
		 * @return Object
		 */
		public Object getValueAt(int row, int col) {
			return data[row][col];
		}

		/**
		 * @param c
		 * @return Class
		 */
		public Class<?> getColumnClass(int c) {
			return getValueAt(0, c).getClass();
		}

		/**
		 * @param row
		 * @param col
		 * @return boolean
		 */
		public boolean isCellEditable(int row, int col) {
			return true;
		}

		/**
		 * @param value
		 * @param row
		 * @param col
		 */
		public void setValueAt(Object value, int row, int col) {
			if (DEBUG) {
				System.out.println("Setting value at " + row + "," + col
						+ " to " + value + " (an instance of "
						+ value.getClass() + ")");
			}

			data[row][col] = value;
			fireTableCellUpdated(row, col);

			if (DEBUG) {
				System.out.println("New value of data:");
				printDebugData();
			}
		}

		private void printDebugData() {
			int numRows = getRowCount();
			int numCols = getColumnCount();

			for (int i = 0; i < numRows; i++) {
				System.out.print("    row " + i + ":");
				for (int j = 0; j < numCols; j++) {
					System.out.print("  " + data[i][j]);
				}
				System.out.println();
			}
			System.out.println("--------------------------");
		}
	}
	

	private class ButtonEditor extends AbstractCellEditor implements TableCellEditor {
		private static final long serialVersionUID = -2099667812173290707L;
		JButton button;
    	protected static final String EDIT = "edit";
    	private String dest; 
	
    	/**
    	 * @param d
    	 */
    	public ButtonEditor(String d) {
    		this.dest = d;
    		button = new JButton();
    		
    		button.addMouseListener(new MouseAdapter(){
				public void mousePressed(MouseEvent e){
					
					if(dest.equals(DIRECTORS)){//cas réalisateurs
						int row = directors_search.getSelectedRow();
						new Realisateurs().getList(directors_content[row]);
					}
					
					if(dest.equals(TYPES)){//cas genres
						int row = types_search.getSelectedRow();
						new Genres().getList(types_content[row]);
					}
					
					if(dest.equals(ORIGINS)){//cas origines
						int row = origins_search.getSelectedRow();
						new Origines().getList(origins_content[row]);
					}
					
					if(dest.equals(ACTORS)){//cas acteurs
						int row = actors_search.getSelectedRow();
						new Acteurs().getList(actors_content[row]);
					}
				}    			
    		});
    		button.setBorderPainted(true);
    	}
	
    	/**
    	 * @return Object 
    	 */
    	public Object getCellEditorValue() {
    		return button.getText();
    	}
	
    	/**
    	 * @param table
    	 * @param value
    	 * @param isSelected
    	 * @param row
    	 * @param column
    	 * @return Component
    	 */
    	public Component getTableCellEditorComponent(JTable table,
	                            Object value,
	                            boolean isSelected,
	                            int row,
	                            int column) {
    		button.setText((String)value);
    		return button;
    	}
    }
    
    class ButtonCellRenderer extends DefaultTableCellRenderer {
		private static final long serialVersionUID = 3451430386728843481L;
		/**
		 * 
		 *
		 */
		public ButtonCellRenderer() {
		    super();
		}
    	/**
    	 * @param table
    	 * @param value
    	 * @param isSelected
    	 * @param hasFocus
    	 * @param row
    	 * @param column
    	 * @return Component
    	 */
		public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
		  		boolean hasFocus, int row, int column) {
			JLabel cell = (JLabel) super.getTableCellRendererComponent(table, value, 
	        		isSelected, hasFocus, row, column);
			cell.setBorder(headerBorder);
			cell.setBackground(couleur);
			cell.setForeground(police_couleur);
			cell.setHorizontalAlignment(SwingConstants.CENTER);
	        return cell;
		}
	}
}
