#ifndef	ACL_STACK_INCLUDE_H
#define	ACL_STACK_INCLUDE_H

#ifdef	__cplusplus
extern "C" {
#endif

#include "acl_define.h"
#include "acl_iterator.h"

/* ˵úڲõڴδڴطʽ */

typedef struct ACL_STACK ACL_STACK;

/**
 * ջͶ
 */
struct ACL_STACK {
	int   capacity;
	int   count;
	void **items;

	/* Ӽ */

	/* ջβӶ̬ */
	void  (*push_back)(struct ACL_STACK*, void*);
	/* ջͷӶ̬ */
	void  (*push_front)(struct ACL_STACK*, void*);
	/* ջβ̬ */
	void *(*pop_back)(struct ACL_STACK*);
	/* ջͷ̬ */
	void *(*pop_front)(struct ACL_STACK*);

	/* for acl_iterator */

	/* ȡͷ */
	void *(*iter_head)(ACL_ITER*, struct ACL_STACK*);
	/* ȡһ */
	void *(*iter_next)(ACL_ITER*, struct ACL_STACK*);
	/* ȡβ */
	void *(*iter_tail)(ACL_ITER*, struct ACL_STACK*);
	/* ȡһ */
	void *(*iter_prev)(ACL_ITER*, struct ACL_STACK*);
};

/**
 * ջռС
 * @param s {ACL_STACK*} ջ
 * @param count {int} ӵĿռС
 */
ACL_API void acl_stack_space(ACL_STACK *s, int count);

/**
 * һջ
 * @param init_size {int} ջĳʼռС > 0
 * @return {ACL_STACK*} ´ջ
 */
ACL_API ACL_STACK *acl_stack_create(int init_size);

/**
 * ջĶ󣬵ջ
 * @param s {ACL_STACK*} ջ
 * @param free_fn {void (*)(void*)} Ϊգô˺صջÿһ
 */
ACL_API void acl_stack_clean(ACL_STACK *s, void (*free_fn)(void *));

/**
 * ջĶջ
 * @param s {ACL_STACK*} ջ
 * @param free_fn {void (*)(void*)} Ϊգô˺صջÿһ
 */
ACL_API void acl_stack_destroy(ACL_STACK *s, void (*free_fn)(void *));

/**
 * ջβµĶ
 * @param s {ACL_STACK*} ջ
 * @param obj {void*}
 */
ACL_API void acl_stack_append(ACL_STACK *s, void *obj);
#define	acl_stack_push	acl_stack_append

/**
 * ջͷµĶ
 * @param s {ACL_STACK*} ջ
 * @param obj {void*}
 * ע˲ЧҪ acl_stack_append ͣΪҪƶеĶλ
 */
ACL_API void acl_stack_prepend(ACL_STACK *s, void *obj);

/**
 * ջɾĳ
 * @param s {ACL_STACK*} ջ
 * @param position {int} ջλ
 * @param free_fn {void (*)(void*)} Ϊգô˺صɾ
 */
ACL_API void acl_stack_delete(ACL_STACK *s, int position, void (*free_fn)(void *));

/**
 * @param s {ACL_STACK*} ջ
 * @param obj {void*} ɾĵַ
 * @param free_fn {void (*)(void*)} Ϊգô˺صɾ
 */
ACL_API void acl_stack_delete_obj(ACL_STACK *s, void *obj, void (*free_fn)(void *));

/**
 * ջĳλõĶַ
 * @param s {ACL_STACK*} ջ
 * @param position {int} ջеλ
 * @return {void*} != NULL: ok; == NULL: error򲻴
 */
ACL_API void *acl_stack_index(ACL_STACK *s, int position);

/**
 * ջеǰĶ
 * @param s {ACL_STACK*} ջ
 * @return {int} 
 */
ACL_API int acl_stack_size(const ACL_STACK *s);

/**
 * ջβĶַ, ͬʱöջƳ
 * @param s {ACL_STACK*} ջ
 * @return {void*} ַ, == NULL ʾǰΪ
 */
ACL_API void *acl_stack_pop(ACL_STACK *s);
#define acl_stack_pop_tail acl_stack_pop

/**
 * ջӵĶַ, öջƳ
 * @param s {ACL_STACK*} ջ
 * @return {void*} ַ, == NULL ʾǰΪ
 */
ACL_API void *acl_stack_top(ACL_STACK *s);

#ifdef	__cplusplus
}
#endif

#endif
