/* object OBJID_OSOFT */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include "obj-osoft.h"

unsigned int objnew_OSOFT(void *, int, int, const char *, const char *);

static void f_free(void *, void *);
static void f_draw(void *, struct VG_Object *);
static int f_data(void *, struct VG_Object *, void *);


/* export-function to create a new object-instance of OBJID_OSOFT
 * @param vgame   private structure of the game
 * @param xm      x-position (center)
 * @param ym      y-position (center)
 * @param nd1     node1 to (de)activate link
 * @param nd2     node2 to (de)activate link
 * @return  instance-ID or 0 = error
 */
unsigned int
objnew_OSOFT(void *vgame, int xm, int ym, const char *nd1, const char *nd2)
{
  const int coll_percent = 100;
  struct s_game *sgame = (struct s_game *)vgame;
  struct VG_Object *objp;
  struct sobj_osoft *objvars;
  char pfad[512];

  if (sgame == NULL) { return 0; }

  /* create private struct */

  objvars = calloc(1, sizeof(*objvars));
  if (objvars == NULL) { return 0; }

  /* load image or sprite */
  snprintf(pfad, sizeof(pfad), "files/images/osoft/%d/osoft.sprite", sgame->svdt.dnew.gamelevel + 1);
  if (access(pfad, R_OK) == 0) { objvars->sprt = vg4->sprite->load(pfad); }
  if (objvars->sprt == NULL) {
    snprintf(pfad, sizeof(pfad), "files/images/osoft/%d/osoft.bmp", sgame->svdt.dnew.gamelevel + 1);
    objvars->imgp = vg4->image->load(pfad);
    if (objvars->imgp == NULL) { f_free(vgame, objvars); return 0; }
    vg4->image->getsize(objvars->imgp, NULL, &objvars->rect.w, &objvars->rect.h);
  } else {
    int anzblk = vg4->sprite->get_blocks(objvars->sprt);
    vg4->sprite->go_block(objvars->sprt, ZUFALL(OBJID_OSOFT, 1, anzblk));
    vg4->sprite->imagesize(objvars->sprt, "avg", &objvars->rect.w, &objvars->rect.h);
  }

  objvars->rect.x = xm - objvars->rect.w / 2;
  objvars->rect.y = ym - objvars->rect.h / 2;

  if (*nd1 != '\0' && *nd2 != '\0') {
    vg4->misc->strcpy(objvars->nd1, sizeof(objvars->nd1), nd1);
    vg4->misc->strcpy(objvars->nd2, sizeof(objvars->nd2), nd2);
    vg4->nodelink->deactivate(sgame->nodes.ndlnk, objvars->nd1, objvars->nd2, VG_TRUE);
  }

  /* create object-instance */
  objp = vg4->object->create(OBJID_OSOFT, 0, 0, 2, objvars);
  objp->f_free = f_free;
  objp->f_draw = f_draw;
  objp->f_data = f_data;

  /* insert object-instance into collision-tag */
  vg4->collision->insert(sgame->coll_tag, objp->instanceid, &objvars->rect, coll_percent);

  return objp->instanceid;
}


/* free private struct of object-instance, called from vg4->object->destroy() */
static void
f_free(void *vgame, void *opriv)
{
  struct sobj_osoft *objvars = (struct sobj_osoft *)opriv;
  struct s_game *sgame = (struct s_game *)vgame;

  if (sgame == NULL) { return; }

  /* free private struct */
  if (objvars->sprt != NULL) {
    vg4->sprite->destroy(objvars->sprt);
  } else if (objvars->imgp != NULL) {
    vg4->image->destroy(objvars->imgp);
  }

  if (*objvars->nd1 != '\0' && *objvars->nd2 != '\0') {
    vg4->nodelink->activate(sgame->nodes.ndlnk, objvars->nd1, objvars->nd2, VG_TRUE);
  }

  free(objvars);
}


/* draw object-instance, called from vg4->object->call_draw() */
static void
f_draw(void *vgame, struct VG_Object *objp)
{
  struct sobj_osoft *objvars = (struct sobj_osoft *)objp->opriv;
  struct VG_Position posi;
  struct VG_Image *imgp;
  struct VG_ImagecopyAttr iattr;

  (void)vgame;

  VG_IMAGECOPY_ATTR_DEFAULT(&iattr);

  if (objvars->sprt != NULL) {
    vg4->sprite->next(objvars->sprt, &imgp, &iattr);
  } else {
    imgp = objvars->imgp;
  }
  if (imgp == NULL) { return; }

  vg4->misc->rect2position(&posi, &objvars->rect);
  posi = vg4->misc->bgposition_getobj(posi);
  vg4->window->copy(imgp, &posi, &iattr);
}


/* get/set data from/for object-instance, called from vg4->object->call_data() */
static int
f_data(void *vgame, struct VG_Object *objp, void *vptr)
{
  struct s_game *sgame = (struct s_game *)vgame;
  struct sobj_osoft *objvars = (struct sobj_osoft *)objp->opriv;
  const char *objid = (const char *)vptr;

  if (sgame == NULL) { return 0; }

  /* set goody */
  if (objid != NULL) { vg4->misc->strcpy(objvars->gd_objid, sizeof(objvars->gd_objid), objid); }

  return 1;
}
