/*
 * JoinWindow.java, 11 févr. 2006
 * 
 * This file is part of FilmZ.
 *
 * Copyright © 2006 Johan Cwiklinski
 *
 * File :               JoinWindow.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.EventQueue;
import java.awt.event.ActionListener;
import java.beans.PropertyVetoException;
import java.text.MessageFormat;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JTable;
import javax.swing.WindowConstants;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableColumnModel;

import be.xtnd.commons.MessagesCommons;
import be.xtnd.commons.gui.EscapeInternalFrame;
import be.xtnd.commons.gui.MainGui;
import be.xtnd.commons.gui.TableSorter;
import be.xtnd.films.Film;

import com.jeta.forms.components.panel.FormPanel;
import com.jeta.forms.components.separator.TitledSeparator;
import com.jgoodies.looks.plastic.PlasticInternalFrameUI;

/**
 * Fenetre d'affichage des relations fortes des films (acteurs, genres, ...)
 * Chaque fenêtre spécialisée doit étendre cette classe
 * @author Johan Cwiklinski
 * @version 1.0
 */
public abstract class JoinWindow extends EscapeInternalFrame {
	private static final long serialVersionUID = 3193480689837396375L;
	/** Nom de la fenêtre*/
	private TitledSeparator titre;
	protected JButton ajouter, supprimer, fermer;
	protected Integer id_selected;
	protected char mode;
	private ActionListener addListener, delListener;
	/** Tableau d'affichage des données */
	public JTable table;
	/** Objet film référent */
	public Film film;
	protected JoinWindow qf;
	private String fenName, fenType, colName;
	protected JLabel label;
	
	/**
	 * Constructeur par défaut 
	 * @param f film référent
	 * @param icon icône de la fenêtre
	 * @param fenType type de la fenêtre (représentant l'objet fils) 
	 * @param fenName nom textuel de la fenêtre
	 * @param colName nom de la colonne visible du tableau
	 * @param mode d'édition @see be.xtnd.commons.db.Database.NEW @see be.xtnd.commons.db.Database.MODIF
	 * @param label le label d ela fenêtre appelante à modifier pour l'affichage des modifications
	 */
	public JoinWindow(final Film f, ImageIcon icon, String fenType, String fenName, 
			String colName, char mode, JLabel label){
		super();
		super.setFrameIcon(icon);
		this.film = f;
		this.fenName = fenName;
		this.colName = colName;
		this.fenType = fenType;
		this.mode = mode;
		this.label = label;
		qf = this;
        putClientProperty(
                PlasticInternalFrameUI.IS_PALETTE,
                Boolean.TRUE);
		FormPanel pane = new FormPanel( "be/xtnd/gui/descriptions/table_association.jfrm" );
				
		titre = (TitledSeparator)pane.getComponentByName("title");
		Object[] args = {film.getTitre()};
		titre.setText(
				MessageFormat.format(Messages.getString("window.movies.titles."+fenType), args)
			);
		
		ajouter = (JButton)pane.getButton("ajouter");
		ajouter.setText(Messages.getString("window.buttons.add"));
		
		supprimer = (JButton)pane.getButton("supprimer");
		supprimer.setText(Messages.getString("window.buttons.delete"));
		
		fermer = (JButton)pane.getButton("fermer");
		fermer.setText(Messages.getString("window.buttons.close"));
		setCloseListener();
		/*fermer.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				dispose();
			}
		});*/
		getRootPane().setDefaultButton(fermer);
		
		table = pane.getTable("liste");
		table.getTableHeader().setReorderingAllowed(false);
		
		displayQueryResults();
		
		setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		setClosable(true);
		setIconifiable(true);
		
		add(pane);
		
		pack();
		setVisible(true);
		setName((film.getId()==null)?fenName+"new":fenName+film.getId());
		setLocation(MainGui.centerOnDesktop(getSize()));
		MainGui.desktop.add(this,JLayeredPane.POPUP_LAYER);
		try {
			setSelected(true);
		} catch (PropertyVetoException e) {}			
	}
	
	/**
	 * Affiche la liste jointe dans le tableau
	 */
	public void displayQueryResults() {
		MainGui.statusBar.setText("Building "+fenType+"'s list.");

		EventQueue.invokeLater(new Runnable() {
			public void run() {
				String[] columnTitle = {"id", colName,"index"};
				Object[][] obj = buildArray();

				table.setModel(new MyTableModel(columnTitle, obj));

		        TableSorter sorter = new TableSorter(table.getModel());
		        table.setModel(sorter);
		        sorter.setTableHeader(table.getTableHeader());
		        sorter.setSortingStatus(1, TableSorter.ASCENDING);
		        table.getTableHeader().setToolTipText(MessagesCommons.getString("window.messages.tri"));
				
		        TableColumnModel columnModel = table.getColumnModel();
				columnModel.getColumn(0).setPreferredWidth(0);
				columnModel.getColumn(0).setMinWidth(0);
				columnModel.getColumn(0).setMaxWidth(0);
				columnModel.getColumn(2).setPreferredWidth(0);
				columnModel.getColumn(2).setMinWidth(0);
				columnModel.getColumn(2).setMaxWidth(0);
				
				MainGui.statusBar.setText("");
				MainGui.verifUnicite((film.getId()==null)?fenName+"new":fenName+film.getId(),null);
			}
		});
	}
	
	protected abstract Object[][] buildArray(); 
			
	/**
	 * Modèle pour affichage de la liste 
	 */
    public class MyTableModel extends AbstractTableModel {
		private static final long serialVersionUID = 3282200795160431498L;
		private String[] columnNames;
        private Object[][] data;
    	        
        MyTableModel(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 false;
        }

        /**
         * @param value
         * @param row
         * @param col
         */
        public void setValueAt(Object value, int row, int col) {
            data[row][col] = value;
            fireTableCellUpdated(row, col);
        }
    }

	/**
	 * Supprime le listener existant et le remplace par celui en paramètre
	 * @param addListener addListener à définir.
	 */
	protected void setAddListener(ActionListener addListener) {
		ajouter.removeActionListener(this.addListener);
		this.addListener = addListener;
		ajouter.addActionListener(this.addListener);
	}

	/**
	 * Supprime le listener existant et le remplace par celui en paramètre
	 * @param delListener delListener à définir.
	 */
	protected void setDelListener(ActionListener delListener) {
		supprimer.removeActionListener(delListener);
		this.delListener = delListener;
		supprimer.addActionListener(this.delListener);
	}

	protected abstract void setCloseListener();
}
