// This file is a part of the xMule Project.
//
// Copyright (c) 2004 Theodore R. Smith (hopeseekr@xmule.ws / http://www.xmule.ws/)
// DSA-1024 Fingerprint: 10A0 6372 9092 85A2 BB7F 907B CB8B 654B E33B F1ED
//
// Copyright (C)2002 Merkur ( merkur-@users.sourceforge.net / http://www.xmule-project.net )
//
// This program 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 2 of the License, or (at your option) any later version.
// 
// This program 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 this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

#include "config.h"                         // HAVE_MALLOC_H

#include <wx/wx.h>
#include <wx/sckaddr.h>
#include <wx/filesys.h>
#include <wx/fs_zip.h>
#include <wx/wfstream.h>

#include <netdb.h>
#include <pthread.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "xmule.h"

#include "ClientCredits.h"
#include "NewFunctions.h"
#include "otherfunctions.h"

uint32_t globaldata2 = 0;

uint32_t MapData(MAP * pos)
{
    return pos->Data;
}

void md4printf(const void * hash)
{
    printf("md4hash: ");
    for (int i = 0 ; i < 16 ; i++)
    {
        printf("%02x", ((unsigned char *) hash) [i]);
    }
    printf("\n");
}

unsigned char * pckprintf(char * info)
{
    int i, s, c;
    unsigned char * t, * c0;
    c0 = (unsigned char *) info;
    s = strlen(info);
    t = (unsigned char *) malloc(1 + (s >> 1));
    for (int i = 0 ; i < s ; i++)
    {
        c = c0 [i];
        if ((c >= 'a') && (c <= 'z'))
        {
            c = c - 'a' + 10;
        }
        else if((c >= '0') && (c <= '9'))
        {
            c = c - '0';
        }
        else
        {
            printf("fehler: %u(%u)\n", c, i);
        }
        if (i & 1)
        {
            t[i >> 1] += c & 15;
        }
        else
        {
            t[i >> 1] = (c & 15) <<4;
        }
    }
    return t;
}

void hexprintf(char * info, const void * buffer, int length)
{
    printf("%s:\n", info);
    for (int i = 0 ; i < length ; i++)
    {
        printf("%02x", ((unsigned char *) buffer) [i]);
    }
    printf("\n");
}

void ascprintf(char * info, const void * buffer, int length)
{
    unsigned char c;
    printf("%s:\n", info);
    for (int i = 0 ; i < length ; i++)
    {
        c = ((unsigned char *) buffer) [i];
        if ((c >= 'a') && (c <= 'z'))
        {
            printf("%c", c);
        }
        else if((c >= 'A') && (c <= 'Z'))
        {
            printf("%c", c);
        }
        else if((c >= '0') && (c <= '9'))
        {
            printf("%c", c);
        }
        else
        {
            printf(".");
        }
    }
    printf("\n");
}

unsigned char * MapDataKey(MAP * pos)
{
    return pos->Key;
}

void MapData_Init(MAP *& base)
{
    base = (MAP *) malloc(sizeof(MAP));
    base->Key = NULL;
    base->Data = 0;
    base->Data2 = 0;
    base->next = base;
    base->prev = base;
}

uint32_t MapData_GetCount(MAP * base)
{
    return base->Data;
}

void * MapData_GetIt(MAP * pos)
{
    if (pos)
    {
        return(void *) pos->Data;
    }
    else
    {
        return(void *) NULL;
    }
}

MAP * MapData_Find(MAP * base, void * tofind, int length)
{
    MAP * found;
    found = base;
    while (length)
    {
        found = MapData_GetNext(found);
        if (found)
        {
            if (found->Key)
            {
                if (!memcmp(found->Key, tofind, length))
                {
                    length = 0;
                }
            }
            else
            {
                found = NULL;
                length = 0;
            }
        }
        else
        {
            length = 0;
        }
    }
    return found;
}

MAP * MapData_GetNext(MAP * next)
{
    if (next)
    {
        next = next->next;
        if (next->Key == NULL)
        {
            next = NULL;
        }
    }
    else
    {
        next = NULL;
    }
    return next;
}

void MapData_Append(MAP * base, void * data, void * key, int length)
{
    if (!length)
    {
        length = 4;
    }
    MAP * toinsert;
    toinsert = (MAP *) malloc(sizeof(MAP));
    toinsert->Key = (unsigned char *) malloc(length);
    if (globaldata2)
    {
        toinsert->Data2 = globaldata2;
        if (!data)
        {
            toinsert->Data = globaldata2;
        }
        globaldata2 = 0;
    }
    else
    {
        toinsert->Data2 = 0;
    }
    toinsert->Data = (uint32_t) data;
    toinsert->prev = base->prev;
    toinsert->next = base;
    if(key) {
    memcpy(toinsert->Key, key, length);
    } else {
    memcpy(toinsert->Key, &toinsert->Data, length);
    }
    base->prev->next = toinsert;
    base->prev = toinsert;
    base->Data++;
    //return toinsert;
}

void MapData_Insert(MAP * base, void * data, void * key, int length)
{
    if (!length)
    {
        length = 4;
    }
    MAP * toinsert;
    toinsert = (MAP *) malloc(sizeof(MAP));
    toinsert->Key = (unsigned char *) malloc(length);
    if (globaldata2)
    {
        toinsert->Data2 = globaldata2;
        if (!data)
        {
            toinsert->Data = globaldata2;
        }
        globaldata2 = 0;
    }
    else
    {
        toinsert->Data2 = 0;
    }
    toinsert->Data = (uint32_t) data;
    toinsert->prev = base;
    toinsert->next = base->next;
    if(key) {
    memcpy(toinsert->Key, key, length);
    } else {
    memcpy(toinsert->Key, &toinsert->Data, length);
    }
    base->next->prev = toinsert;
    base->next = toinsert;
    base->Data++;
    //return toinsert;
}

MAP * MapData_Remove(MAP * base, MAP * todelete)
{
    MAP * next = NULL;
    if (base->Data)
    {
        delete todelete->Key;
        todelete->Key = NULL;
        todelete->Data = 0;
        next = todelete->next;
        next->prev = todelete->prev;
        next->prev->next = next;
        todelete->next = NULL;
        todelete->prev = NULL;
        free(todelete);
        base->Data--;
    }
    else
    {
        next = todelete;
    }
    return next;
}

void MapData_RemoveAll(MAP * base)
{
    MAP * pos;
    pos = base->next;
    while (pos->Key)
    {
        pos = MapData_Remove(base, pos);
    }
}

