/*
BOIL (Brunni's Own Interpreter Language)
(c) 1998 netEstate (http://www.netestate.de/, info@netestate.de),
Michael Brunnbauer & Markus Hendel, Gesellschaft fuer Netzwerkkommunikation bR
Am Bluetenanger 8, 80995 Muenchen, Germany

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
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include "general.h"
#include "handles.cc"
#include "boil.h"
#include "boil.tab.h"
#include "libs.h"

int args_tcache_get[]= { TYPE_VALUE_STRING,
                         TYPE_VALUE_STRING,
                         TYPE_VALUE_STRING,
                         0 };

flowctrl func_tcache_get(type_block* aktblock,opt* options,
                         joined_list<type_value>* args)
{
  aktblock=aktblock;options=options;args=args; /* to prevent warnings */
  flowctrl back;
  back.ctrl=FLOW_RETURN;
  back.returnval.type=TYPE_VALUE_STRING;
  
  if (!defined((*args)[0].stringval) ||
      !defined((*args)[1].stringval) ||
      !defined((*args)[2].stringval))
    {
      setvarulong("error",1);
      setvarstring("perror","tcache_get: string not defined");
      return back;
    };

  hashdir<joined_list<cachefield>,string,256,0>* table=
    tcache.get_listelem((*args)[0].stringval);
  if (!table) { return back; };

  joined_list<cachefield>* cols=table->get_listelem((*args)[1].stringval);
  if (!cols) { return back; };
  unsigned long colslen=cols->length();
  for (unsigned long i=0;i!=colslen;i++)
    {
      if ((*cols)[i].name==(*args)[2].stringval)
	{ back.returnval.stringval=(*cols)[i].value; break; };
    };
  return back;
}

int args_tcache_set[]= { TYPE_VALUE_STRING,
                         TYPE_VALUE_STRING,
                         TYPE_VALUE_STRING,
                         TYPE_VALUE_STRING,
                         0 };

flowctrl func_tcache_set(type_block* aktblock,opt* options,
                         joined_list<type_value>* args)
{
  aktblock=aktblock;options=options;args=args; /* to prevent warnings */
  flowctrl back;
  back.ctrl=FLOW_RETURN;
  back.returnval.type=TYPE_VALUE_VOID;
  unsigned long i,u;

  if (!defined((*args)[0].stringval) ||
      !defined((*args)[1].stringval) ||
      !defined((*args)[2].stringval) ||
      !defined((*args)[3].stringval))
    {
      setvarulong("error",1);
      setvarstring("perror","tcache_set: string not defined");
      return back;
    };

  hashdir<joined_list<cachefield>,string,256,0>* table;

  /* cleaning up if using too much mem */
  if (string_mem>tcache_size)
    {
      /* increment actual index hash */
      tcache_hash++;
      
      /* hash-values for tables */
      for (i=0;i!=256;i++)
	{
	  /* tables for a hash value */
	  for (u=0;u!=tcache.values[i].length();u++)
	    {
              /* delete last index for actual hash */
	      table=&tcache.values[i][u];
	      unsigned long hashlen=table->names[tcache_hash].length();
	      if (hashlen)
		{
		  printf("deleting index %s in %s\n",
			 (char*) table->names[tcache_hash][hashlen-1],
			 (char*) tcache.names[i][u]);
		  fflush(stdout);
		  table->remove_listelem(table->names[tcache_hash][hashlen-1]);
		};
	    };
	};
    };
  
  table=tcache.get_listelem((*args)[0].stringval);
  if (!table)
    {
      table=new hashdir<joined_list<cachefield>,string,256,0>();
      if (!table) { return back; };
      tcache.insert_listelem(*table,(*args)[0].stringval);
      delete table;
      table=tcache.get_listelem((*args)[0].stringval);
    };

  joined_list<cachefield>* cols=
    table->get_listelem((*args)[1].stringval);
  if (!cols)
    { 
      cols=new joined_list<cachefield>();
      if (!cols) { return back; };
      table->insert_listelem(*cols,(*args)[1].stringval);
      delete cols;
      cols=table->get_listelem((*args)[1].stringval);
    };

  unsigned long colslen=cols->length();
  string* value=0;
  for (i=0;i!=colslen;i++)
    {
      if ((*cols)[i].name==(*args)[2].stringval)
	{ value=&(*cols)[i].value; break; };
    };

  if (value)
    {
      *value=(*args)[3].stringval;
    }
  else
    {
      cachefield cfield;
      cfield.name=(*args)[2].stringval;
      cfield.value=(*args)[3].stringval;
      cols->insert_listelem(cfield);
    };
  
  return back;
}

int args_tcache_del[]= { TYPE_VALUE_STRING,
                         TYPE_VALUE_STRING,
                         0 };

flowctrl func_tcache_del(type_block* aktblock,opt* options,
                         joined_list<type_value>* args)
{
  aktblock=aktblock;options=options;args=args; /* to prevent warnings */
  flowctrl back;
  back.ctrl=FLOW_RETURN;
  back.returnval.type=TYPE_VALUE_VOID;

  if (!defined((*args)[0].stringval) ||
      !defined((*args)[1].stringval))
    {
      setvarulong("error",1);
      setvarstring("perror","tcache_set: string not defined");
      return back;
    };

  hashdir<joined_list<cachefield>,string,256,0>* table=
    tcache.get_listelem((*args)[0].stringval);
  if (!table) { return back; };

  table->remove_listelem((*args)[1].stringval);
  return back;
}

int args_tcache_setsize[]= { TYPE_VALUE_ULONG,
			     0 };

flowctrl func_tcache_setsize(type_block* aktblock,opt* options,
			     joined_list<type_value>* args)
{
  aktblock=aktblock;options=options;args=args; /* to prevent warnings */
  flowctrl back;
  back.ctrl=FLOW_RETURN;
  back.returnval.type=TYPE_VALUE_VOID;

  tcache_size=(*args)[0].val.ulongval;
  return back;
}

int args_tcache_getsize[]= { 0 };

flowctrl func_tcache_getsize(type_block* aktblock,opt* options,
                             joined_list<type_value>* args)
{
  aktblock=aktblock;options=options;args=args; /* to prevent warnings */
  flowctrl back;
  back.ctrl=FLOW_RETURN;
  back.returnval.type=TYPE_VALUE_ULONG;
  
  back.returnval.val.ulongval=string_mem;
  return back;
}
