/*
 * (C) Copyright IBM Corp. 1997-1998  All rights reserved.
 *
 * US Government Users Restricted Rights Use, duplication or
 * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
 *
 * The program is provided "as is" without any warranty express or
 * implied, including the warranty of non-infringement and the implied
 * warranties of merchantibility and fitness for a particular purpose.
 * IBM will not be liable for any damages suffered by you as a result
 * of using the Program. In no event will IBM be liable for any
 * special, indirect or consequential damages or lost profits even if
 * IBM has been advised of the possibility of their occurrence. IBM
 * will not be liable for any third party claims against you.
 */

package com.ibm.xml.parser;

import org.w3c.dom.*;
import java.util.*;

/**
 * <P>The <CODE>AttDef</CODE> class implements the <CODE>AttributeDefinition</CODE> interface
 * as defined by the Document Object Model (DOM).
 * <P>This class provides support for a single attribute object that is declared as part of an
 * Element's attribute list declaration in the DTD.  Refer to Attlist for a detailed description.</P>
 *
 * @version 1.1
 * @author TAMURA Kent &lt;kent@trl.ibm.co.jp&gt;
 * @see org.w3c.dom.AttributeDefinition
 * @see com.ibm.xml.parser.Attlist
 * @see com.ibm.xml.parser.Child
 */
public class AttDef extends Child implements AttributeDefinition {

    public  static  final   int         NOFIXED     =   -1; // Adds to AttributeDefinition.DefaultValueType
    public  static  final   int         UNKNOWN     =   0;  // Adds to AttributeDefinition.DeclaredValueType
    public  static  final   String[]    S_TYPESTR   = {
        "*UNKNOWN*",
        "CDATA",
        "ID",
        "IDREF",
        "IDREFS",
        "ENTITY",
        "ENTITIES",
        "NMTOKEN",
        "NMTOKENS",
        "NOTATION",
        "ENUMERATION",
    };
    
            String      name                =   null;       
            int         declaredValueType   =   UNKNOWN;    // Must be AttributeDefinition.DeclaredValueType
            String      value               =   null;
            Vector      tokens              =   null;       // Only used for enumerated atttribute types:
                                                            //   <var>NOTATION</var> and <var>NAME_TOKEN_GROUP</var>.
            int         defaultValueType    =   NOFIXED;    // Must be AttributeDefinition.DefaultValueType
            
    /**
     * Constructor.
     * @param   name        Name of this attribute as defined by the DTD.
     */
    public AttDef(String name) {
        this.name = name;
    }

    /**
     * Clone this attribute definition using the appropriate factory.  
     * <p>This method is defined by Child.
     * @return          Cloned attribute definition.
     * @see com.ibm.xml.parser.Child#clone
     */
    public synchronized Object clone() {
        checkFactory();
        AttDef ad = factory.createAttDef(this.name);
        ad.setFactory(getFactory());
        ad.value = this.value;
        ad.defaultValueType = this.defaultValueType;
        ad.declaredValueType = this.declaredValueType;
        if (null != this.tokens)
            ad.tokens = (Vector)this.tokens.clone();
        return ad;
    }

    /**
     * Returns that this object is an attribute definition Node. 
     * <p>This method is defined by DOM.
     * @return          Attribute definition Node indicator.
     */
    public int getNodeType() {
        return Child.ATTDEF;
    }

    /**
     * Returns the name of this attribute in the DTD definition.  
     * <p>This method is defined by DOM.
     * @return          Name of this attribute in the DTD definition.
     * @see #setName
     */
    public String getName() {
        return this.name;
    }
    
    /**
     * Sets the name of this attribute in the DTD definition.
     * <p>This method is defined by DOM.
     * @param   name    Name of this attribute in the DTD definition.
     * @see #getName
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * Returns the declared type of this attribute in the DTD definition.
     * <p>This method is defined by DOM.
     * @return          Declared type of this attribute in the DTD definition.  Must be
     *                  one of org.w3c.dom.AttributeDefinition#DeclaredValueType
     * @see org.w3c.dom.AttributeDefinition
     * @see #setDeclaredType
     */
    public int getDeclaredType() {
        return this.declaredValueType;
    }
    
    /**
     * Sets the declared type of this attribute in the DTD definition.
     * <p>This method is defined by DOM.
     * @param declaredValueType Declared type of this attribute in the DTD definition.  Must be
     *                          one of org.w3c.dom.AttributeDefinition#DeclaredValueType
     * @see org.w3c.dom.AttributeDefinition
     * @see #getDeclaredType
     */
    public void setDeclaredType(int declaredValueType) {
        this.declaredValueType = declaredValueType;
    }

    /**
     * Returns a Node whose children make up the default value of this attribute
     * in the DTD definition.  This is useful if this attribute was not given an explicit
     * value in the document instance.
     * <p>This method is defined by DOM.
     * <p>This method is CURRENTLY NOT IMPLEMENTED.
     * @return          The Child Node whose children make up the default value of this
     *                  attribute.
     * @see #setDefaultValue
     * @see #getDefaultStringValue
     */
    public Node getDefaultValue() {
        return null;
    }
    
    /**
     * Sets a <var>Node</var> whose children make up the default value of this attribute
     * in the DTD definition.  This is useful if this attribute was not given an explicit
     * value in the document instance.
     * <p>This method is defined by DOM.
     * <p>This method is CURRENTLY NOT IMPLEMENTED.
     * @param   name    The Child Node whose children make up the default value of this
     *                  attribute.
     * @see #getDefaultValue
     * @see #setDefaultStringValue
     */
    public void setDefaultValue(Node node) {
        return;
    }
    
    /**
     * Returns the default value of this attribute in the DTD definition.  
     * This is useful if this attribute was not given an explicit value in the document 
     * instance.  The returned value is only meaningful for attribute types defined as
     * <var>FIXED</var> or <var>NOFIXED</var>.
     * @return          The default value of the attribute, or <var>null</var> if none specified.
     * @see #getDefaultValue
     * @see #setDefaultStringValue
     */
    public String getDefaultStringValue() {
        return this.value;
    }

    /**
     * Sets the default value of this attribute in the DTD definition.  
     * This is useful if this attribute was not given an explicit value in the document 
     * instance.  The specified <var>value</var> is only meaningful for attribute types defined as
     * <var>FIXED</var> or <var>NOFIXED</var>.
     * @param   value   The default value of the attribute in the DTD definition.      
     * @see #setDefaultValue
     * @see #getDefaultStringValue
     */
    public void setDefaultStringValue(String value) {
        this.value = TXAttribute.normalize(getDeclaredType(), value);
    }

    /**
     * Returns a list of all tokens that can be used as values for this enumerated attribute type;
     * the returned value has no meaning for other attribute types.
     * Enumerated attribute types are: <var>NOTATION</var> and <var>NAME_TOKEN_GROUP</var>.
     * <p>This method is defined by DOM.
     * <p>This method is CURRENTLY NOT IMPLEMENTED.
     * @return          The list of allowed tokens for the attribute value as defined by
     *                  the DTD definition, or <var>null</var> if none specified.
     * @see #elements
     * @see #elementAt
     * @see #size
     * @see #contains
     * @see #setAllowedTokens
     */
    public String getAllowedTokens() {
        return null;
    }
    
    /**
     * Sets a list of all tokens that can be used as values for this enumerated attribute type;
     * the returned value has no meaning for other attribute types.
     * Enumerated attribute types are: <var>NOTATION</var> and <var>NAME_TOKEN_GROUP</var>.
     * <p>This method is defined by DOM.
     * <p>This method is CURRENTLY NOT IMPLEMENTED.
     * @param   tokens  The list of allowed tokens for the attribute value as defined by
     *                  the DTD definition. 
     * @see #addElement
     * @see #getAllowedTokens
     */
    public void setAllowedTokens(String tokens) {
    }

    /**
     * Adds the specified <var>token</var> to the end of the list of tokens that can be used as values 
     * for this enumerated attribute type; the specified <var>token</var> has no meaning for 
     * other attribute types. 
     * Enumerated attribute types are: <var>NOTATION</var> and <var>NAME_TOKEN_GROUP</var>.
     * @param token     Value to add to the list of valid tokens for this enumerated attribute.
     * @return          =true if the token does not already exist in this token list; otherwise, =false.
     * @see #elementAt
     * @see #contains
     * @see #size
     * @see #elements
     */
    public boolean addElement(String token) {
        if (null == this.tokens)  this.tokens = new Vector();
        if (0 <= this.tokens.indexOf(token))  return false;
        this.tokens.addElement(token);
        return true;
    }
    
    /**
     * Returns the token at the specified <var>index</var> in the list of tokens that can be used as values 
     * for this enumerated attribute type; the returned token has no meaning for other attribute types. 
     * Enumerated attribute types are: <var>NOTATION</var> and <var>NAME_TOKEN_GROUP</var>.
     * @param index     Index into the list of tokens that can be used as values
     *                  for this enumerated attribute type.
     * @return          Token at the specified index, or <var>null</var> if an invalid index.           
     * @see #addElement
     * @see #contains
     * @see #size
     * @see #elements
     */
    public String elementAt(int index) {
        return null == this.tokens ? null : (String)this.tokens.elementAt(index);
    }
    
    /**
     * Returns whether the specified <var>token</var> is in the list of tokens that can be 
     * used as values for this enumerated attribute type; the returned value has no meaning 
     * for other attribute types. 
     * Enumerated attribute types are: <var>NOTATION</var> and <var>NAME_TOKEN_GROUP</var>.
     * @param token     Value to check in the list of valid tokens for this enumerated attribute.
     * @return          =true if <var>token</var> is defined; otherwise, =false.           
     * @see #addElement
     * @see #elementAt
     * @see #size
     * @see #elements
     */
    public boolean contains(String token) {
        return null == this.tokens ? false : 0 <= this.tokens.indexOf(token);
    }
    
    /**
     * Returns the number of tokens in the list of tokens that can be used as values for 
     * this enumerated attribute type; the returned value has no meaning for other attribute types. 
     * Enumerated attribute types are: <var>NOTATION</var> and <var>NAME_TOKEN_GROUP</var>.
     * @return          Number of tokens, or <var>null</var> if no tokens defined.           
     * @see #addElement
     * @see #elementAt
     * @see #contains
     * @see #elements
     */
    public int size() {
        return null == this.tokens ? 0 : this.tokens.size();
    }

    /**
     * Returns a list of all tokens that can be used as values for this enumerated attribute type;
     * the returned value has no meaning for other attribute types.
     * Enumerated attribute types are: <var>NOTATION</var> and <var>NAME_TOKEN_GROUP</var>.
     * @return          The list of allowed tokens for the attribute value as defined by
     *                  the DTD definition, or <var>null</var> if none specified.
     * @see #addElement
     * @see #elementAt
     * @see #size
     * @see #contains
     */
    public Enumeration elements() {
        return null == this.tokens ? null : this.tokens.elements();
    }
    
    /**
     * Returns the default type of this attribute's value in the DTD definition.  
     * <p>This method is defined by DOM.
     * @return          The default type of this attribute in the DTD definition.  Must be
     *                  one of org.w3c.dom.AttributeDefinition#DefaultValueType
     * @see org.w3c.dom.AttributeDefinition
     * @see #setDefaultType
     */
    public int getDefaultType() {
        return this.defaultValueType;
    }
    
    /**
     * Sets the default type of this attribute's value in the DTD definition.  
     * <p>This method is defined by DOM.
     * @param   defaultValueType    The default type of this attribute in the DTD definition.  Must be
     *                              one of org.w3c.dom.AttributeDefinition#DefaultValueType
     * @see org.w3c.dom.AttributeDefinition
     * @see #getDefaultType
     */
    public void setDefaultType(int defaultValueType) {
        this.defaultValueType = defaultValueType;
    }
}

