/*
 * Copyright 2004,2005 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef AXIS2_OM_DOCTYPE_H
#define AXIS2_OM_DOCTYPE_H

/**
 *@file axis2_om_doctype.h	
 *@brief defines struct representing xml DTD and its manipulation functions
 */

#include <axis2_om_node.h>
#include <axis2_om_output.h>

#ifdef __cplusplus
extern "C"
{
#endif

    struct axis2_om_doctype;
    struct axis2_om_doctype_ops;

/**
 * @defgroup axis2_om_doctype OM Doctype
 * @ingroup axis2_om 
 * @{
 */

  /**
    * \brief OM doctype ops struct
    * Encapsulator struct for ops of axis2_om_doctype
    */
 AXIS2_DECLARE_DATA   typedef struct axis2_om_doctype_ops
    {
      /**
        * free doctype struct
        * @param om_doctype pointer to axis2_om_doctype_t struct to be freed
        * @param env Environment. MUST NOT be NULL,
        * @return satus of the op. AXIS2_SUCCESS on success
        *         AXIS2_FAILURE on error.
        */
        axis2_status_t (AXIS2_CALL *
        free)(struct axis2_om_doctype *om_doctype,
              axis2_env_t **env);
       /**
        * @param om_doctype pointer to a axis2_om_doctype_t struct
        * @param env environment must not be null       
        * @return DTD text 
        */
        axis2_char_t* (AXIS2_CALL *
        get_value)(struct axis2_om_doctype *om_doctype,
                   axis2_env_t **env);
       /**
        * @param om_doctype pointer to axis2_om doctype_t struct
        * @param env environment , MUST NOT be NULL.
        * @param value doctype text value
        * @return status of the op,
        *         AXIS2_SUCCESS on success, AXIS2_FAILURE on error.
        */

        axis2_status_t (AXIS2_CALL *
        set_value)(struct axis2_om_doctype *om_doctype,
                   axis2_env_t **env,
                   const axis2_char_t *value);
       /**
        * serialize op 
        * @param om_doctype pointer to axis2_om_doctype_t struct
        * @param env environment , MUST NOT be NULL
        * @param om_output pointer to axis2_om_output_t struct
        * @returns status of the op,
        *          AXIS2_SUCCESS on success, AXIS2_FAILURE on error.
        */                                   
        
        axis2_status_t (AXIS2_CALL *
        serialize)(struct axis2_om_doctype *om_doctype,
                   axis2_env_t **env,
                   axis2_om_output_t *om_output);
                                                                                                                                      
    } axis2_om_doctype_ops_t;

  /**
    * \brief OM doctype struct
    * Handles XML document type in OM
    */
    typedef struct axis2_om_doctype
    {
        /** Doctype related ops */
        axis2_om_doctype_ops_t *ops;

    } axis2_om_doctype_t;

  /**
    * Creates a axis2_om_doctype_t struct
    * @param env Environment. MUST  NOT be NULL,
    * @param parent parent of the new node. Optinal, can be NULL. 
    * @param value doctype text
    * @param node This is an out parameter.cannot be NULL.
    *               Returns the node corresponding to the doctype created.
    *               Node type will be set to AXIS2_OM_DOCTYPE
    * @return pointer to newly created doctype struct 
    */
    AXIS2_DECLARE(axis2_om_doctype_t *)
    axis2_om_doctype_create (axis2_env_t **env,
                             axis2_om_node_t * parent,
                             const axis2_char_t * value,
                             axis2_om_node_t ** node);

/** free given doctype */    
#define AXIS2_OM_DOCTYPE_FREE(doctype, env) \
        ((doctype)->ops->free(doctype, env))
/** returns the value of doctype */
#define AXIS2_OM_DOCTYPE_GET_VALUE(doctype, env) \
        ((doctype)->ops->get_value(doctype, value))
/** set the doctype value */
#define AXIS2_OM_DOCTYPE_SET_VALUE(doctype, env, value) \
        ((doctype)->ops->set_value(doctype, env, value))
/** serialize op */       
#define AXIS2_OM_DOCTYPE_SERIALIZE(doctype, env, om_output) \
        ((doctype)->ops->serialize(doctype, env, om_output))

/** @} */
    
#ifdef __cplusplus
}
#endif

#endif                          /* AXIS2_OM_DOCTYPE_H */
