/* Copyright 2022-2026 Kurt Nienhaus
 *
 * This file is part of VgaGames.
 * VgaGames 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.
 * VgaGames 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 VgaGames.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include "object.h"

void init_object_mgmt(void);

void vg4_object_mgmt_dump(FILE *);

static struct VG_ObjMgmt * object_mgmt_create(const char *);
static void object_mgmt_destroy(const char *);
static void object_mgmt_destroyall(void);


/* set functions */
void
init_object_mgmt(void)
{
  vg4->object->mgmt_create = object_mgmt_create;
  vg4->object->mgmt_destroy = object_mgmt_destroy;
  vg4->object->mgmt_destroyall = object_mgmt_destroyall;
} /* Ende init_object_mgmt */


/* vg4_object_mgmt_dump:
 * dump object-managements
 * @param outfp  filepointer to dump to, or NULL = stdout
 */
void
vg4_object_mgmt_dump(FILE *outfp)
{
  struct SML3_hash *hptr;
  struct SML3_hashelem *he1;
  struct VG_ObjMgmt *omgmt;

  hptr = vg4data.lists.object.hmgmt;

  if (outfp == NULL) { outfp = stdout; }

  fprintf(outfp, "\nDump of object-managements\n"); 
  fprintf(outfp, "==========================\n\n");

  for (he1 = SML3_hashlist(hptr, NULL, 0); he1 != NULL; he1 = SML3_hashlist(hptr, he1, 0)) {
    omgmt = (struct VG_ObjMgmt *)SML3_hashelem_valget(he1, NULL);
    fprintf(outfp, "- %s\n", omgmt->objid);
    fprintf(outfp, "  f_free=[%s]\n", (omgmt->f_free != NULL ? "set" : "unset"));
    fprintf(outfp, "  f_run=[%s]\n", (omgmt->f_run != NULL ? "set" : "unset"));
    fprintf(outfp, "  f_data=[%s]\n", (omgmt->f_data != NULL ? "set" : "unset"));
    fprintf(outfp, "\n");
  }
} /* Ende object_mgmt_dump */


/* object_mgmt_create:
 * create an object-management
 * @param objid   object-ID
 * @return  object-management
 */
static struct VG_ObjMgmt *
object_mgmt_create(const char *objid)
{
  struct SML3_hash *hptr;
  struct SML3_hashelem *he1;
  struct VG_ObjMgmt *omgmt;

  if (objid == NULL || *objid == '\0') { objid = VGI_OBJID_NONE; }

  hptr = vg4data.lists.object.hmgmt;

  he1 = SML3_hashget(hptr, objid, strlen(objid) + 1);
  if (he1 == NULL) {
    omgmt = SML3_calloc(1, sizeof(*omgmt));
    vg4->misc->strcpy(omgmt->objid, sizeof(omgmt->objid), objid);
    he1 = SML3_hashset(hptr, objid, strlen(objid) + 1);
    SML3_hashelem_valset(he1, omgmt, sizeof(*omgmt));
    free(omgmt);
  }
  omgmt = (struct VG_ObjMgmt *)SML3_hashelem_valget(he1, NULL);

  return omgmt;
} /* Ende object_mgmt_create */


/* object_mgmt_destroy:
 * destroy an object-management
 * @param objid   object-ID
 */
static void
object_mgmt_destroy(const char *objid)
{
  struct SML3_hash *hptr;
  struct SML3_hashelem *he1;
  struct VG_ObjMgmt *omgmt;

  if (objid == NULL || *objid == '\0') { objid = VGI_OBJID_NONE; }

  hptr = vg4data.lists.object.hmgmt;

  he1 = SML3_hashget(hptr, objid, strlen(objid) + 1);
  if (he1 == NULL) { return; }

  omgmt = (struct VG_ObjMgmt *)SML3_hashelem_valget(he1, NULL);
  if (omgmt->f_free != NULL) { omgmt->f_free(); }
  SML3_hashdel(he1);
} /* Ende object_mgmt_destroy */ 


/* object_mgmt_destroyall:
 * destroy all object-managements
 */
static void
object_mgmt_destroyall(void)
{
  struct SML3_hash *hptr;
  struct SML3_hashelem *he1;
  struct VG_ObjMgmt *omgmt;

  hptr = vg4data.lists.object.hmgmt;

  for (he1 = SML3_hashlist(hptr, NULL, 0); he1 != NULL; he1 = SML3_hashlist(hptr, he1, 0)) {
    omgmt = (struct VG_ObjMgmt *)SML3_hashelem_valget(he1, NULL);
    if (omgmt->f_free != NULL) { omgmt->f_free(); }
  }
  SML3_hashfree(&vg4data.lists.object.hmgmt);
} /* Ende object_mgmt_destroyall */
