#ifndef ACL_DLINK_INCLUDE
#define ACL_DLINK_INCLUDE

#ifdef __cplusplus
extern "C" {
#endif

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

/**
 * ֿԪͶ
 */
typedef	struct {
	acl_int64 begin;
	acl_int64 end;
	void *pnode;
} ACL_DITEM;

/**
 * ֿͶ
 */
typedef	struct ACL_DLINK {
	ACL_ARRAY *parray;
	void *call_back_data;

	/* for acl_iterator */

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

/**
 * һֿ
 * @param nsize {int} ʼС
 * @return {ACL_DLINK*} ֿ
 */
ACL_API ACL_DLINK *acl_dlink_create(int nsize);

/**
 * ͷһֿ
 * @param plink {ACL_DLINK*} ָֿ
 */
ACL_API void acl_dlink_free(ACL_DLINK *plink);

/**
 * ݶֿԪزǷڶֿ
 * @param plink {ACL_DLINK*} ָֿ
 * @param pitem {ACL_DITEM*} ݿԪ
 * @return {ACL_DITEM*} ݿԪ
 */
ACL_API ACL_DITEM *acl_dlink_lookup_by_item(const ACL_DLINK *plink,
	ACL_DITEM *pitem);

/**
 * ԪزҶֿеԪ
 * @param plink {const ACL_DLINK*} ָֿ
 * @param pitem {ACL_DITEM*} ݿԪ
 * @param pidx {int*} 洢ѯԪؽڶе±λ
 * @return {ACL_DITEM*} ݿԪ
 */
ACL_API ACL_DITEM *acl_dlink_lookup2_by_item(const ACL_DLINK *plink,
	ACL_DITEM *pitem, int *pidx);

/**
 * ӶֿвѯĳֵӦݿԪصַ
 * @param plink {const ACL_DLINK*} ָֿ
 * @param n {acl_int64} ѯֵ
 * @return {ACL_DITEM*} ݿԪ
 */
ACL_API ACL_DITEM *acl_dlink_lookup(const ACL_DLINK *plink, acl_int64 n);

/**
 * ӶֿвѯĳֵӦݿԪصַ¼±λ
 * @param plink {const ACL_DLINK*} ָֿ
 * @param n {acl_int64} ѯֵ
 * @param pidx {int*} 洢ѯԪؽڶе±λ
 * @return {ACL_DITEM*} ݿԪ
 */
ACL_API ACL_DITEM *acl_dlink_lookup2(const ACL_DLINK *plink,
	acl_int64 n, int *pidx);

/**
 * ӶֿвѯĳΧݿԪصַ¼±λ
 * @param plink {const ACL_DLINK*} ָֿ
 * @param begin {acl_int64} ѯΧʼλֵ
 * @param end {acl_int64} ѯΧĽλֵ
 * @param pidx {int*} 洢ѯԪؽڶе±λ
 * @return {ACL_DITEM*} ݿԪ
 */
ACL_API ACL_DITEM *acl_dlink_lookup_range(const ACL_DLINK *plink,
	acl_int64 begin, acl_int64 end, int *pidx);

/**
 * ӶֿвѯһĳֵݿԪز¼±λ
 * @param plink {const ACL_DLINK*} ָֿ
 * @param off {acl_int64} Ƚֵ
 * @param pidx {int*} 洢ѯԪؽڶе±λ
 * @return {ACL_DITEM*} ݿԪ
 */
ACL_API ACL_DITEM *acl_dlink_lookup_larger(const ACL_DLINK *plink,
	acl_int64 off, int *pidx);

/**
 * ӶֿвѯһСĳֵݿԪز¼±λ
 * @param plink {const ACL_DLINK*} ָֿ
 * @param off {acl_int64} Ƚֵ
 * @param pidx {int*} 洢ѯԪؽڶе±λ
 * @return {ACL_DITEM*} ݿԪ
 */
ACL_API ACL_DITEM *acl_dlink_lookup_lower(const ACL_DLINK *plink,
	acl_int64 off, int *pidx);

/**
 * ֿʼݿ
 * @param plink {ACL_DLINK*} ָֿ
 * @param begin {acl_int64} ʼλֵ
 * @param end {acl_int64} λֵ
 * @return {ACL_DITEM*} ´ݿԪ
 */
ACL_API ACL_DITEM *acl_dlink_insert(ACL_DLINK *plink,
	acl_int64 begin, acl_int64 end);

/**
 * ӶֿɾĳֵݿԪ
 * @param plink {ACL_DLINK*} ָֿ
 * @param n {acl_int64} λֵ
 * @return {int} 0ʾOK-1: ʾǷ򲻴
 */
ACL_API int acl_dlink_delete(ACL_DLINK *plink, acl_int64 n);

/**
 * ݿԪشӶֿɾݿԪ
 * @param plink {ACL_DLINK*} ָֿ
 * @param pitem {ACL_DITEM*} ݿԪ
 * @return {int} 0ʾOK-1: ʾǷ
 */
ACL_API int acl_dlink_delete_by_item(ACL_DLINK *plink, ACL_DITEM *pitem);

/**
 * ͬ acl_dlink_insert
 * @DEPRECATED ˺Ҳṩ
 */
ACL_API ACL_DITEM *acl_dlink_modify(ACL_DLINK *plink,
	acl_int64 begin, acl_int64 end);

/**
 * ӶɾĳֵΧݿ鼯, 
 * ɾпܻڲµݿԪ
 * @param plink {ACL_DLINK*} ָֿ
 * @param begin {acl_int64} ҪɾΧʼλ
 * @param end {acl_int64} ҪɾΧĽλ
 * @return {int} 0ʾOK-1: ʾǷ
 */
ACL_API int acl_dlink_delete_range(ACL_DLINK *plink,
	acl_int64 begin, acl_int64 end);

/**
 * ĳ±λõݿԪصַ
 * @param plink {const ACL_DLINK*} ָֿ
 * @param idx {int} ±λ
 * @return {ACL_DITEM*} NULL: ±Խ; != NULL: ݿԪصַ
 */
ACL_API ACL_DITEM *acl_dlink_index(const ACL_DLINK *plink, int idx);

/**
 * õǰݿĸܺ
 * @param plink {const ACL_DLINK*} ָֿ
 * @return {int} ݿĸ
 */
ACL_API int acl_dlink_size(const ACL_DLINK *plink);

/**
 * ()ӡݿʼλõϢ
 * @param plink {const ACL_DLINK*} ָֿ
 * @return {int} 0ʾOK-1: ʾǷ
 */
ACL_API int acl_dlink_list(const ACL_DLINK *plink);

#ifdef __cplusplus
}
#endif
#endif
