/* ConfigurationFrame.java */

/* 
 * Copyright (C) 1996-98 Mark Boyns <boyns@sdsu.edu>
 *
 * This file is part of Muffin.
 *
 * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
package org.doit.muffin;

import java.awt.Button;
import java.awt.Color;
import java.awt.Event;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Label;
import java.awt.Panel;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.Enumeration;
import java.io.File;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.StringReader;
import org.doit.util.TextDialog;
import org.doit.util.YesNoDialog;

/**
 * @author Mark Boyns
 */
class ConfigurationFrame extends MuffinFrame implements ActionListener, ItemListener, WindowListener, ConfigurationListener
{
    BigList configNamesList = null;
    Configuration configs = null;
    TextArea text = null;
    
    ConfigurationFrame (Configuration configs)
    {
	super ("Muffin: Configurations");

	this.configs = configs;

	setResizable (false);

	configNamesList = new BigList (10, false);

	Label l;
	Button b;
	GridBagConstraints c;

	Panel panel = new Panel ();
	GridBagLayout layout = new GridBagLayout ();
	panel.setLayout (layout);

	Label currentLabel = new Label ();
	//currentLabel.setFont (new Font ("Fixed", Font.PLAIN, 12));
	c = new GridBagConstraints ();
	c.gridwidth = GridBagConstraints.REMAINDER;
	layout.setConstraints (currentLabel, c);
	panel.add (currentLabel);

	l = new Label ("Known Configurations");
	//l.setFont (new Font ("Fixed", Font.BOLD, 12));
	c = new GridBagConstraints ();
	c.gridwidth = GridBagConstraints.REMAINDER;
	layout.setConstraints (l, c);
	panel.add (l);

	c = new GridBagConstraints ();
	c.gridheight = 4;
	c.insets = new Insets (0, 10, 5, 10);
	layout.setConstraints (configNamesList, c);
	panel.add (configNamesList);

	b = new Button ("New...");
	b.setActionCommand ("doNew");
	b.addActionListener (this);
	c = new GridBagConstraints ();
	c.gridwidth = GridBagConstraints.REMAINDER;
	c.anchor = GridBagConstraints.NORTHWEST;
	layout.setConstraints (b, c);
	panel.add (b);
	
	b = new Button ("Select");
	b.setActionCommand ("doSelect");
	b.addActionListener (this);
	c = new GridBagConstraints ();
	c.gridwidth = GridBagConstraints.REMAINDER;
	c.anchor = GridBagConstraints.NORTHWEST;
	layout.setConstraints (b, c);
	panel.add (b);

	b = new Button ("Rescan");
	b.setActionCommand ("doRescan");
	b.addActionListener (this);
	c = new GridBagConstraints ();
	c.gridwidth = GridBagConstraints.REMAINDER;
	c.anchor = GridBagConstraints.NORTHWEST;
	layout.setConstraints (b, c);
	panel.add (b);

	b = new Button ("Delete");
	b.setActionCommand ("doDelete");
	b.addActionListener (this);
	c = new GridBagConstraints ();
	c.gridwidth = GridBagConstraints.REMAINDER;
	c.anchor = GridBagConstraints.NORTHWEST;
	layout.setConstraints (b, c);
	panel.add (b);

	l = new Label ("Automatic Configuration");
	//l.setFont (new Font ("Fixed", Font.BOLD, 12));
	c = new GridBagConstraints ();
	layout.setConstraints (l, c);
	panel.add (l);

	b = new Button ("Example");
	b.setActionCommand ("doExample");
	b.addActionListener (this);
	c = new GridBagConstraints ();
	c.gridwidth = GridBagConstraints.REMAINDER;
	layout.setConstraints (b, c);
	panel.add (b);

	text = new TextArea (10, 40);
	text.setEditable (true);
	//text.setFont (new Font ("Fixed", Font.PLAIN, 12));
	c = new GridBagConstraints ();
	c.gridwidth = GridBagConstraints.REMAINDER;
	layout.setConstraints (text, c);
	panel.add (text);

	add ("Center", panel);
	
	Panel buttonPanel = new Panel ();
	b = new Button ("Apply");
	b.setActionCommand ("doApply");
	b.addActionListener (this);
	buttonPanel.add (b);
	b = new Button ("Reload");
	b.setActionCommand ("doReload");
	b.addActionListener (this);
	buttonPanel.add (b);
	b = new Button ("Save");
	b.setActionCommand ("doSave");
	b.addActionListener (this);
	buttonPanel.add (b);
	b = new Button ("Close");
	b.setActionCommand ("doClose");
	b.addActionListener (this);
	buttonPanel.add (b);
	add ("South", buttonPanel);

	addWindowListener (this);
	updateConfigNamesList ();
	loadAutoConfigFile ();

	configs.addConfigurationListener (currentLabel);
	configs.addConfigurationListener (this);
	
 	pack ();
 	setSize (getPreferredSize ());
    }

    public void configurationChanged (String name)
    {
	updateConfigNamesList ();
    }

    void loadAutoConfigFile ()
    {
	text.setText ("");
	
	File file = new File (configs.getAutoConfigFile ());
	if (!file.exists ())
	{
	    return;
	}
	
	try
	{
	    BufferedReader in = new BufferedReader (new FileReader (file));
	    String s;
	    while ((s = in.readLine ()) != null)
	    {
		text.append (s + "\n");
	    }
	    in.close ();
	}
	catch (Exception e)
	{
	    System.out.println (e);
	}
    }

    void updateConfigNamesList ()
    {
	if (configNamesList.getItemCount () > 0)
	{
	    configNamesList.removeAll ();
	}

	Enumeration e = configs.sortedKeys ();
	while (e.hasMoreElements ())
	{
	    String name = (String) e.nextElement ();
	    configNamesList.addItem (name); // DEPRECATION: use add()
	}
    }

    public void itemStateChanged (ItemEvent event)
    {
    }

    /**
     * Handle button events.
     *
     * @param event some event
     */
    public void actionPerformed (ActionEvent event)
    {
	String arg = event.getActionCommand ();

	if ("doClose".equals (arg))
	{
	    setVisible (false);
	}
	else if ("doNew".equals (arg))
	{
	    TextDialog dialog = new TextDialog (this, "New configuration name:");
	    dialog.show ();
	    String name = dialog.getAnswer ();
	    if (name != null && name.length () > 0)
	    {
		name.trim ();
		configs.createConfig (name);
	    }
	    dialog.dispose ();
	}
	else if ("doDelete".equals (arg))
	{
	    int i = configNamesList.getSelectedIndex ();
	    if (i != -1)
	    {
		String name = configNamesList.getItem (i);
		if (configs.delete (name))
		{
		    updateConfigNamesList ();

		    YesNoDialog dialog = new YesNoDialog (this, "Delete the " + name + " file?");
		    dialog.show ();
		    if (dialog.isYes ())
		    {
			configs.deleteUserConfigFile (name);
		    }
		    dialog.dispose ();
		}
	    }
	}
	else if ("doSelect".equals (arg))
	{
	    int i = configNamesList.getSelectedIndex ();
	    if (i != -1)
	    {
		configs.setCurrent (configNamesList.getItem (i));
	    }
	}
	else if ("doRescan".equals (arg))
	{
	    configs.rescan ();
	    updateConfigNamesList ();
	}
	else if ("doReload".equals (arg))
	{
	    configs.reload ();
	}
	else if ("doApply".equals (arg))
	{
	    configs.load (new StringReader (text.getText ()));
	}
	else if ("doSave".equals (arg))
	{
	    try
	    {
		File file = new File (configs.getAutoConfigFile ());
		if (file.exists ())
		{
		    file.delete ();
		}
		FileWriter writer = new FileWriter (file);
		writer.write (text.getText ());
		writer.close ();
	    }
	    catch (Exception e)
	    {
		System.out.println (e);
	    }
	}
	else if ("doExample".equals (arg))
	{
	    text.setText ("counter\t\t\tcounter.conf\n" +
			  "(cgi-bin|\\.cgi)\t\tcgi.conf\n" +
			  "^http://.*\\.sdsu\\.edu/\t\tsdsu.conf\n" +
			  "^http://.*\\.yahoo\\.com/\tyahoo.conf\n");
	}
    }

    public void windowActivated (WindowEvent e)
    {
    }
  
    public void windowDeactivated (WindowEvent e)
    {
    }
  
    public void windowClosing (WindowEvent e)
    {
	setVisible (false);
    }
  
    public void windowClosed (WindowEvent e)
    {
    }
  
    public void windowIconified (WindowEvent e)
    {
    }
  
    public void windowDeiconified (WindowEvent e)
    {
    }
  
    public void windowOpened (WindowEvent e)
    {
    }
}
