// ResourceEditor.java
// $Id: ResourceEditor.java,v 1.15 1998/01/22 13:27:09 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";

    private 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);
      }

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

 	private class Switcher extends Thread {
	    Button b;

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

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

        private 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();
      } 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;
    }
}




