// AttributeHelper.java
// $Id: AttributesHelper.java,v 1.11 1998/03/30 09:48:03 bmahe Exp $
// (c) COPYRIGHT MIT and INRIA, 1997.
// Please first read the full copyright statement in file COPYRIGHT.html

package org.w3c.jigadm.editors ;

import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.lang.*;
import org.w3c.jigsaw.admin.*;
import org.w3c.tools.resources.Attribute;
import org.w3c.jigadm.*;
import org.w3c.jigadm.gui.*;
import org.w3c.jigadm.events.*;

public class AttributesHelper extends ResourceHelper {

    class ButtonBarListener implements ActionListener {

	class Commiter extends Thread {
	    public void run() {
		try {
		    commitChanges();
		} catch (RemoteAccessException ex) {
		    errorPopup("RemoteAccessException",ex);
		}
	    }
	}

	public void actionPerformed(ActionEvent ae) {
	    if (ae.getActionCommand().equals("Reset"))
		resetChanges();
	    else if (ae.getActionCommand().equals("Commit")) {
		(new Commiter()).start();
	    } 
	}
    }

    private RemoteResourceWrapper rrw = null;
    private Attribute[] a = null;
    private AttributeEditor[] ae = null;
    private ScrollPane pwidget;
    private boolean initialized = false;

    Panel widget;

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

	int num = 0;
        for(int i=0; i<ae.length; i++) {
            if (ae[i].hasChanged())
                num++;
        }
	boolean authorized;
        String s[] = new String[num];
	Object o[] = new Object[num];
        num = 0;
        for(int i=0; i<ae.length; i++) {
            if (ae[i].hasChanged()) {
                s[num] = a[i].getName();
		o[num] = ae[i].getValue();
		if(s[num].equals("identifier")) {
		    // should send an event
		    if(rrw.getBrowser() != null)
			rrw.getBrowser().renameNode(rrw, (String)o[num]);
		    processEvent(new ResourceChangeEvent(rrw,
							 "identifier",
							 null,
							 o[num]));
		}
		num++;
	    }
	}
	authorized = false;
	while(!authorized) {
	    try {
		authorized = true;
		rrw.getResource().setValues(s, o);
	    } catch (RemoteAccessException ex) {
		if(ex.getMessage().equals("Unauthorized")) {
		    authorized = false;
		} else {
		    throw ex;
		}
	    } finally {
		if(!authorized) {
		    rrw.getBrowser().popupDialog("admin");
		}
	    }
	}
	clearChanged();
	// FIXME propagate event
    }
	

    public boolean hasChanged() {
	if(ae == null)
	    return false;
	boolean changed = false;
	for(int i=0; !changed && i<ae.length; i++) {
	    changed = ae[i].hasChanged();
	}
	return changed;
    }

    public void resetChanges() {
	if(ae == null)
	    return;

	for(int i=0; i<ae.length; i++) {
	    if(ae[i].hasChanged())
		ae[i].resetChanges();
	}
    }

    public void clearChanged() {
	if(ae == null)
	    return;
	for(int i=0; i<ae.length; i++) {
	    if (ae[i].hasChanged())
		ae[i].clearChanged();
	}
    }

    public Component getComponent() {
	return widget;
    }

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

    public AttributesHelper() {
	widget = new Panel(new BorderLayout());
    }

    public void initialize(RemoteResourceWrapper rrw, Properties pr)
	throws RemoteAccessException
    {
	Object val[] = null;
	
	if(initialized)
	    return;

	RemoteResource rr;
	Attribute b[] = null;
	String s[] = null;
	int nbn = 0;
	boolean authorized;
	

	this.rrw = rrw;
	rr = rrw.getResource();
	authorized = false;
	while(!authorized) {
	    try {
		authorized = true;
		b = rr.getAttributes();
	    } catch (RemoteAccessException ex) {
		if(ex.getMessage().equals("Unauthorized")) {
		    authorized = false;
		} else {
		    throw ex;
		}
	    } finally {
		if(!authorized) {
		    rrw.getBrowser().popupDialog("admin");
		}
	    }
	}
	// we select only the editable Attributes.
	for(int i=0; i<b.length; i++)
	    if(b[i] == null)
		nbn++;
	    else
		if(!b[i].checkFlag(Attribute.EDITABLE))
		    nbn++;
	a = new Attribute[b.length-nbn];
	s = new String[a.length];
	ae = new AttributeEditor[a.length];
	int j = 0;
	for(int i=0; i<b.length; i++) {
	    if(b[i] != null && b[i].checkFlag(Attribute.EDITABLE)) {
		a[j] = b[i];
		s[j] = b[i].getName();
		j++;
	    }
	}
	val = rr.getValues(s);

	// add all the attribute editors

	Label l;
	GridBagLayout gbl = new GridBagLayout();
	GridBagConstraints gbc = new GridBagConstraints();
	Panel p = new Panel(gbl);
	pwidget = new ScrollPane();
	gbc.fill = GridBagConstraints.HORIZONTAL;
	gbc.weightx = 0;
	gbc.weighty = 0;
	for(int i=0; i<a.length; i++) {
	    if(a[i] != null) {
		PropertyManager pm = PropertyManager.getPropertyManager();
		Properties attrProps = pm.getAttributeProperties(rrw, a[i]);
		String labelText = (String) attrProps.get("label");
		if ( labelText == null )
		    labelText = a[i].getName();
		l = new Label(labelText, Label.RIGHT);
		ae[i] = AttributeEditorFactory.getEditor(rrw, a[i]);
		authorized = false;
		while(!authorized) {
		    try {
			authorized = true;
			ae[i].initialize(rrw, a[i], val[i], attrProps);
		    } catch (RemoteAccessException ex) {
			if(ex.getMessage().equals("Unauthorized")) {
			    authorized = false;
			} else {
			    throw ex;
			}
		    } finally {
			if(!authorized) {
			    rrw.getBrowser().popupDialog("admin");
			}
		    }
		}
		gbc.gridwidth = 1;
		gbl.setConstraints(l, gbc);
		p.add(l);
		gbc.gridwidth = GridBagConstraints.REMAINDER;
		gbl.setConstraints(ae[i].getComponent(), gbc);
		p.add(ae[i].getComponent());
	    }
	}
	pwidget.add(p);
	widget.add("Center", pwidget);
	// Now add the reset/commit button bar

	Panel  toolpane= new Panel(new BorderLayout());
	Button commitb = new Button("Commit");

	Button resetb  = new Button("Reset");
	ButtonBarListener bbl = new ButtonBarListener();

	commitb.addActionListener(bbl);
	resetb.addActionListener(bbl);

	toolpane.add("West", commitb);
	toolpane.add("East", resetb);

	widget.add("South", toolpane);
	// add information about the class of the resource edited

	String classes[] = {""};
	try {
	    classes = rr.getClassHierarchy();
	} catch (RemoteAccessException ex) {
	    // big trouble but it may be temporary and this information
	    // is not vital, so just warn
	    ex.printStackTrace();
	}
	l = new Label("Class: " + classes[0], Label.CENTER);
	widget.add("North", l);
	initialized = true;
    }
}
