#include    "gen_linklist.h"
#include "platform.h"
#include <stdio.h>

// https://blog.csdn.net/swwlqw/article/details/22498833

/*-------------- insert ------------------------------
* insert data to any postion
*/
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#undef container_of
#define container_of(ptr, type, member) ((type *)(((size_t)ptr) - offsetof(type, member)))

typedef struct gen_linknodebuf_STR{
	unsigned char status;
	GenLinkNode node;
}GenLinkNodebuf;

GenLinkNodebuf gen_linknodebuf[500]={0};

GenLinkNode* gen_malloc(void)
{
		for(unsigned short i = 0;i < 500;i++)
		{
					if(gen_linknodebuf[i].status == 0 ){
						gen_linknodebuf[i].status = 1;
						return &gen_linknodebuf[i].node;
					}
		}
		return NULL;
}

void gen_free(GenLinkNode * nodetemp)
{
		GenLinkNodebuf * temp;
		temp = container_of(nodetemp,struct gen_linknodebuf_STR,node);
		temp->status = 0;
}





unsigned char gen_linklist__insert(GenLinkList* const list,void *pele,unsigned short index)
{
    uint8_t rtn=1;
    PLATFORM_DISABLE_IRQ();
    
    if(list->length < index) 
    {
        rtn = 0;
    }
    else
    {
        //GenLinkNode *node = (GenLinkNode *)malloc(sizeof(GenLinkNode));
		GenLinkNode *node = gen_malloc();
        if(node ==NULL)
        {
             rtn = 0;
        }
        else
        {
            node->next = NULL;
            node->pdata = pele;

            GenLinkNode *pnode_tmp= list->front;
            for(unsigned short i=0;i<index;i++){
                if(pnode_tmp!=NULL)
                pnode_tmp =pnode_tmp->next;
            }//for
            node->next =pnode_tmp->next;
            pnode_tmp->next =node;
            (list->length)++; 
        }
    }    
    PLATFORM_ENABLE_IRQ();
    return rtn; 

}

/* -------------- detele  ------------------------------
* detele node at any postion
*/
void* gen_linklist__detele(GenLinkList* const list,unsigned short index)
{
    void * rtn = NULL;
    PLATFORM_DISABLE_IRQ();
    if(list->length <= index) 
    {
        rtn = NULL;
    }
    else
    {
        GenLinkNode *pnode_tmp= list->front;
        for(unsigned short i=0;i<index;i++){
            if(pnode_tmp!=NULL)
            pnode_tmp =pnode_tmp->next;
        }//for

        GenLinkNode *pnode_record= pnode_tmp->next;
        
        if(pnode_record!=NULL)
        {
            pnode_tmp->next = pnode_tmp->next->next;
            rtn =pnode_record->pdata;
            //free(pnode_record);
			gen_free(pnode_record);
            if(list->length)
                (list->length)--;
        }
        else{
        
            rtn=NULL;
        
        } //
            
    }
    PLATFORM_ENABLE_IRQ();	
    return rtn;
}

/*-------------- get ele ------------------------------
* get element of index;
*/
void* gen_linklist__get_ele(GenLinkList* const list,unsigned short index)
{
    if( list->length <= index) return NULL;

    GenLinkNode *pnode_tmp= list->front->next;//diff with no head
    for(unsigned short i=0;i<index;i++){
//        if(pnode_tmp->next != NULL)
        pnode_tmp =pnode_tmp->next;
    }//for
    
    if(pnode_tmp != NULL)
        return pnode_tmp->pdata;
    else
        return NULL;
}

/*-------------- get len ------------------------------
* get length of linklist 
*/
unsigned short gen_linklist__get_len(GenLinkList* const list)
{
    return list->length;
}


