import javax.swing.* ;
import java.awt.* ;
import java.awt.event.* ;
import javax.swing.event.* ;

/**
 * Classe du Panel Wizard. 
 * Creation dynamique, avec ajout de 120 composants par une boucle de quelques lignes.
 * Alors que VisualAge prend 2100 lignes pour ne placer que les JLabels
 */
// TODO : ajouter une gestion des exceptions pour les manipulations des tableaux de composants
public class WizPane extends JPanel {
    // Les choix possibles dans les combobox
    private String[] combostr = {"Not Set", "(Blank)", "On", "Off"} ;
    // Les labels a afficher
    private String[] labels_str = {
	"Accept", "Reject", "Add host directory", "Continue", "Background", "URL Base ", "Cache", "Convert Links",
	"Cut directories", "Debug", "Delete After", "Directory Prefix", "Keep directory structure", "Accept domains",
	"Bytes/dot", "Dots/line", "Dot spacing", "Dot style", "Exclude directories", "Exclude domains", "Follow FTP",
	"Force HTML", "FTP proxy", "Glob", "Header", "HTTP user", "HTTP password", "HTTP proxy", "Ignore Length",
	"Include directories", "Read URLs from", "Kill longer data", "Logfile", "Login", "Mirror", "Read .netrc", 
	"No clobber", "No parent directory", "No proxy", "Output document", "Passive FTP", "FTP password", "Proxy user",
	"Proxy password", "Quiet", "Quota", "Recursion level", "Recursive", "Relative links only", "Remove FTP listings",
	"Retrieve symlinks", "Use robots.txt", "Print server responses", "Simple host check", "Span hosts", "Timeout", 
	"Timestamping", "Retries", "Use proxy", "Verbose", "Wait"
    } ;
    // Les noms des composants actifs de l'interface (i.e. JTextFields et JComboBox)
    private String[] component_names = {
	"tf_accept", "tf_reject", "co_add_hostdir", "co_continue", "co_background", "tf_base", "co_cache",
	"co_convert_links", "tf_cut_dirs", "co_debug", "co_delete_after", "tf_dir_prefix", "co_dirstruct",
	"tf_domains", "tf_dot_bytes", "tf_dot_in_line", "tf_dot_spacing", "tf_dot_style", "tf_exclude_directories",
	"tf_exclude_domains", "co_follow_ftp", "co_force_html", "tf_ftp_proxy", "co_glob", "tf_header", "tf_http_user",
	"tf_http_passwd", "tf_http_proxy", "co_ignore_length", "tf_include_directories", "tf_input", "co_kill_longer",
	"tf_logfile", "tf_login", "co_mirror", "co_netrc", "co_noclobber", " co_no_parent", "tf_no_proxy", 
	"tf_output_document", "co_passive_ftp", "tf_passwd", "tf_proxy_user", "tf_proxy_passwd", "co_quiet", 
	"tf_quota", "tf_reclevel", "co_recursive", "co_relative_only", "co_remove_listing", 
	"co_retr_symlinks", "co_robots", "co_server_response", "co_simple_host_check", "co_span_hosts", "tf_timeout",
	"co_timestamping", "tf_tries", "co_use_proxy", "co_verbose", "tf_wait"
    } ;
    // Les tableaux de composants a placer dans la frame
    private JLabel[] labels ;
    private JComponent[] components ;
    private GridBagConstraints[] constraints ; // Les constraints pour placer tous ces petits		


    public WizPane() {
	super() ;
	initialize() ;
    }

    // Initialisation du Panel et creation de tous les composants de maniere dynamique
    private void initialize() {
	int i , j = 0;
	//	GridBagConstraints constraints = new GridBagConstraints();
	setName("WizPanel");
	setLayout(new GridBagLayout());
	//	setPreferredSize(new Dimension(300, 500));
		setSize(500, 500);
	//	setMinimumSize(new Dimension(300,500)) ;

	// On cree d'abord tous les JLabel
	labels = new JLabel[labels_str.length] ;
	constraints = new GridBagConstraints[2*labels_str.length] ;
	for(i = 0 ; i < labels_str.length ; i++) {
	    constraints[i] = new GridBagConstraints(0, j++, 1, 1, 0, 0,
							   GridBagConstraints.CENTER,
							   GridBagConstraints.HORIZONTAL,
							   new Insets(2, 2, 2, 2),0,0);
	    labels[i] = new JLabel(labels_str[i],SwingConstants.LEFT) ;
	    labels[i].setForeground(Color.black);
	    labels[i].setHorizontalTextPosition(SwingConstants.LEFT);
	    // labels[i].setFont(new Font("dialog", 0, 12));
	    add(labels[i], constraints[i]);
	}
	// Les composants actifs
	j = 0 ;
	components = new JComponent[component_names.length] ;
	for(i = 0 ; i < component_names.length ; i++) {
	    if(component_names[i].regionMatches(0 , "tf_" , 0 , 2)) {
		components[i] = new JTextField() ;
		constraints[i+labels_str.length] = new GridBagConstraints(1, j++, 2, 1, 1, 1,
									  GridBagConstraints.CENTER,
									  GridBagConstraints.HORIZONTAL,
									  new Insets(2, 2, 2, 2),0,0);
	    }
	    else {
		components[i] = new JComboBox(combostr) ;
		constraints[i+labels_str.length] = new GridBagConstraints(1, j++, 1, 1, 0, 0,
									  GridBagConstraints.CENTER,
									  GridBagConstraints.HORIZONTAL,
									  new Insets(2, 2, 2, 2),0,0);
	    }
	    // Ajout du composant au JPanel
	    components[i].setName(component_names[i]) ;
	    add(components[i], constraints[i+labels_str.length]) ;
	}
    }
    

    /**
     * Le nom des composants etant la seule chose que l'on sait d'eux, on se doit d'avoir une methode
     * permettant de renvoyer un composant precis en fonction de son nom.
     * @param component_name Le nom du composant dans l'interface.
     * @return Le composant trouve.
     */
    public JComponent getComponentByName(String component_name) {
	int i = 0 ;
	while(i < component_names.length) {
	    if(component_names[i].equals(component_name))
		return components[i] ;
	    i++ ;
	}
	return null ;
    }

    /**
     * Renvoie la valeur du parametre associe a un composant.
     * @param component_name Le nom du composant dont on veut recuperer le parametre
     * @return La chaine representant la valeur du parametre.
     */
    public String getComponentParamValue(String component_name) {
	JComponent comp = getComponentByName(component_name) ;
	if(component_name.regionMatches(0 , "tf_" , 0 , 2)) 
	    return ((JTextField)comp).getText() ;
	else
	    return combostr[((JComboBox)comp).getSelectedIndex()] ;
    }

    /**
     * Modifie la valeur du parametre associe a un composant.
     * @param compoent_name Le nom du composant a modifier
     * @param param_value La nouvelle valeur du parametre associe au composant.
     */
    public void setComponentParamValue(String component_name, String param_value) {
	if(param_value.equals("Not Set") || param_value.equals("(Blank)") || 
	   param_value.equals("On") || param_value.equals("Off")) {
	    JComboBox combo = (JComboBox)getComponentByName(component_name) ;
	    if(param_value.equals("Not Set"))
		combo.setSelectedIndex(0) ;
	    else if(param_value.equals("(Blank)"))
		combo.setSelectedIndex(1) ;
	    else if(param_value.equals("On"))
		combo.setSelectedIndex(2) ;
	    else
		combo.setSelectedIndex(3) ;
	}
	else {
	    JTextField textfield = (JTextField)getComponentByName(component_name) ;
	    textfield.setText(param_value) ;
	}
    }

    /**
     * Enregistre les Listeners pour les differents composant de l'interface.
     * @param action Le ActionListener des combobox
     * @param caret Le CaretListener des JTextFields
     */
    // TODO : modifier le bazard pour avoir juste un EventListenr en param
    public void registerListeners(ActionListener action, CaretListener caret) {
	int i ;
	for(i = 0 ; i < component_names.length ; i++) 
	    if(component_names[i].regionMatches(0 , "tf_" , 0 , 2)) // Les textfields
		((JTextField)components[i]).addCaretListener(caret) ;
	    else
		((JComboBox)components[i]).addActionListener(action) ;
    }


    /**
     * main entrypoint - starts the part when it is run as an application
     * @param args java.lang.String[]
     */
    public static void main(String[] args) {
	JFrame frame = new JFrame();
	WizPane aWizPane = new WizPane();
	JScrollPane scroll = new JScrollPane();

	// scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED ) ;
	aWizPane.setLocation(0,0);
	scroll.setViewportView(aWizPane);
	frame.getContentPane().setLayout(new GridLayout());
	frame.getContentPane().add(scroll, "scroll pane");
	frame.setSize(aWizPane.getSize());
	frame.setVisible(true);
	/*
	  // Pour le debug
	  ((JTextField)aWizPane.getComponentByName("tf_http_passwd")).setText("Salut") ;
	  System.out.println(aWizPane.getComponentParamValue("co_ignore_length")) ;
	  System.out.println(aWizPane.getComponentParamValue("tf_http_passwd"));
	  aWizPane.setComponentParamValue("tf_http_passwd", "Yo ! le retour !") ;
	  aWizPane.setComponentParamValue("co_ignore_length", "On") ;
	*/
    }
}









