// FiltersHelper.java
// $Id: FiltersHelper.java,v 1.10 1997/08/21 09:32:26 bmahe Exp $
// (c) COPYRIGHT MIT and INRIA, 1997.
// Please first read the full copyright statement in file COPYRIGHT.html

package w3c.jigadm.editors ;

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import w3c.jigadm.*;
import w3c.jigsaw.admin.*;
import w3c.tools.widgets.*;
import w3c.tools.store.Attribute;

public class FiltersHelper extends ResourceHelper {

	static private String FAL_ADD    = "add";
	static private String FAL_DELETE = "delete";
	static private String FAL_EDIT   = "edit";
	static private String FAL_BACK   = "back";

    private class FiltersActionListener implements ActionListener {
 
        private class Performer extends Thread {
	    boolean addDelOrEdit;
	    Button source;

  	    public void run() {
		if(source == null) {
		    if(addDelOrEdit) {
			addFilter();
		    } else {
			initAddPanel(prop);
		    }
		} else {
		    if(addDelOrEdit) {
			deleteFilter(source);
		    } else {
			editFilter(source);
		    }
		}
	    }

   	    private Performer(Button source, boolean b) {
		this.source = source;
		addDelOrEdit = b;
	    }

   	    private Performer(boolean b) {
		this(null, b);
	    }
	}

        public void actionPerformed(ActionEvent ae) {
	    String command = ae.getActionCommand();
	    Button source = (Button) ae.getSource();

	    if ( command.equals(FAL_ADD)) {
		(new Performer(true)).start();
	    } else if ( command.equals(FAL_DELETE)) {
		(new Performer(source, true)).start();
	    } else if ( command.equals(FAL_EDIT)) {
		(new Performer(source, false)).start();
	    } else if ( command.equals(FAL_BACK)) {
		(new Performer(false)).start();
	    }
	}
    }
	
    private FiltersActionListener fal;
    RemoteResourceWrapper rrw = null;
    AttributesHelper filterattr = null;
    RemoteResource filters[] = null;
    Button lb[] = null; // wait for the image button
    Button rb[] = null;
    private boolean initialized = false;
    private boolean editing = false;
    Properties prop;
    Panel widget;
    Panel addFilter;
    Panel filterProps;
    Panel filterList;
    FakeComboBox combo;
    Component centerComp;
    ScrollPane sp;

    protected void addFilter() {
        String selected = combo.getText();
	if(selected != null)
	  if (selected.length() > 0) {
	    boolean authorized = false;
	    boolean ok = true;
	    while (!authorized) {
		try {
		    authorized = true;
		    rrw.getResource().registerFilter( null, 
						      selected );
		    
		} catch (RemoteAccessException ex) {
		    if( ex.getMessage().equals("Unauthorized")) {
			authorized = false;
		    } else {
		        errorPopup("RemoteAccessException",ex);
			ok = false;
		    }
		} finally {
		    if(!authorized) {
			rrw.getBrowser().popupDialog("admin");
		    }
		}
	    }
	    if(ok) {
		widget.setVisible(false);
		widget.remove(sp);
		// yes, we can avoid reloading everything...
		try {
		    initFilters();
		} catch (RemoteAccessException ex) {
 		    errorPopup("RemoteAccessException",ex);
		}
		widget.validate();
		widget.setVisible(true);
	    }
	}
    }
    
    protected void deleteFilter(Button toggled) 
//	throws RemoteAccessException
    {
	Button lab = null;
	boolean ok = false;
	boolean authorized;
	for(int i=0; i< rb.length; i++) {
	    if( toggled.equals(rb[i])) {
		lab = lb[i];
		ok = true;
		authorized = false;
		while (!authorized) {
		    try {
			authorized = true;
			rrw.getResource().unregisterFilter(filters[i]);
		    } catch (RemoteAccessException ex) {
			if( ex.getMessage().equals("Unauthorized")) {
			    authorized = false;
			} else {
			    errorPopup("RemoteAccessException",ex);
			    ok = false;
			}
		    } finally {
			if(!authorized) {
			    rrw.getBrowser().popupDialog("admin");
			}
		    }
		}
	    }
	}
	if(ok) {
	    filterList.remove(lab);
	    filterList.remove(toggled);
	}
    }
    
    protected void editFilter(Button toggled) 
//	throws RemoteAccessException
    {
	Button lab = null;
	boolean authorized;
	for(int i=0; i< rb.length; i++) {
	    if( toggled.equals(lb[i])) {
		filterattr = new AttributesHelper();
		widget.remove(centerComp);
		authorized = false;
		while (!authorized) {
		    try {
			authorized = true;
			filterattr.initialize(
			    new RemoteResourceWrapper(filters[i]), null);
		    } catch (RemoteAccessException ex) {
			if( ex.getMessage().equals("Unauthorized")) {
			    authorized = false;
			} else {
			  errorPopup("RemoteAccessException",ex);
			    // do nothing
			}
		    } finally {
			if(!authorized) {
			    rrw.getBrowser().popupDialog("admin");
			}
		    }
		}
		Panel interp = new Panel(new BorderLayout());
		interp.add("Center", filterattr.getComponent());
		centerComp = interp;
		Button back = new Button("Back to Add Filter menu");
		back.setActionCommand(FAL_BACK);
		back.addActionListener(fal);
		interp.add("South", back);
		widget.add("Center", centerComp);
		widget.validate();
		widget.setVisible(true);
	    }
	}
    }
    
    public Component getComponent() {
	return widget;
    }

    public void commitChanges()
	throws RemoteAccessException
    {
	if(!initialized)
	    return;
	return;
    }

    public boolean hasChanged() {
	return false;
    }

    public void resetChanges() {
    }

    public void clearChanged() {
    }

    public final String getTitle () {
	return "Filters";
    }

    public FiltersHelper() {
	widget = new Panel();
	fal = new FiltersActionListener();
    }

    protected void initFilters() 
	throws RemoteAccessException
    {
	// Add the list of Filters and inherited filters
	boolean authorized;
	sp = new ScrollPane();
	GridBagLayout gbl = new GridBagLayout();
	GridBagConstraints gbc = new GridBagConstraints();
	filterList = new Panel (gbl);
	sp.add(filterList);
	
	authorized = false;
	while (!authorized) {
	    try {
		authorized = true;
		filters = rrw.getResource().getFilters();
	    } catch (RemoteAccessException ex) {
		if( ex.getMessage().equals("Unauthorized")) {
		    authorized = false;
		} else {
		    throw ex; // another reason, throw it
		}
	    } finally {
		if(!authorized) {
		    rrw.getBrowser().popupDialog("admin");
		}
	    }
	}

	if(filters != null) {
	    String ri[] = new String[filters.length];
	    lb = new Button[filters.length];
	    rb = new Button[filters.length];
	    for(int i=0; i<ri.length; i++) {
		ri[i] = filters[i].getClassHierarchy()[0];
	    }
	    for(int i=0; i<ri.length; i++) {
		lb[i] = new Button(
		    ri[i].substring(ri[i].lastIndexOf('.') + 1));
		lb[i].setActionCommand(FAL_EDIT);
		lb[i].addActionListener(fal);
		gbc.gridwidth = 1;
		gbl.setConstraints(lb[i], gbc);
		filterList.add(lb[i]);
		rb[i] = new Button("Delete");
		rb[i].setActionCommand(FAL_DELETE);
		rb[i].addActionListener(fal);
		// add a button to edit the filter
		gbc.gridwidth = GridBagConstraints.REMAINDER;
		gbl.setConstraints(rb[i], gbc);
		filterList.add(rb[i]);
	    }
	}
	// add the inherited filters
	RemoteResource shadowfilter[];
	RemoteResourceWrapper father;
	RemoteResourceWrapper root;

	// thanks to the wrapper, we can go up in the tree
	father = rrw.getFatherWrapper();
	root = rrw.getBrowser().getRootWrapper();
	while(father != root) {
	    try {
		shadowfilter = father.getResource().getFilters();
	    } catch (Exception ex) { // not a filtered resource
		break;
	    }
	    if(shadowfilter != null) {
		String ri[] = new String[shadowfilter.length];
		for(int i=0; i<ri.length; i++) {
		    ri[i] = shadowfilter[i].getClassHierarchy()[0];
		}
		for(int i=0; i<ri.length; i++) {
		    Label sh;
		    Label l;
		    l = new Label(
			ri[i].substring(ri[i].lastIndexOf('.') + 1),
			Label.RIGHT);
		    gbc.gridwidth = 1;
		    gbl.setConstraints(l, gbc);
		    filterList.add(l);
		    sh = new Label("(inherited)");
		    gbc.gridwidth = GridBagConstraints.REMAINDER;
		    gbl.setConstraints(sh, gbc);
		    filterList.add(sh);
		}		  
	    }
	    father = father.getFatherWrapper();
	}
	widget.add("South", sp);
    }

    protected void initAddPanel(Properties config) {
	if(addFilter == null) {
	    addFilter = new Panel(new BorderLayout());
	
	    String af = config.getProperty(
		"w3c.jigadm.editors.filters");
	    StringTokenizer st = new StringTokenizer(af, "|");
	    ScrollPane fsp = new ScrollPane();
	    GridBagLayout fgbl = new GridBagLayout();
	    GridBagConstraints fgbc = new GridBagConstraints();
	    Panel fspp = new Panel (fgbl);
	    fsp.add(fspp);
	    PropertyManager pm = PropertyManager.getPropertyManager();
	    String downPath = pm.getIconLocation("down");
	    String leftPath = pm.getIconLocation("left");
	    combo = new FakeComboBox(35,7,true,downPath,leftPath);
	    while(st.hasMoreTokens())
	      combo.add(st.nextToken().trim());
	    fspp.add(combo);
	    addFilter.add("Center", fsp);
	    // Add listener to switch between filter chooser and configurer
	    Button newb     = new Button("Add Filter");
	    newb.setActionCommand(FAL_ADD);
	    newb.addActionListener(fal);
	    addFilter.add("South", newb);
	} else
	    widget.remove(centerComp);
	widget.add("Center", addFilter);
	centerComp = addFilter;
    }

    public void initialize(RemoteResourceWrapper rrw, Properties pr)
	throws RemoteAccessException
    {
	if(!initialized)
	    initialized = true;
	else {
	    widget.removeAll();
	}
	
	RemoteResource rr;
	this.prop = pr;
	this.rrw = rrw;
	rr = rrw.getResource();

	if(rr.isFiltered()) {
	    widget.setLayout(new BorderLayout());
	    // Create the Add Filter panel
	    initAddPanel(prop);
	    // add the filters
	    initFilters();
	}
    }
}
