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

static void axiom_navigator_update_next_node(
    axiom_navigator_t * om_navigator,
    const axutil_env_t * env);

struct axiom_navigator
{
    axiom_node_t *node;

    axis2_bool_t visited;

    axiom_node_t *next;

    axiom_node_t *root;

    axis2_bool_t backtracked;

    axis2_bool_t end;

    axis2_bool_t start;

};

AXIS2_EXTERN axiom_navigator_t *AXIS2_CALL
axiom_navigator_create(
    const axutil_env_t * env,
    axiom_node_t * om_node)
{
    axiom_navigator_t *om_navigator = NULL;
    AXIS2_ENV_CHECK(env, NULL);
    AXIS2_PARAM_CHECK(env->error, om_node, NULL);

    om_navigator =
        (axiom_navigator_t *) AXIS2_MALLOC(env->allocator,
                                           sizeof(axiom_navigator_t));
    if (!om_navigator)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }

    om_navigator->node = NULL;
    om_navigator->visited = AXIS2_FALSE;
    om_navigator->next = NULL;
    om_navigator->root = NULL;
    om_navigator->end = AXIS2_FALSE;
    om_navigator->start = AXIS2_TRUE;
    om_navigator->backtracked = AXIS2_FALSE;

    om_navigator->next = om_node;
    om_navigator->root = om_node;

    return om_navigator;
}

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

AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axiom_navigator_is_navigable(
    axiom_navigator_t * om_navigator,
    const axutil_env_t * env)
{
    if (AXIS2_TRUE == om_navigator->end)
    {
        return AXIS2_FALSE;
    }
    else
    {
        if (om_navigator->next)
        {
            return AXIS2_TRUE;
        }
    }
    return AXIS2_FALSE;
}

AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axiom_navigator_is_completed(
    axiom_navigator_t * om_navigator,
    const axutil_env_t * env)
{
    return om_navigator->end;
}

AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axiom_navigator_visited(
    axiom_navigator_t * om_navigator,
    const axutil_env_t * env)
{
    return om_navigator->visited;
}

AXIS2_EXTERN axiom_node_t *AXIS2_CALL
axiom_navigator_next(
    axiom_navigator_t * om_navigator,
    const axutil_env_t * env)
{
    AXIS2_ENV_CHECK(env, NULL);

    if (!om_navigator->next)
    {
        return NULL;
    }

    om_navigator->node = om_navigator->next;
    om_navigator->visited = om_navigator->backtracked;
    om_navigator->backtracked = AXIS2_FALSE;

    axiom_navigator_update_next_node(om_navigator, env);

    /** set the starting and ending flags */
    if (om_navigator->root == om_navigator->next)
    {
        if (!(om_navigator->start))
        {
            om_navigator->end = AXIS2_TRUE;
        }
        else
        {
            om_navigator->start = AXIS2_FALSE;
        }
    }
    return om_navigator->node;
}

/** this method encapsulate searching logic */
static void
axiom_navigator_update_next_node(
    axiom_navigator_t * om_navigator,
    const axutil_env_t * env)
{
    if (!om_navigator)
    {
        return;
    }

    if (!om_navigator->next)
    {
        return;
    }

    if ((AXIOM_ELEMENT == axiom_node_get_node_type(om_navigator->next, env)) &&
        !(om_navigator->visited))
    {
        if (axiom_node_get_first_child(om_navigator->next, env))
        {
            om_navigator->next =
                axiom_node_get_first_child(om_navigator->next, env);
        }
        else if (AXIS2_TRUE == axiom_node_is_complete(om_navigator->next, env))
        {
            om_navigator->backtracked = AXIS2_TRUE;
        }
        else
        {
            om_navigator->next = NULL;
        }
    }
    else
    {
        axiom_node_t *parent = NULL;
        axiom_node_t *next_sibling = NULL;

        next_sibling = axiom_node_get_next_sibling(om_navigator->next, env);

        parent = axiom_node_get_parent(om_navigator->next, env);

        if (next_sibling)
        {
            om_navigator->next = next_sibling;
        }
        else if ((parent) && axiom_node_is_complete(parent, env))
        {
            om_navigator->next = parent;
            om_navigator->backtracked = AXIS2_TRUE;
        }
        else
        {
            om_navigator->next = NULL;
        }
    }
}
