/*
 * SimpleObjectWindow.java, 12 févr. 2006
 * 
 * This file is part of FilmZ.
 *
 * Copyright © 2006 Johan Cwiklinski
 *
 * File :               SimpleObjectWindow.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.Component;
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.beans.PropertyVetoException;
import java.sql.SQLException;
import java.text.MessageFormat;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
import javax.swing.table.TableColumnModel;

import be.xtnd.commons.GuiCommons;
import be.xtnd.commons.MessagesCommons;
import be.xtnd.commons.db.Database;
import be.xtnd.commons.db.ResultSetTableModel;
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.JoinClass;
import be.xtnd.gui.FilmzMain;
import be.xtnd.gui.Menus;

import com.jeta.forms.components.panel.FormPanel;
import com.jeta.forms.components.separator.TitledSeparator;

/**
 * @author Johan Cwiklinski
 * @version 1.0
 */
public abstract class SimpleObjectWindow {
	private String fenListName, fenNewName, fenModifName, typeObject, listQuery;
	protected boolean select = false;
	protected JoinClass object;
	protected JTextField textfield;
	protected JTable table;
	private ResultSetTableModelFactory factory; 
	protected String toSelect = "";
	protected JoinWindow af;
	protected Object[] objet;
	protected boolean fromJoin = true;
	protected Liste liste;
	protected GuiCommons commons = new GuiCommons(Messages.getBundle());
	protected char mode;
	private ImageIcon icon;

	protected SimpleObjectWindow(String type, ImageIcon icon, String listname, 
			String modifname, String newname, String listQuery){
		this.typeObject = type;
		this.icon = icon;
		this.fenListName = listname;
		this.fenModifName = modifname;
		this.fenNewName = newname;
		this.listQuery = listQuery;
	}
	
	/** Affiche la liste */
	public void getList(){
		liste = new Liste();
	}
	
	/**
	 * Affiche la liste
	 * @param obj
	 */
	public void getList(Object[] obj){
		this.fromJoin = false;
		this.objet = obj;
		this.select = true;
		liste = new Liste();
	}
	
	/**
	 * Affiche la liste  
	 * @param af fenêtre appelante
	 */
	public void getList(JoinWindow af){
		this.af = af;
		//this.toSelect="";
		this.select = true;
		liste = new Liste();
	}

	/** Affiche la fenêtre de création d'un objet */
	public void nouveau(){
		initObject(null);
		mode = Database.NEW;
		new DetailWindow();
	}
	
	/**
	 * Affiche la fenêtre de modification d'un objet
	 * @param id identifiant de l'objet à modifier
	 */
	public void modifier(Integer id){
		initObject(id);
		mode =Database.MODIF;
		new DetailWindow();
	}
	
	/**
	 * Supprime un objet de la base
	 * @param id identifiant d el'objet à supprimer
	 */
	public void supprimer(Integer id){
		initObject(id);
		Object[] args = {object.getValeur()};
		int result = 0;
		int response = JOptionPane.showConfirmDialog(
				MainGui.desktop, 
				MessageFormat.format(Messages.getString("window."+typeObject+".messages.deleted.confirm"), args),
				Messages.getString("window."+typeObject+".messages.deleted.title"),
				JOptionPane.YES_NO_OPTION,
				JOptionPane.WARNING_MESSAGE);

		if (response == JOptionPane.YES_OPTION) {
			result = object.delete(id);

			String strMessage = new String();
			int typeMessage = 0;
			String titreMessage = new String();
			
			if(result>0){
				strMessage = MessageFormat.format(
						Messages.getString("window."+typeObject+".messages.deleted"),
						args);
				titreMessage = Messages.getString("window."+typeObject+".messages.deleted.title");
				typeMessage = JOptionPane.INFORMATION_MESSAGE;
			}else if(result==-2){
				Object[] argsList = {object.getValeur(), object.fkTitre()};
				strMessage = MessageFormat.format(
						Messages.getString("window."+typeObject+".messages.fk"), 
						argsList);
				titreMessage = MessagesCommons.getString("window.messages.error");
				typeMessage = JOptionPane.ERROR_MESSAGE;
			}else{
				strMessage = MessageFormat.format(
						Messages.getString("window."+typeObject+".messages.notdeleted"),
						args);
				titreMessage = MessagesCommons.getString("window.messages.error");
				typeMessage = JOptionPane.ERROR_MESSAGE;
			}
			JOptionPane.showMessageDialog(
					MainGui.desktop, 
					strMessage,
					titreMessage,
					typeMessage);							
			try {
				if(!MainGui.verifUnicite(fenListName, null)){
					liste.displayQueryResults(constructQuery());
				}
			} catch (Exception e1) {e1.printStackTrace();}
		}
	}
	
	protected abstract void initObject(Integer id);
	
	protected abstract void ajout(Integer id);
	
	protected abstract String constructQuery();
	
	protected class Liste extends EscapeInternalFrame{
		private static final long serialVersionUID = -4247479573467139344L;
		private Integer id_selected;
		private JPopupMenu popup;
		/* list header */
		private TitledSeparator chercher_label;
		private JButton search;
		private JLabel search_label;

		/**
		 * Construit la liste
		 */
		public Liste(){
			this(new ResultSetTableModelFactory(FilmzMain.db), null);
		}
		
		/**
		 * Construit la liste
		 * @param position position de la fenêtre
		 */
		public Liste(Point position){
			this(new ResultSetTableModelFactory(FilmzMain.db), position);
		}
		
		/**
		 * Construit la liste
		 * @param f factory resultset
		 * @param position position de la fenêtre
		 */
		public Liste(ResultSetTableModelFactory f, Point position) {
			setFrameIcon(icon);

			FormPanel pane = new FormPanel( "be/xtnd/gui/descriptions/simple_list.jfrm" );
			getContentPane().add(pane);
			
			chercher_label = (TitledSeparator)pane.getComponentByName("title_label");
			chercher_label.setText(Messages.getString("window.search.title"));

			search_label = pane.getLabel("search_label");
			search_label.setText(Messages.getString("window."+typeObject+".labels.search"));
			
			textfield = pane.getTextField("search");
			
			search = (JButton)pane.getButton("search_button");
			search.setText(Messages.getString("window.search.button"));
			search.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					try {
						displayQueryResults(constructQuery());
					} catch (Exception e1) {e1.printStackTrace();}
				}
			});

			factory = f;
			table = pane.getTable("liste");
	    	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(select && InputEvent.BUTTON1_MASK !=0){
			    		if(e.getClickCount()==2){
							id_selected = new Integer(table.getValueAt(table.rowAtPoint(e.getPoint()),0).toString());
							if(fromJoin){
								ajout(id_selected);
								af.displayQueryResults();
							}else{
								objet[2] = table.getValueAt(table.rowAtPoint(e.getPoint()),1).toString();
								//al.setText(table.getValueAt(table.rowAtPoint(e.getPoint()),0).toString());
								//return table.getValueAt(table.rowAtPoint(e.getPoint()),0).toString();
							}
							dispose();
			    		}
			    	}
				}
			});
			displayQueryResults(listQuery);
			
			popup = new JPopupMenu();
			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.del"),"del",Menus.DELETE_IMAGE);

			table.add(popup);
			
			setIconifiable(false);
			setClosable(true);
			setResizable(true);
			setMaximizable(true);
			setName(fenListName);
			setFrameIcon(icon);
			setSize(400, 300);
			if(position==null) position = MainGui.centerOnDesktop(getSize());
			setLocation(position);
			//setLocation(MainGui.centerOnDesktop(getSize()));
			setVisible(true);
			if(select){MainGui.desktop.add(this,JLayeredPane.POPUP_LAYER);}else{MainGui.desktop.add(this);}
			try {setSelected(true);} catch (PropertyVetoException e) {}

		}

		/**
		 * 
		 * @param q
		 */
		public void displayQueryResults(final String q) {
			MainGui.statusBar.setText("Contacting database...");

			EventQueue.invokeLater(new Runnable() {
				public void run() {
					try {
						ResultSetTableModel mod = factory.getResultSetTableModel(q);
						table.setModel(mod);
						
				        TableSorter sorter = new TableSorter(table.getModel());
				        table.setModel(sorter);
				        sorter.setTableHeader(table.getTableHeader());
				        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);

						if(!toSelect.equals(""))
							table.changeSelection(
									mod.findString(toSelect, 1)-1,
									1,false,false);

						setTitle(Messages.getString("window."+typeObject+".titles.list")+" ("+table.getRowCount()+")");
						
						MainGui.statusBar.setText("");
						MainGui.verifUnicite(fenListName,null);
					} 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("");					
					}
				}
			});
		}	
	
		@Override
		protected void popupActions(ActionEvent event){
			String command = event.getActionCommand();
			if(command.equals("new")){
				if(MainGui.verifUnicite(fenNewName,null)){
					nouveau();
					//nouvelActeur();
				}
			}else if(command.equals("del")){
				supprimer(id_selected);
				//supprimeActeur(id_selected);
				try {
					displayQueryResults(constructQuery());
				} catch (Exception e1) {e1.printStackTrace();}
			}else if(command.equals("detailled")){
				if(MainGui.verifUnicite(fenModifName+id_selected,null)){
				//if(MainGui.verifUnicite("acteur_"+id_selected,null)){
					modifier(id_selected);
					//modifieActeur(id_selected);
				}
			}
		}	
	}

	private class DetailWindow extends EscapeInternalFrame{
		private static final long serialVersionUID = 3225615238459711945L;
		private JTextField nom_acteur;
		private JLabel nom_acteur_label;
		
		DetailWindow(){
			super();
			super.setFrameIcon(Menus.ACTORS_IMAGE);
			if(mode==Database.NEW){
				super.setTitle(Messages.getString("window."+typeObject+".titles.new"));
				super.setName(fenNewName);				
			}else{
				Object[] args = {object.getValeur()};
				String titre = MessageFormat.format(Messages.getString("window."+typeObject+".titles.modif"), args);
				super.setTitle(titre);
				super.setName(fenModifName+object.getId());				
			}
			fenetreChamps();
		}
					
		void fenetreChamps(){
			FormPanel pane = new FormPanel( "be/xtnd/gui/descriptions/simple.jfrm" );
			
			initLabels(pane);
			
			nom_acteur = pane.getTextField("textfield");
			nom_acteur.setText(object.getValeur());
						
			setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
			setClosable(true);
			setIconifiable(true);
			
			add(pane);
			
			commons.createButtonBar(this,new OkayEvent());
			
			pack();
			setVisible(true);
			setLocation(MainGui.centerOnDesktop(getSize()));
			if(select){MainGui.desktop.add(this,JLayeredPane.DRAG_LAYER);}else{MainGui.desktop.add(this,JLayeredPane.MODAL_LAYER);}
			try {
				setSelected(true);
			} catch (PropertyVetoException e) {}			
		}
		
		private void queries(){
			boolean nouveau = false;
			String titre = new String();
			int boite = 0;
			String message = new String();
			
			object.setValeur(nom_acteur.getText());
			
			if(mode==Database.NEW){
				titre = Messages.getString("window."+typeObject+".messages.added.title");
				nouveau = true;
			}else{
				titre = Messages.getString("window."+typeObject+".messages.modified.title");
				nouveau = false;
			}
			object.enregistrer(nouveau);

			Object[] args = {object.getValeur()};
			if(object.getAffectedRows()>0){
				boite = JOptionPane.INFORMATION_MESSAGE+JOptionPane.OK_OPTION;
				if(mode==Database.NEW){
					message = MessageFormat.format(Messages.getString("window."+typeObject+".messages.added"), args);
				}else if(mode==Database.MODIF){
					message = MessageFormat.format(Messages.getString("window."+typeObject+".messages.modified"), args);
				}
				dispose();
				try {
					if(!MainGui.verifUnicite(fenListName, null)){
						liste.displayQueryResults(constructQuery());
					}
				} catch (Exception e1) {e1.printStackTrace();}
				//if(select)
				toSelect = object.getValeur();
			}else{
				boite = JOptionPane.WARNING_MESSAGE+JOptionPane.OK_OPTION;
				if(object.getSqlMessage().equals("")) object.setSqlMessage(MessagesCommons.getString("window.messages.noerror"));
				if(mode==Database.NEW){
					message = MessageFormat.format(Messages.getString("window."+typeObject+".messages.notadded"), args);
				}else if(mode==Database.MODIF){
					message = MessageFormat.format(Messages.getString("window."+typeObject+".messages.notmodified"), args);
				}
				message = message + "\n("+object.getSqlMessage()+")";
			}
			JOptionPane.showMessageDialog(MainGui.desktop, message, titre, boite);
		}	
		
		private void initLabels(FormPanel pane){
			nom_acteur_label = pane.getLabel("label");
			nom_acteur_label.setText(Messages.getString("window."+typeObject+".labels."+typeObject));
		}
		
		private boolean verifEntrees(){
			boolean valid = true;
			StringBuffer sb = new StringBuffer();
			sb.append(MessagesCommons.getString("window.messages.required"));

			if(nom_acteur.getText().trim().equals("")){
				sb.append(Messages.getString("window."+typeObject+".required."+typeObject));
				if(valid) nom_acteur.requestFocus();
				valid = false;
			}
			if(!valid){
				JOptionPane.showMessageDialog(
					MainGui.desktop, 
					sb.toString(),
					MessagesCommons.getString("window.messages.error"),
					JOptionPane.ERROR_MESSAGE);			
			}
			return valid;
		}
		
		class OkayEvent implements ActionListener{
			/**
			 * @param e
			 */
			public void actionPerformed(ActionEvent e) {
				if(verifEntrees())
					queries();
			}		
		}
	}
}
