/*
 * Atom table functions
 *
 * Copyright 1993, 1994, 1995 Alexandre Julliard
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>

#include "windows.h"
#include "xmalloc.h"

#ifdef CONFIG_IPC
#include "dde_atom.h"
#include "options.h"
#endif

#define MIN_STR_ATOM              0xc000

typedef struct
{
  WORD  refCount;
  BYTE  length;
  char* str;
} ATOMDATA;

typedef struct
{
  void* next;
  ATOMDATA a2h[16];
} ATOMtoHANDLEtable;

static ATOMtoHANDLEtable* GlobalAtomTable = NULL;
static ATOMtoHANDLEtable*  LocalAtomTable = NULL;


/***********************************************************************
 *           ATOM_Init
 *
 * Global table initialisation.
 */
BOOL ATOM_Init(void)
{
  return TRUE;
}


/***********************************************************************
 *           ATOM_AddAtom
 */
static ATOM ATOM_AddAtom( ATOMtoHANDLEtable** tableptr, SEGPTR name )
{
    ATOMDATA* FirstUnused;
    ATOM FirstUnusedIndex;
    ATOM Index;
    ATOMtoHANDLEtable* table;
    int i,len;
    char *str;

    /* Check for integer atom */

    if (!HIWORD(name)) return (ATOM)LOWORD(name);
    str = (char*)name;
    if (str[0] == '#') return atoi( &str[1] );

    if ((len = strlen( str )) > 255) len = 255;
    table = *tableptr;
    FirstUnused = NULL;
    FirstUnusedIndex = 0;
    Index = MIN_STR_ATOM;
    while (table)
    {
      for(i=0; i<16; i++, Index++)
      {
	if (!table->a2h[i].refCount)
	{
	  FirstUnused=&table->a2h[i];
	  FirstUnusedIndex=Index;
	}
	else if ((table->a2h[i].length == len) && 
		 (!lstrncmpi( table->a2h[i].str, str, len )))
	{
	    table->a2h[i].refCount++;
	    return Index;
	}
      }
      tableptr = (ATOMtoHANDLEtable**)&table->next;
      table = table->next;
    }
    if(!FirstUnused)
    {
      *tableptr = xmalloc(sizeof(ATOMtoHANDLEtable));
      (*tableptr)->next = NULL;
      for(i=0; i<16; i++)
      {
	(*tableptr)->a2h[i].str = NULL;
	(*tableptr)->a2h[i].refCount = 0;
      }
      FirstUnused = (*tableptr)->a2h;
      FirstUnusedIndex = Index;
    }
    if((FirstUnused->str = malloc(len+1)))
    {
      memcpy( FirstUnused->str, str, len );
      FirstUnused->str[len] = 0;
    }
    else
      return 0;
    FirstUnused->refCount = 1;
    FirstUnused->length = len;
    return FirstUnusedIndex;
}


/***********************************************************************
 *           ATOM_DeleteAtom
 */
static ATOM ATOM_DeleteAtom( ATOMtoHANDLEtable** tableptr, ATOM atom )
{    
    ATOMtoHANDLEtable* table;
    int i;
    ATOM Index;

    if (atom < MIN_STR_ATOM) return 0;  /* Integer atom */

    Index = MIN_STR_ATOM;
    table = *tableptr;
    while (table)
    {
      if(atom-Index < 16)
      {
	i=atom-Index;

	/* Delete atom */
	if (--table->a2h[i].refCount == 0)
	{
	  free(table->a2h[i].str);
	  table->a2h[i].str=NULL;
	}    
	return 0;
      }
      else
      {
	Index+=16;
	table = table->next;
      }
    }
    return atom;
}


/***********************************************************************
 *           ATOM_FindAtom
 */
static ATOM ATOM_FindAtom( ATOMtoHANDLEtable** tableptr, SEGPTR name )
{
    ATOM Index;
    ATOMtoHANDLEtable* table;
    int i,len;
    char *str;

    /* Check for integer atom */

    if (!HIWORD(name)) return (ATOM)LOWORD(name);
    str = (char*)name;
    if (str[0] == '#') return atoi( &str[1] );

    if ((len = strlen( str )) > 255) len = 255;
    table=*tableptr;
    Index=MIN_STR_ATOM;
    while (table)
    {
      for(i=0; i<16; i++, Index++)
      {
	if ((table->a2h[i].refCount != 0) &&
	    (table->a2h[i].length == len) && 
	    (!lstrncmpi( table->a2h[i].str, str, len )))
	  return Index;
      }
      table=table->next;
    }
    return 0;
}


/***********************************************************************
 *           ATOM_GetAtomName
 */
static WORD ATOM_GetAtomName( ATOMtoHANDLEtable** tableptr, ATOM atom,
                              LPSTR buffer, short count )
{
    ATOMtoHANDLEtable* table;
    ATOM Index;
    char * strPtr=NULL;
    int i,len=0;
    char text[8];
    
    if (!count) return 0;
    if (atom < MIN_STR_ATOM)
    {
	sprintf( text, "#%d", atom );
	len = strlen(text);
	strPtr = text;
    }
    else
    {
      Index = MIN_STR_ATOM;
      table = *tableptr;
      while (table)
      {
	if(atom-Index < 16)
	{
	  i=atom-Index;
	  
	  if (table->a2h[i].refCount == 0)
	    table=NULL;
	  else
	  {
	    len = table->a2h[i].length;
	    strPtr = table->a2h[i].str;
	  }
	  break;
	}
	else
	{
	  Index+=16;
	  table = table->next;
	}
      }
      if(!table)return 0;
    }
    if (len >= count) len = count-1;
    memcpy( buffer, strPtr, len );
    buffer[len] = '\0';
    return len;
}


/***********************************************************************
 *           InitAtomTable   (KERNEL.68)
 */
WORD InitAtomTable( WORD entries )
{
    return entries;
}


/***********************************************************************
 *           GetAtomHandle   (KERNEL.73)
 */
HANDLE GetAtomHandle( ATOM atom )
{
  fprintf(stderr,"JBP: GetAtomHandle() called (obsolete).\n");
  return 0;
}


/***********************************************************************
 *           AddAtom   (KERNEL.70)
 */
ATOM AddAtom( SEGPTR str )
{
    return ATOM_AddAtom( &LocalAtomTable, (SEGPTR)str );
}


/***********************************************************************
 *           DeleteAtom   (KERNEL.71)
 */
ATOM DeleteAtom( ATOM atom )
{
    return ATOM_DeleteAtom( &LocalAtomTable, atom );
}


/***********************************************************************
 *           FindAtom   (KERNEL.69)
 */
ATOM FindAtom( SEGPTR str )
{
    return ATOM_FindAtom( &LocalAtomTable, str );
}


/***********************************************************************
 *           GetAtomName   (KERNEL.72)
 */
WORD GetAtomName( ATOM atom, LPSTR buffer, short count )
{
    return ATOM_GetAtomName( &LocalAtomTable, atom, buffer, count );
}


/***********************************************************************
 *           GlobalAddAtom   (USER.268)
 */
ATOM GlobalAddAtom( SEGPTR str )
{
#ifdef CONFIG_IPC
    if (Options.ipc) return DDE_GlobalAddAtom( str );
#endif
    return ATOM_AddAtom( &GlobalAtomTable, str );
}


/***********************************************************************
 *           GlobalDeleteAtom   (USER.269)
 */
ATOM GlobalDeleteAtom( ATOM atom )
{
#ifdef CONFIG_IPC
    if (Options.ipc) return DDE_GlobalDeleteAtom( atom );
#endif
    return ATOM_DeleteAtom( &GlobalAtomTable, atom );
}


/***********************************************************************
 *           GlobalFindAtom   (USER.270)
 */
ATOM GlobalFindAtom( SEGPTR str )
{
#ifdef CONFIG_IPC
    if (Options.ipc) return DDE_GlobalFindAtom( str );
#endif
    return ATOM_FindAtom( &GlobalAtomTable, str );
}


/***********************************************************************
 *           GlobalGetAtomName   (USER.271)
 */
WORD GlobalGetAtomName( ATOM atom, LPSTR buffer, short count )
{
#ifdef CONFIG_IPC
    if (Options.ipc) return DDE_GlobalGetAtomName( atom, buffer, count );
#endif
    return ATOM_GetAtomName( &GlobalAtomTable, atom, buffer, count );
}
