#ifndef __LIBADT_SLIST_H
#define __LIBADT_SLIST_H
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include "debug.h"
#include "mmm.h"
//use stack memallocation features. need to make some changes in api
//!TODO give for_each macros that can be used
//!TODO add insert element in list for sorting stuff
//!TODO save/load could be just void* list->val that to save, sequently
//when need to compare 2 nodes values with are pointers on anything
// return:
// -1 (<) void 1 is less then void 2
// 0 (=) void 1 is equal to void 2
// 1 (>) void 1 is bigger then void 2
typedef int (*clb_llist_cmp)(void *, void *);
//when need to free whole list and also values of list with are just pointer
//to anything
// param void* - list->val
typedef int (*clb_llist_free)(void *);
//load and save data to file if possible
//return
// 0 - everything is ok
// non-zero - something went wrong
// can put different errors that you whant
//param
//void* - string where to save, or how to save
//void* - linked list that need to save
typedef int (*clb_llist_save)(void *, void *);
//return
// non-zero - some error happened
// 0 - everything is ok
//param
//void* - string from where to load
//void* - list where to save
typedef int (*clb_llist_load)(void *, void **);
typedef struct ListNode
{
struct ListNode *next;
void *val;
} ListNode;
typedef struct List
{
int count;
ListNode *first;
ListNode *last;
} List;
typedef struct ListManager
{
List *list;
int sorted; //auto sort if needed
int mode; // read only
char *name; // list name
clb_llist_cmp *cmp;
clb_llist_free *free;
clb_llist_save *save;
clb_llist_load *load;
} ListManager;
struct List* llist_new();
struct ListNode* llist_newn( void* );
struct ListManager* llist_newm();
//#define __LLIST_NEW()
//#define __LLIST_NEWN()
int llist_length( struct List* );
int llist_index( struct List*, void* );
//llist_find( struct List );
//!find by pointer
//!find by value
void llist_reverse( struct List* );
//void llist_append( struct List*, void* );
void llist_appendn( struct List**, void*, struct ListNode* );
//#define __LIST_APPEND()
// get one element from list and erease it from list
void* llist_pop( struct List* );
void* llist_popf( struct List* );//pop first element of list
//add at the end one element
void llist_push( struct List*, void* );
//remove node from list and return value of element
//void* llist_remove( struct List*, struct ListNode* );
void* llist_removen( struct List*, struct ListNode* );
//delete one element from the list
//void llist_delete( struct List*, void*);
void llist_free( struct List* );
void llist_freen( struct ListNode* );
//void llist_merge( struct List**, struct List* );
//void llist_compare( struct List
//void llist_split( struct List*,
//void llist_splitn( struct List*, struct ListNode*
//void llist_splitp( struct List*, void*
//void llist_splitc( struct List*, void (*)(void*)
//void llist_sort(
//!sort by pointer
//!sort by val value, need compare callback
void llist_sortn( struct List*, clb_llist_cmp );
int llist_save( struct List*, clb_llist_save );
struct List* llist_load( clb_llist_load, const char* );
#define llist_first(A) ((A)->first)
#define llist_last(A) ((A)->last)
//#define LLIST_FOREACH()
//#define LLIST_FOREACH_PREV()
//#define llist_islastn(A) ()
//#define llist_isfirstn(A) ()
//#define llist_getfirstn(A) ((A))
//#define llist_getlastn(A) ()
#endif