//
// File: register.cpp
// All functions related to 3d-device registration should be placed here
// Author: F.J. Alberti
// Created: 10/07/2001
//
// FA  24/10/2001   Undefine MX3hardware
//

#include <stdlib.h>
#include <string.h>
#include "../base.h"         // future SDK types.h
#include "../macros.h"
#include "register.h"
extern "C" {
# include "../loadpak.h"
}


static NativeDefinition defs[] = {
  { "MX3getDeviceList", 0, "fun [] [[S S] r1]", MX3getDeviceList }
};

// Maximum number of supported registered 3D devices
static const uint kMaxDevices = 16;

// The device table
static struct {
  char* name;  // device name (as it appears in usm.ini)
  char* id;    // device id   (as it appears in usm.ini)
} dev[kMaxDevices];

// The index of the last device registered (in the range [0, kMaxDevices-1]
static uint devcnt = 0;


// Error messages generated by MX3registerDevice:
#define MSGEDEVNULLNAME   "Device name is null"
#define MSGEDEVNULLID     "Device id for '%s' is null"
#define MSGEDEVTABLEFULL  "Device table overflow. Only %d devices can be registered"


void regX3D(char* name, void* address)
// This function has been deprecated, but it is still exported
{
}


int MX3getDeviceList(mmachine m)
{
  SECHECK(SEPUSH(m, NIL));
  for (uint i = 0; i < devcnt; i++) {
    SECHECK(SEPUSHSTR(m, dev[i].name));
    SECHECK(SEPUSHSTR(m, dev[i].id));
    SECHECK(SEPUSH(m, SEI2W(2)));
    SECHECK(SENEWTUPLE(m));
    SESWAP(m);
    SECHECK(SEPUSH(m, SEI2W(2)));
    SECHECK(SENEWTUPLE(m));
  }
	return MERROK;
}


int MX3registerDevice(char* name, char* id)
// Adds a device (name, id) into the device table
{
  if (!name) {
    MMechostr(MSKRUNTIME, "(!) "MSGEDEVNULLNAME"\n");
    return MERRMEM;
  }
  if (!id) {
    MMechostr(MSKRUNTIME, "(!) "MSGEDEVNULLID"\n", name);
    return MERRMEM;
  }
  if (devcnt >= kMaxDevices) {
    MMechostr(MSKRUNTIME, "(!) "MSGEDEVTABLEFULL"\n", kMaxDevices);
    return MERRMEM;
  }
  if (!(dev[devcnt].name = new char[strlen(name)+1]))
    return MERRMEM;
  strcpy(dev[devcnt].name, name);
  if (!(dev[devcnt].id   = new char[strlen(id)+1]))
    return MERRMEM;
  strcpy(dev[devcnt].id  , id);
  devcnt++;
  return MERROK;
}


int loadPackageDevice3D(mmachine m)
{
  return PKhardpak2(m, "Device3D", sizeof(defs)/sizeof(defs[0]), defs);
}
