#ifndef CODE_WINLIST_CXX
#define CODE_WINLIST_CXX

/*-----------------------------------------------------------------------
 * Xclasses code file
 * ($Id: win_list.cxx,v 1.1.1.1 1998/07/16 19:29:27 cvs Exp $)
 * 
 * Copyright (C) 1998 Jürgen Schmitz
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA  02111-1307, USA.
 *-----------------------------------------------------------------------
 */

#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
#include <string.h>
#include "types.h"
#include <Xclasses/group.h>
#include <Xclasses/gadget.h>


#define MAXHASH	25
static ggs		*alle[MAXHASH]={NULL,};
static ggs		*nohash_start=NULL,*nohash_end=NULL;

#define MAXFONTHASH	25
static struct ffs {
	struct ffs *next;
	XFontStruct *f;
	char name[1];
} *falle[MAXFONTHASH]={NULL,};


static int hashmaximum(void)
{
	return MAXHASH-1;
}
static int hashauslastung(int h)
{
	int n=0;
    ggs *g;
    g=alle[h];

    while (g)
    {
		n++;
        g=g->next;
    }
	return n;
}
int hashtest(void)
{
	int t,n=0,m=0,h,z=0;
	for(int i=0;i<=hashmaximum();i++)
	{
		printf("%02d ",i);
		n+=hashauslastung(i);
	}
	t=n;
	printf("\n");
	for(int i=0;i<=hashmaximum();i++)
	{
		h=hashauslastung(i);
		if (h>m) m=h;
		if (h<t) t=h;
		if (h==0) z++;
		printf("%02d ",h);
	}
	printf("\n\nTotal items %d, Hash cells %d, Min fill %d, Max fill %d, Free cells %d (%d%%)\n",n,hashmaximum()+1,t,m,z,(100*z/(hashmaximum()+1)));
	if ((m-t)>2)
	{
		printf("Hash table is bad used.\n");
		return 0;
	}
	else
	{
		printf("Hash table is well used!\n");
		return 1;
	}
}

static int calchash(Window win)
{
	return (win % MAXHASH);
}
void Add(struct ggs *g)
{
	int h=calchash(g->win);
	g->hashwert=h;
	g->next=alle[h];
	g->prev=(struct ggs*)&alle[h];
	g->nohash_next=NULL;
	g->nohash_prev=nohash_end;
	if (nohash_end)	nohash_end->nohash_next=g;
	nohash_end=g;
	if (!nohash_start) nohash_start=g;
	if (alle[h])
	{
		alle[h]->prev=g;
	}
	alle[h]=g;
}
void Rem(struct ggs *g)
{
	if (g->next)
	{
		g->next->prev=g->prev;
	}
	if (g->prev)
	{
		g->prev->next=g->next;
	}
	if (g->nohash_next)
	{
		g->nohash_next->nohash_prev=g->nohash_prev;
	}
	else
	{
		nohash_end=g->nohash_prev;
	}
	if (g->nohash_prev)
	{
		g->nohash_prev->nohash_next=g->nohash_next;
	}
	else
	{
		nohash_start=g->nohash_next;
	}
	delete g;
}
struct ggs *FindGG(Window win,int typ)
{
    ggs *g;
    int h=calchash(win);
    g=alle[h];

    while (g)
    {
        if (g->win==win)
        {
        	return g;
//        	if (g->typ & typ) return g; else return NULL;
        }
        g=g->next;
    }
    return NULL;
}
struct ggs *NextGG(ggs *old,int typ)
{
	if (old)
	{
		int h=old->hashwert;

		if (old->next) return old->next;

		while (++h<MAXHASH)
		{
	    	old=(struct ggs*)&alle[h];
	    	if (old->next) return old->next;
		}
    }
    else
    {
    	int h=0;
    	do
    	{
	    	old=(struct ggs*)&alle[h];
	    	if (old->next) return old->next;
		}
		while (++h<MAXHASH);
    }
    return NULL;
}
struct ggs *nohash_NextGG(ggs *old)
{
	if (!old) return nohash_start;
	old=old->nohash_next;
	return old;
}
struct ggs *nohash_PrevGG(ggs *old)
{
	if (!old) return nohash_end;
	old=old->nohash_prev;
	return old;
}


static int calcfonthash(char *f)
{
	int i,l=strlen(f),s=l;

	for(i=0;i<l;i++) s+=f[i];
	return s % MAXFONTHASH;
}
void fontAdd(char *n,XFontStruct *f)
{
	struct ffs *g;

	if (g=(struct ffs*)new char[sizeof(struct ffs)+strlen(n)+1])
	{
		int h=calcfonthash(n);
		g->next=falle[h];
		g->f=f;
		strcpy(g->name,n);
		falle[h]=g;
	}	
}
XFontStruct *FindFont(char *n)
{
    struct ffs *g;
    int h=calcfonthash(n);
    g=falle[h];

    while (g)
    {
        if (!strcasecmp(n,g->name))
        {
			return g->f;
        }
        g=g->next;
    }
    return NULL;
}
void FreeFonts(Display *d)
{
	struct ffs *g1,*g2;
	int h;

	for(h=0;h<MAXFONTHASH;h++)
	{
		g1=falle[h];
		while (g1)
		{
			g2=g1->next;
			XFreeFont(d,g1->f);
			delete [] (char*)g1;
			g1=g2;
		}
		falle[h]=NULL;
	}
}

#endif
