// FormFieldRegistry.java
// $Id: FormFieldRegistry.java,v 1.6 1997/01/17 09:52:10 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 w3c.tools.store.*;
import w3c.jigsaw.resources.*;
import w3c.jigsaw.forms.*;

public class FormFieldRegistry {
    /**
     * The field registery. Maps attribute classes to FormField classes.
     */
    private static Hashtable fields = new Hashtable() ;

    static {
	registerField("w3c.tools.store.BooleanAttribute"
		      , "w3c.jigsaw.forms.BooleanField") ;
	registerField("w3c.tools.store.ClassAttribute"
		      , "w3c.jigsaw.forms.ClassnameField") ;
	registerField("w3c.tools.store.DateAttribute"
		      , "w3c.jigsaw.forms.DateField") ;
	registerField("w3c.tools.store.DoubleAttribute"
		      , "w3c.jigsaw.forms.DoubleField") ;
	registerField("w3c.jigsaw.resources.EncodingAttribute"
		      , "w3c.jigsaw.forms.EncodingField") ;
	registerField("w3c.tools.store.IntegerAttribute"
		      , "w3c.jigsaw.forms.IntegerField") ;
	registerField("w3c.tools.store.LongAttribute"
		      , "w3c.jigsaw.forms.LongField") ;
	registerField("w3c.jigsaw.resources.LanguageAttribute"
		      , "w3c.jigsaw.forms.LanguageField") ;
	registerField("w3c.jigsaw.resources.MimeTypeAttribute"
		      , "w3c.jigsaw.forms.MimeTypeField") ;
	registerField("w3c.tools.store.StringArrayAttribute"
		      , "w3c.jigsaw.forms.TextArrayField") ;
	registerField("w3c.tools.store.StringAttribute"
		      , "w3c.jigsaw.forms.TextField") ;
	registerField("w3c.tools.store.FileAttribute"
		      , "w3c.jigsaw.forms.FileField") ;
	registerField("w3c.tools.store.FilenameAttribute"
		      , "w3c.jigsaw.forms.FilenameField") ;
	registerField("w3c.tools.store.PropertiesAttribute"
		      , "w3c.jigsaw.forms.PropertiesField");
    }

    /**
     * Register a form field to edit the givan class of attributes.
     * @param acls The class of the editable attribute.
     * @param fcls The class of the form field to use.
     */

    public static synchronized void registerField(Class acls, Class fcls) {
	fields.put(acls, fcls) ;
    }

    /**
     * Register a form field to edit the givan class of attributes.
     * @param aclsname The name of the class of the editable attribute.
     * @param fclsname The name of the class of the form field to use.
     * @exception RuntimeException If the class names can't be resolved.
     */

    public static synchronized void registerField(String aclsname
						  , String fclsname) {
	try {
	    Class acls = Class.forName(aclsname) ;
	    Class fcls = Class.forName(fclsname) ;
	    registerField(acls, fcls) ;
	} catch (Exception ex) {
	    throw new RuntimeException ("Can't resolve one of "
					+ aclsname
					+ " or " 
					+ fclsname) ;
	}
    }

    /**
     * Get a suitable form field to edit the given attribute of the target.
     * @param target The target resource to edit.
     * @param a What attribute of the target needs edits.
     * @return An instance conforming to the FormFieldInterface, or
     *    <strong>null</strong> if no such form field was registered.
     */

    public static synchronized 
    FormFieldInterface getField(Resource target, Attribute a) {
	Class cls   = (Class) fields.get(a.getClass()) ;
	
	if ( cls == null )
	    return null ;
	try {
	    FormFieldInterface field = (FormFieldInterface) cls.newInstance() ;
	    Object             value = target.getValue(a.getName(), null) ;
	    String             hurl  = target.getHelpURL(a.getName());

	    field.initialize(a.getName()
			     , a.getName()
			     , (hurl != null) ? hurl+"#"+a.getName() : null
			     , value) ;
	    // A bad, but usefull hack
	    if ( field instanceof FormField )
		((FormField) field).setURLWindowName("jigsaw-help");
	    return field;
	} catch (Exception ex) {
	    ex.printStackTrace() ;
	    return null ;
	}
    }

    /**
     * Get a form field to edit a shadow attribute of target.
     * @param target The shadower resource.
     * @param a The attribute to edit.
     * @return An instance conforming to the FormFieldInterface, or
     *    <strong>null</strong> if no such form field was registered.
     */

    public static synchronized 
    FormFieldInterface getTargetField(ResourceShadower target, Attribute a) {
	Class cls   = (Class) fields.get(a.getClass()) ;
	
	if ( cls == null )
	    return null ;
	try {
	    FormFieldInterface field = (FormFieldInterface) cls.newInstance() ;
	    Object             value = target.getTargetValue(a.getName(),null);
	    field.initialize(a.getName(), a.getName(), null, value) ;
	    return field;
	} catch (Exception ex) {
	    ex.printStackTrace() ;
	    return null ;
	}
    }

}
