/* Copyright 2013 Akira Ohta (akohta001@gmail.com)
    This file is part of ntch.

    The ntch is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    The ntch is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with ntch.  If not, see <http://www.gnu.org/licenses/>.
    
*/
#ifndef _NT_STD_T_H_
#define _NT_STD_T_H_ 

#ifndef NULL
#define NULL ((void*)0)
#endif
#define TRUE 1
#define FALSE 0

typedef int BOOL;
typedef void (*nt_memfree_fn)(void* ptr);
typedef int (*nt_compare_fn)(void *lhs, void *rhs);
typedef int (*nt_compare_n_fn)(int a, int b);

typedef struct tag_nt_link_t *nt_link_tp;
typedef struct tag_nt_link_t{
	union{
		void * data;
		int n_data;
	};
	nt_link_tp prev;
	nt_link_tp next;
} nt_link_t;

typedef struct tag_nt_stack_t *nt_stack_tp;
typedef struct tag_nt_stack_t{
	int cursor;
	nt_link_tp linkp;
	nt_link_tp unlinkedp;
} nt_stack_t;

typedef struct tag_nt_enum_handle *nt_enum_handle;
typedef struct tag_nt_enum_handle {
	int chk_sum;
}nt_enum_handle_t;

typedef struct tag_nt_map_handle *nt_map_handle;
typedef struct tag_nt_map_handle {
	int chk_sum;
}nt_map_handle_t;

typedef struct tag_nt_queue_handle *nt_queue_handle;
typedef struct tag_nt_queue_handle{
	int chk_sum;
} nt_queue_handle_t;

#define nt_enum_release(a) nt_enum_unset((a))

/* 
 * nt_enum_handle nt_enum_set(nt_link_tp linkp)
 * Set NULL to the linkp is accesptable and returns
 * an empty enumerator object (not NULL).
 * When you get a valid object, 
 * you must free it by calling nt_enum_unset. */
extern nt_enum_handle nt_enum_set(nt_link_tp linkp);

extern void nt_enum_reset(nt_enum_handle handle);
extern void nt_enum_unset(nt_enum_handle handle);
extern void* nt_enum_fetch(nt_enum_handle handle);
extern int nt_enum_get_count(nt_enum_handle handle);
extern void nt_enum_set_free_func(nt_enum_handle handle, nt_memfree_fn free_func);

extern nt_map_handle nt_map_alloc();
extern void nt_map_free(nt_map_handle handle, nt_memfree_fn value_free_func);
extern BOOL nt_map_add_pair(nt_map_handle handle, const wchar_t *key, void *value);
extern void* nt_map_find(nt_map_handle handle, const wchar_t *key);
extern void* nt_map_remove(nt_map_handle handle, const wchar_t *key);
extern int nt_map_get_count(nt_enum_handle handle);

extern nt_queue_handle nt_queue_alloc();
extern void nt_queue_free(nt_queue_handle h_que, nt_memfree_fn free_func);
extern BOOL nt_queue_push(nt_queue_handle h_que, void* data);
extern void* nt_queue_shift(nt_queue_handle h_que);
extern int nt_queue_get_count(nt_queue_handle h_que);

extern void* nt_stack_push(nt_stack_tp stackp, void* data);
extern void* nt_stack_peek(nt_stack_tp stackp);
extern void* nt_stack_pop(nt_stack_tp stackp);
extern void* nt_stack_cursor_next();
extern void* nt_stack_add_last(nt_stack_tp stackp, void* data);
extern int nt_stack_get_position(nt_stack_tp stackp);
extern BOOL nt_stack_is_empty(nt_stack_tp stackp);

extern nt_stack_tp nt_stack_alloc();
extern void nt_stack_free(nt_stack_tp ptr, nt_memfree_fn free_func);

extern nt_link_tp nt_link_add_data(nt_link_tp link, void *data);
extern nt_link_tp nt_link_add_n_data(nt_link_tp link, int  n_data);
extern nt_link_tp nt_link_insert_before(nt_link_tp top_linkp,
			nt_link_tp dest, nt_link_tp src);
extern nt_link_tp nt_link_add_last(nt_link_tp top_linkp, nt_link_tp src);
extern nt_link_tp nt_link_remove(nt_link_tp src, nt_link_tp target);
extern nt_link_tp nt_link_remove2(nt_link_tp src, nt_link_tp target);
extern nt_link_tp nt_link_remove_by_data(nt_link_tp link, void *data);
extern void* nt_link_get(nt_link_tp link);
extern nt_link_tp nt_link_find(nt_link_tp link, void *data, 
			nt_compare_fn comp_func);
extern void nt_link_sort(nt_link_tp *linkp, nt_compare_fn comp_func);
extern void nt_link_n_sort(nt_link_tp *linkp, 
			nt_compare_n_fn comp_func);
extern nt_link_tp nt_link_next(nt_link_tp link);
extern int nt_link_num(nt_link_tp linkp);
extern void* nt_link_get_by_index(nt_link_tp linkp, int index);
extern void nt_all_link_free(nt_link_tp ptr, nt_memfree_fn free_func);
extern nt_link_tp nt_link_copy(nt_link_tp src_linkp);

typedef struct tag_nt_key_value_t *nt_key_value_tp;
typedef struct tag_nt_key_value_t{
	char *key;
	char *value;
}nt_key_value_t;

typedef struct tag_nt_w_key_value_t *nt_w_key_value_tp;
typedef struct tag_nt_w_key_value_t{
	wchar_t *key;
	void *value;
}nt_w_key_value_t;

extern nt_key_value_tp nt_key_value_alloc(char *key, char *value);
extern nt_w_key_value_tp nt_w_key_value_alloc(const wchar_t *key, void *value);

#endif /* _NT_STD_T_H_ */
