/*
 * 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 <axutil_array_list.h>
#include <axutil_utils.h>
#include <string.h>

struct axutil_array_list
{

    /**The number of elements in this list. */
    int size;

    /**Current capacity of this list. */
    int capacity;

    /** Where the data is stored. */
    void **data;
};

AXIS2_EXTERN struct axutil_array_list *AXIS2_CALL
axutil_array_list_create(
    const axutil_env_t * env,
    int capacity)
{
    axutil_array_list_t *array_list = NULL;

    array_list = AXIS2_MALLOC(env->allocator, sizeof(axutil_array_list_t));
    if (!array_list)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
		AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory");
        return NULL;
    }

    array_list->size = 0;
    array_list->capacity = 0;
    array_list->data = NULL;

    /* Check capacity, and set the default if error */
    if (capacity <= 0)
        capacity = AXIS2_ARRAY_LIST_DEFAULT_CAPACITY;
    array_list->data = AXIS2_MALLOC(env->allocator, sizeof(void *) * capacity);
    if (!array_list->data)
    {
        axutil_array_list_free(array_list, env);
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
		AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory");
        return NULL;
    }
    array_list->capacity = capacity;

    return array_list;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_array_list_ensure_capacity(
    struct axutil_array_list * array_list,
    const axutil_env_t * env,
    int min_capacity)
{
    AXIS2_PARAM_CHECK (env->error, array_list, AXIS2_FAILURE);
    if (min_capacity > array_list->capacity)
    {
        int new_capacity = (array_list->capacity * 2 >
             min_capacity) ? (array_list->capacity * 2) : min_capacity;
        void **data = (void **) AXIS2_MALLOC(env->allocator,
            sizeof(void *) * new_capacity);
        if (!data)
        {
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
			AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory");
            return AXIS2_FAILURE;
        }
        memcpy(data, array_list->data, sizeof(void *) * array_list->capacity);

        AXIS2_FREE(env->allocator, array_list->data);

        array_list->data = data;
        array_list->capacity = new_capacity;
    }
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN int AXIS2_CALL
axutil_array_list_size(
    struct axutil_array_list *array_list,
    const axutil_env_t * env)
{
    /* Don't use AXIS2_PARAM_CHECK to verify array_list, as it clobbers 
       env->error->status_code on no error destroying the information 
       therein that an error has already occurred. */
    if (!array_list)
        return 0;
    return array_list->size;
}

AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axutil_array_list_is_empty(
    struct axutil_array_list * array_list,
    const axutil_env_t * env)
{
    AXIS2_PARAM_CHECK (env->error, array_list, AXIS2_FAILURE);
    return array_list->size == 0;
}

AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axutil_array_list_contains(
    struct axutil_array_list * array_list,
    const axutil_env_t * env,
    void *e)
{
    AXIS2_PARAM_CHECK (env->error, array_list, AXIS2_FAILURE);
    return axutil_array_list_index_of(array_list, env, e) != -1;
}

AXIS2_EXTERN int AXIS2_CALL
axutil_array_list_index_of(
    struct axutil_array_list *array_list,
    const axutil_env_t * env,
    void *e)
{
    int i = 0;

    AXIS2_PARAM_CHECK (env->error, array_list, AXIS2_FAILURE);
    for (i = 0; i < array_list->size; i++)
        if (e == array_list->data[i])
            return i;
    return -1;
}

AXIS2_EXTERN void *AXIS2_CALL
axutil_array_list_get(
    struct axutil_array_list *array_list,
    const axutil_env_t * env,
    int index)
{
    /* Don't use AXIS2_PARAM_CHECK to verify array_list, as it clobbers 
       env->error->status_code on no error destroying the information 
       therein that an error has already occurred. */
    if (axutil_array_list_check_bound_exclusive(array_list, env, index))
        return array_list->data[index];
    else
        return NULL;
}

AXIS2_EXTERN void *AXIS2_CALL
axutil_array_list_set(
    struct axutil_array_list *array_list,
    const axutil_env_t * env,
    int index,
    void *e)
{
    void *result = NULL;

    AXIS2_PARAM_CHECK (env->error, array_list, NULL);
    if (axutil_array_list_check_bound_exclusive(array_list, env, index))
    {
        result = array_list->data[index];
        array_list->data[index] = e;
    }
    return result;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_array_list_add(
    struct axutil_array_list * array_list,
    const axutil_env_t * env,
    const void *e)
{
    AXIS2_PARAM_CHECK (env->error, array_list, AXIS2_FAILURE);
    if (array_list->size == array_list->capacity)
        if (axutil_array_list_ensure_capacity
            (array_list, env, array_list->size + 1) != AXIS2_SUCCESS)
            return AXIS2_FAILURE;
    array_list->data[array_list->size++] = (void *) e;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_array_list_add_at(
    struct axutil_array_list * array_list,
    const axutil_env_t * env,
    const int index,
    const void *e)
{
    int i = 0;
    AXIS2_PARAM_CHECK (env->error, array_list, AXIS2_FAILURE);

    if (!axutil_array_list_check_bound_inclusive(array_list, env, index))
        return AXIS2_FAILURE;
    if (array_list->size == array_list->capacity)
    {
        if (axutil_array_list_ensure_capacity
            (array_list, env, array_list->size + 1) != AXIS2_SUCCESS)
            return AXIS2_FAILURE;
    }
    if (index != array_list->size)
    {
        for (i = array_list->size; i > index; i--)
            array_list->data[i] = array_list->data[i - 1];
    }
    array_list->data[index] = (void *) e;
    array_list->size++;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN void *AXIS2_CALL
axutil_array_list_remove(
    struct axutil_array_list *array_list,
    const axutil_env_t * env,
    int index)
{
    void *result = NULL;
    int i = 0;
    AXIS2_PARAM_CHECK (env->error, array_list, NULL);

    if (axutil_array_list_check_bound_exclusive(array_list, env, index))
    {
        result = array_list->data[index];
        for (i = index; i < array_list->size - 1; i++)
            array_list->data[i] = array_list->data[i + 1];
        array_list->size--;
    }

    return result;
}

AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axutil_array_list_check_bound_inclusive(
    struct axutil_array_list * array_list,
    const axutil_env_t * env,
    int index)
{
    /* Don't use AXIS2_PARAM_CHECK to verify array_list, as it clobbers 
       env->error->status_code on no error destroying the information 
       therein that an error has already occurred. */
    if (!array_list || index < 0 || index > array_list->size)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INDEX_OUT_OF_BOUNDS,
                        AXIS2_FAILURE);
        return AXIS2_FALSE;
    }
    return AXIS2_TRUE;
}

AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axutil_array_list_check_bound_exclusive(
    struct axutil_array_list * array_list,
    const axutil_env_t * env,
    int index)
{
    /* Don't use AXIS2_PARAM_CHECK to verify array_list, as it clobbers 
       env->error->status_code on no error destroying the information 
       therein that an error has already occurred. */
    if (!array_list || index < 0 || index >= array_list->size)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INDEX_OUT_OF_BOUNDS,
                        AXIS2_FAILURE);
        return AXIS2_FALSE;
    }
    return AXIS2_TRUE;
}

AXIS2_EXTERN void AXIS2_CALL
axutil_array_list_free(
    struct axutil_array_list *array_list,
    const axutil_env_t * env)
{
    AXIS2_PARAM_CHECK_VOID (env->error, array_list);

    if (array_list->data)
    {
        AXIS2_FREE(env->allocator, array_list->data);
    }
    AXIS2_FREE(env->allocator, array_list);
    return;
}

AXIS2_EXTERN void AXIS2_CALL
axutil_array_list_free_void_arg(
    void *array_list,
    const axutil_env_t * env)
{
    axutil_array_list_t *array_list_l = NULL;

    AXIS2_PARAM_CHECK_VOID (env->error, array_list);

    array_list_l = (axutil_array_list_t *) array_list;
    axutil_array_list_free(array_list_l, env);
    return;
}







