// ResourceEditor.java
// $Id: ResourceEditor.java,v 1.18 1998/06/18 16:26:14 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.awt.*;
import java.awt.event.*;
import java.util.*;
import org.w3c.jigadm.*;
import org.w3c.jigadm.events.*;
import org.w3c.jigsaw.admin.*;
import org.w3c.tools.resources.*;
import org.w3c.tools.widgets.*;

public class ResourceEditor implements ResourceEditorInterface {

    public static final String UNREMOVABLE_P = "unremovable";

    class Alert extends Canvas {

	Image alert = null;
	int width  = 0;
	int height = 0;

	public Dimension getMinimumSize() {
	    return new Dimension(width+8, height+8);
	}

	public Dimension getPreferredSize() {
	    return new Dimension(width+8, height+8);
	}

	public boolean imageUpdate(Image img, int flaginfo,
				   int x, int y, int width, int height) {
	    initSize();
	    Container parent = getParent();
	    if(parent != null) 
		parent.doLayout();
	    return super.imageUpdate(img, flaginfo, x, y, width, height);
	}

	private void initSize() {
	    if (alert != null) {
		width = alert.getWidth(this);
		height = alert.getHeight(this);
	    }
	}

	public void paint(Graphics g) {
	    if (alert != null)
		g.drawImage(alert, 0, 0, this);
	}

	Alert() {
	    PropertyManager pm = PropertyManager.getPropertyManager();
	    String alertPath = pm.getIconLocation("alert");
	    if (alertPath != null) {
		alert = Toolkit.getDefaultToolkit().getImage(alertPath);
		prepareImage(alert,this);
	    }
	    initSize();
	}
    }
    
    class ButtonBarListener implements ActionListener {

 	class Switcher extends Thread {
	    Button b;

            public void run() {
		try {
		    switchHelper(b);
	   	} catch (RemoteAccessException ex) {
		    // do fancy things FIXME
		}
	    }
	    
	    Switcher(Button b) {
		this.b = b;
	    }
	}

        class Deleter extends Thread {
            public void run() {
		delete();
	    }
	}

        class Reindexer extends Thread {
            public void run() {
		reindex();
	    }
	}

        public void actionPerformed(ActionEvent ae) {
	    if (ae.getActionCommand().equals("Delete")) {
		(new Deleter()).start();
	    } else if(ae.getActionCommand().equals("Reindex")) {
		(new Reindexer()).start();
	    } else {
		(new Switcher((Button)ae.getSource())).start();
	    }
	}
    }

    protected Vector rls = null;
    
    Panel target = null;
    Panel buttonp = null;
    Panel editorp = null;
    Button commitb = null;
    Button resetb;
    RemoteResource rr = null;
    RemoteResourceWrapper rrw = null;
    ResourceHelper rh[] = null;
    protected Button b[] = null;
    Properties p;

    public void commitChanges()
	throws RemoteAccessException
    {
	boolean authorized;
	for(int i=0; i<rh.length; i++) {
	    if(rh[i].hasChanged()) {
		authorized = false;
		while (!authorized) {
		    try {
			authorized = true;
			rh[i].commitChanges();
		    } catch (RemoteAccessException ex) {
			if( ex.getMessage().equals("Unauthorized")) {
			    authorized = false;
			} else {
			    (new MessagePopup("Exception : ",
					      ex.getMessage())).show();
			    throw ex; // another reason, throw it
			}
		    } finally {
			if(!authorized) {
			    rrw.getBrowser().popupDialog("admin");
			}
		    }
		}
	    }
	}
    }
    
    public void resetChanges()
	throws RemoteAccessException
    {
	for(int i=0; i<rh.length; i++) {
	    if(rh[i].hasChanged()) {
		rh[i].resetChanges();
	    }
	}
    }
  
    protected void switchHelper(Button toggled)
	throws RemoteAccessException
    {
	for(int i=0; i< b.length; i++) {
	    boolean authorized;
	    if( toggled.equals(b[i])) {
	        PropertyManager pm = PropertyManager.getPropertyManager();
		Properties props = pm.getHelperProperties(rrw, 
							  rh[i].getClass().getName());
		authorized = false;
		while (!authorized) {
		    try {
			authorized = true;
			rh[i].initialize(rrw, props);
		    } catch (RemoteAccessException ex) {
			if( ex.getMessage().equals("Unauthorized")) {
			    authorized = false;
			} else {
			    (new MessagePopup("Exception : ",
					      ex.getMessage())).show();
			    throw ex; // another reason, throw it
			}
		    } finally {
			if(!authorized) {
			    rrw.getBrowser().popupDialog("admin");
			}
		    }
		}
		editorp.setVisible(false);
		editorp.removeAll();
		editorp.add("Center", rh[i].getComponent());
		editorp.validate();
		editorp.setVisible(true);
	    }
	}
    }

    protected void reindex() {
	boolean authorized = false;
	while (!authorized) {
	    try { 
		authorized = true;
		rrw.getResource().reindex();
		(new MessagePopup("Reindexation done.")).show();
	    } catch (RemoteAccessException ex) {
		if( ex.getMessage().equals("Unauthorized")) {
		    authorized = false;
		} else {
		    (new MessagePopup("Exception : ",
				      ex.getMessage())).show();
		    // must throw a fancy error
		}
	    } finally {
		if(!authorized) {
		    rrw.getBrowser().popupDialog("admin");
		}
	    }
	}
    }

    protected void delete() {
	boolean authorized = false;
	while (!authorized) {
	    try { 
		authorized = true;
		rrw.getResource().delete();
	    } catch (RemoteAccessException ex) {
		if( ex.getMessage().equals("Unauthorized")) {
		    authorized = false;
		} else {
		    (new MessagePopup("Exception : ",
				      ex.getMessage())).show();
		    // must throw a fancy error
		}
	    } finally {
		if(!authorized) {
		    rrw.getBrowser().popupDialog("admin");
		}
	    }
	}
	processEvent(new ResourceChangeEvent(
					     rrw.getFatherWrapper(), "deleted", rrw, null));
    }
   
    public boolean hasChanged() {
	for(int i=0; i<rh.length; i++) {
	    if(rh[i].hasChanged()) {
		return true;
	    }
	}
	return false;
    }

    public void clearChanged() {
	for(int i=0; i<rh.length; i++) {
	    if(rh[i].hasChanged()) {
		rh[i].clearChanged();
	    }
	}
    }
    
    public RemoteResource getValue() {
	return rr;
    }

    public synchronized void addResourceListener(ResourceListener rl) {
	if (rls == null)
	    rls = new Vector(2);
	rls.addElement(rl);
    }

    public synchronized void removeResourceListener(ResourceListener rl) {
	if ( rls != null ) 
	    rls.removeElement(rl);
    }

    protected void processEvent(EventObject eo) {
	Vector rls = null;
	ResourceListener rl;
	synchronized(this) {
	    if((this.rls != null) && (eo instanceof ResourceChangeEvent )) {
		rls = (Vector) this.rls.clone();
	    } else {
		return;
	    }
	}
	for(int i=0; i<rls.size(); i++) {
	    rl = (ResourceListener) rls.elementAt(i);
	    rl.resourceChanged((ResourceChangeEvent)eo);
	}
    }

    public void initialize(RemoteResourceWrapper rrw, Properties p)
	throws RemoteAccessException
    {
	int num = 0;
	this.rrw = rrw;
	rr = rrw.getResource();
	ButtonBarListener bbl = new ButtonBarListener();
	this.p = p;
	target.removeAll();
	rh = ResourceHelperFactory.getHelpers(rrw);

	PropertyManager pm = PropertyManager.getPropertyManager();
	Properties props = pm.getEditorProperties(rrw);
	if ((props == null) ||
	    (props.getProperty(UNREMOVABLE_P,
			       "false").equalsIgnoreCase("false")))
	    {
		Panel pan = new Panel();
		Button deleteb = new Button("Delete Resource");
		deleteb.setActionCommand("Delete");
		deleteb.addActionListener(bbl);
		pan.add( new Alert());
		pan.add( deleteb);
		if (rr.isDirectoryResource()) {
		    Button reindexb = new Button("Reindex Children");
		    reindexb.setActionCommand("Reindex");
		    reindexb.addActionListener(bbl);
		    pan.add(reindexb);
		}
		target.setVisible(false);
		target.add("South", pan);
	    }
	if(rh != null) {
	    buttonp = new Panel(new GridLayout(1, rh.length+1));
	    b = new Button[rh.length];
	    for(int i=0; i<rh.length; i++) {
		b[i] = new Button(rh[i].getTitle());
		buttonp.add(b[i]);
		b[i].addActionListener(bbl);
		if (rh[i].getTitle().equalsIgnoreCase("shortcut"))
		    num = i;
	    }
	    editorp = new Panel(new BorderLayout());
	    target.setVisible(false);
	    target.add("North", buttonp);
	    target.add("Center", editorp);
	    target.validate();
	    target.setVisible(true);
	    switchHelper(b[num]);
	} else {
	    target.validate();
	    target.setVisible(true);
	}
    }

    public ResourceEditor(Panel p) {
	target = p;
    }
}




