
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 <axiom_child_element_iterator.h>

struct axiom_child_element_iterator
{
    axiom_node_t *current_child;
    axiom_node_t *last_child;
    axis2_bool_t next_called;
    axis2_bool_t remove_called;
};

AXIS2_EXTERN axiom_child_element_iterator_t *AXIS2_CALL
axiom_child_element_iterator_create(
    const axutil_env_t * env,
    axiom_node_t * current_child)
{
    axiom_child_element_iterator_t *iterator = NULL;
    AXIS2_ENV_CHECK(env, NULL);

    iterator = (axiom_child_element_iterator_t *) AXIS2_MALLOC(env->allocator,
                                                               sizeof
                                                               (axiom_child_element_iterator_t));

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

    iterator->current_child = current_child;
    iterator->last_child = NULL;

    iterator->next_called = AXIS2_FALSE;
    iterator->remove_called = AXIS2_FALSE;

    return iterator;
}

AXIS2_EXTERN void AXIS2_CALL axiom_child_element_iterator_free(
    void *iterator,
    const axutil_env_t * env)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_FREE(env->allocator, iterator);
    return;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL axiom_child_element_iterator_remove(
    axiom_child_element_iterator_t * iterator,
    const axutil_env_t * env)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, iterator, AXIS2_FAILURE);

    if (!(iterator->next_called))
        return AXIS2_FAILURE;
    if (iterator->remove_called)
        return AXIS2_FAILURE;

    iterator->remove_called = AXIS2_TRUE;

    if (!(iterator->last_child))
        return AXIS2_FAILURE;
    axiom_node_free_tree(iterator->last_child, env);
    iterator->last_child = NULL;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_bool_t AXIS2_CALL axiom_child_element_iterator_has_next(
    axiom_child_element_iterator_t * iterator,
    const axutil_env_t * env)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);

    return (iterator->current_child) ? AXIS2_TRUE : AXIS2_FALSE;
}

AXIS2_EXTERN axiom_node_t *AXIS2_CALL axiom_child_element_iterator_next(
    axiom_child_element_iterator_t * iterator,
    const axutil_env_t * env)
{
    AXIS2_ENV_CHECK(env, NULL);

    iterator->next_called = AXIS2_TRUE;
    iterator->remove_called = AXIS2_FALSE;
    if (iterator->current_child)
    {
        iterator->last_child = iterator->current_child;
        do
        {
            iterator->current_child =
                axiom_node_get_next_sibling(iterator->current_child, env);

        }
        while (iterator->current_child &&
               (axiom_node_get_node_type(iterator->current_child, env)
                != AXIOM_ELEMENT));

        return iterator->last_child;
    }
    return NULL;
}
