/*
 * 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.
 */

#include <axis2_wsdl_extensible_element.h>

/**
 * @brief Wsdl extensible element struct impl
 *   Wsdl extensible element
 */
typedef struct axis2_wsdl_extensible_element_impl
{
    axis2_wsdl_extensible_element_t extensible_element;

    axis2_qname_t *type;

    axis2_bool_t required;

}
axis2_wsdl_extensible_element_impl_t;

#define AXIS2_INTF_TO_IMPL(extensible_element) \
      ((axis2_wsdl_extensible_element_impl_t *)extensible_element)

/************************* Function prototypes ********************************/

axis2_status_t AXIS2_CALL
axis2_wsdl_extensible_element_free(
    axis2_wsdl_extensible_element_t *extensible_element,
    const axis2_env_t *env);

axis2_bool_t AXIS2_CALL
axis2_wsdl_extensible_element_is_required(
    axis2_wsdl_extensible_element_t *extensible_element,
    const axis2_env_t *env);

axis2_status_t AXIS2_CALL
axis2_wsdl_extensible_element_set_required(
    axis2_wsdl_extensible_element_t *extensible_element,
    const axis2_env_t *env,
    axis2_bool_t required);

axis2_qname_t *AXIS2_CALL
axis2_wsdl_extensible_element_get_type(
    axis2_wsdl_extensible_element_t *extensible_element,
    const axis2_env_t *env);

axis2_status_t AXIS2_CALL
axis2_wsdl_extensible_element_set_type(
    axis2_wsdl_extensible_element_t *extensible_element,
    const axis2_env_t *env,
    axis2_qname_t *type);

/************************** End of function prototypes ************************/

axis2_wsdl_extensible_element_t * AXIS2_CALL
axis2_wsdl_extensible_element_create(const axis2_env_t *env)
{
    axis2_wsdl_extensible_element_impl_t *extensible_element_impl = NULL;

    AXIS2_ENV_CHECK(env, NULL);

    extensible_element_impl = (axis2_wsdl_extensible_element_impl_t *)
            AXIS2_MALLOC(env->allocator, sizeof(axis2_wsdl_extensible_element_impl_t));


    if (NULL == extensible_element_impl)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }

    extensible_element_impl->type = NULL;
    extensible_element_impl->extensible_element.ops = NULL;

    extensible_element_impl->extensible_element.ops =
        AXIS2_MALLOC(env->allocator, sizeof(axis2_wsdl_extensible_element_ops_t));
    if (NULL == extensible_element_impl->extensible_element.ops)
    {
        axis2_wsdl_extensible_element_free(&(extensible_element_impl->
                extensible_element), env);
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }

    extensible_element_impl->extensible_element.ops->free =
        axis2_wsdl_extensible_element_free;

    extensible_element_impl->extensible_element.ops->is_required =
        axis2_wsdl_extensible_element_is_required;
    extensible_element_impl->extensible_element.ops->set_required =
        axis2_wsdl_extensible_element_set_required;
    extensible_element_impl->extensible_element.ops->get_type =
        axis2_wsdl_extensible_element_get_type;
    extensible_element_impl->extensible_element.ops->set_type =
        axis2_wsdl_extensible_element_set_type;


    return &(extensible_element_impl->extensible_element);
}

/***************************Function implementation****************************/

axis2_status_t AXIS2_CALL
axis2_wsdl_extensible_element_free(
    axis2_wsdl_extensible_element_t *extensible_element,
    const axis2_env_t *env)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    if (extensible_element->ops)
        AXIS2_FREE(env->allocator, extensible_element->ops);

    if (AXIS2_INTF_TO_IMPL(extensible_element)->type)
    {
        AXIS2_QNAME_FREE(AXIS2_INTF_TO_IMPL(extensible_element)->
                type, env);
        AXIS2_INTF_TO_IMPL(extensible_element)->type = NULL;

    }

    AXIS2_FREE(env->allocator, AXIS2_INTF_TO_IMPL(extensible_element));

    return AXIS2_SUCCESS;
}

axis2_bool_t AXIS2_CALL
axis2_wsdl_extensible_element_is_required(
    axis2_wsdl_extensible_element_t *extensible_element,
    const axis2_env_t *env)
{
    AXIS2_ENV_CHECK(env, AXIS2_FALSE);
    return AXIS2_INTF_TO_IMPL(extensible_element)->required;
}

axis2_status_t AXIS2_CALL
axis2_wsdl_extensible_element_set_required(
    axis2_wsdl_extensible_element_t *extensible_element,
    const axis2_env_t *env,
    axis2_bool_t required)
{
    AXIS2_ENV_CHECK(env, AXIS2_FALSE);

    AXIS2_INTF_TO_IMPL(extensible_element)->required = required;
    return AXIS2_SUCCESS;
}

axis2_qname_t *AXIS2_CALL
axis2_wsdl_extensible_element_get_type(
    axis2_wsdl_extensible_element_t *extensible_element,
    const axis2_env_t *env)
{
    AXIS2_ENV_CHECK(env, NULL);
    return AXIS2_INTF_TO_IMPL(extensible_element)->type;
}

axis2_status_t AXIS2_CALL
axis2_wsdl_extensible_element_set_type(
    axis2_wsdl_extensible_element_t *extensible_element,
    const axis2_env_t *env,
    axis2_qname_t *type)
{
    axis2_wsdl_extensible_element_impl_t *extensible_element_impl =
        AXIS2_INTF_TO_IMPL(extensible_element);

    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, type, AXIS2_FAILURE);

    if (extensible_element_impl->type)
    {
        AXIS2_QNAME_FREE(extensible_element_impl->type, env);
        extensible_element_impl->type = NULL;
    }

    extensible_element_impl->type = AXIS2_QNAME_CLONE(type, env);
    if (!extensible_element_impl->type)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }
    return AXIS2_SUCCESS;
}
