// GenericResourceEditor.java
// $Id: GenericResourceEditor.java,v 1.12 1997/04/04 07:35:58 abaird Exp $
// (c) COPYRIGHT MIT and INRIA, 1996.
// Please first read the full copyright statement in file COPYRIGHT.html

package w3c.jigsaw.formedit;


import java.util.* ;
import java.net.*;

import w3c.tools.store.*;
import w3c.jigsaw.http.*;
import w3c.jigsaw.resources.*;
import w3c.jigsaw.forms.*;
import w3c.jigsaw.html.*;


class AttributeCardHandler extends FormCardHandler {
    Resource target = null ;

    /**
     * A field value has changed, forward to the target.
     * @param field The field whose value changed.
     * @param value The value of the field.
     */

    public void notifyChange(FormFieldInterface field, Object value) 
	throws FormFieldException 
    {
	try {
	    target.setValue(field.getName(), value) ;
	} catch (IllegalAttributeAccess ex) {
	    throw new FormFieldException(field.getName()
					 + " cannot be set to "
					 + value
					 + " (IllegalAttributeException).");
	}
    }
	
    AttributeCardHandler(Resource target) {
	this.target = target ;
    }

}

public class GenericResourceEditor extends FormResource {
    /**
     * Attribute index - Our target resource.
     */
    protected static int ATTR_TARGET = -1 ;
    
    static {
	Attribute a   = null ;
	Class     cls = null ;
	try {
	    cls = Class.forName("w3c.jigsaw.formedit.GenericResourceEditor");
	} catch (Exception ex) {
	    ex.printStackTrace() ;
	    System.exit(1) ;
	}
	// The target attribute:
	a = new ObjectAttribute("target"
				, "w3c.tools.store.Resource"
				, null
				, Attribute.DONTSAVE) ;
	ATTR_TARGET = AttributeRegistry.registerAttribute(cls, a) ;
    }

    /**
     * The attributes defined by the class of our target.
     */
    protected Attribute target_attributes[] = null ;

    /**
     * Get the target resource we are editing.
     */

    public Resource getTarget() {
	return (Resource) getValue(ATTR_TARGET, null);
    }

    /**
     * Dump some title in the header.
     */

    public void dumpHeader(HtmlGenerator into) {
	// Try to link to our parent directory, if possible:
	Resource resource = getTarget();
	if ( resource instanceof HTTPResource) {
	    HTTPResource target = (HTTPResource) resource;
	    HTTPResource parent = target.getParent();
	    if ( parent != null ) {
		String parlnk = null;
		try {
		    String editor = getParent().getURLPath();
		    parlnk = editor + parent.getURLPath();
		} catch (Exception ex) {
		}
		if ( parlnk != null ) 
		    into.append("<h3>Parent: <a href=\""+parlnk+"\">"
                                + parent.getIdentifier()
				+ "</a></h3>");
	    }
	}
	// Always display the class name:
	into.append("<h2>"+getTarget().getClass().getName()+"</h2>");
    }

    /**
     * Define the cards for our target.
     * We define only the attribute card here.
     */

    protected void defineCards() {
	FormFieldInterface   field   = null ;
	Resource             target  = getTarget() ;
	AttributeCardHandler handler = new AttributeCardHandler(target) ;
	FormCardResource     card    = defineCard(handler
						  , "Attributes"
						  , "Attributes of "
						  + target.getIdentifier());
	// Add link to the edited resource:
	if ( target.definesAttribute("url") ) {
	    try {
		String url = (String) target.getValue("url", null);
		card.addField(new LinkField(url, "Resource url", null, url));
	    } catch (ClassCastException ex) {
	    }
	}
	// Provide a field for each attribute:
	for (int i = 0 ; i < target_attributes.length ; i++) {
	    Attribute a = target_attributes[i] ;
	    if ( ! a.checkFlag(Attribute.EDITABLE) )
		continue ;
	    field = FormFieldRegistry.getField(target, a);
	    if ( field != null ) 
		card.addField(field) ;
	}
    }

    /**
     * intitialize the editor.
     * @param values The default attribute values.
     * @exception HolderInitException If unable to init (here, if we
     *    don't get provided with a target to edit).
     */

    public void initialize(Object values[]) {
	// Super intialize first:
	super.initialize(values) ;
	// Set up: check target, and get attributes to be edited.
	Resource target = getTarget() ;
	if ( target == null ) 
	    throw new HolderInitException ("No target to edit.");
	Class cls = target.getClass() ;
	this.target_attributes = AttributeRegistry.getClassAttributes(cls) ;
	defineCards();
    }

}
