/* utils.c */
#include "os.h"
#include "copyright.h"
#include "interface.h"
#include "externs.h"
#include "db.h"

dbref find_entrance (dbref door)
{
  dbref room;
  dbref thing;
  for (room = 0; room < db_top; room++)
    if (Typeof (room) == TYPE_ROOM) {
      thing = db[room].exits;
      while (thing != NOTHING) {
        if (thing == door)
          return room;
        thing = db[thing].next;
      }
    }
  return NOTHING;
}

/* remove the first occurence of what in list headed by first */
dbref remove_first (dbref first, dbref what)
{
  dbref prev;
  /* special case if it's the first one */
  if (first == what) {
    return db[first].next;
  } else {
    /* have to find it */
    DOLIST (prev, first) {
      if (db[prev].next == what) {
        db[prev].next = db[what].next;
        return first;
      }
    }
    return first;
  }
}

int member (dbref thing, dbref list)
{
  DOLIST (list, list) {
    if (list == thing)
      return 1;
  }

  return 0;
}

int recursive_member (dbref disallow, dbref from, int count)
{
  dbref contents = db[from].contents;

  if (count > 50)
    return 0;
  DOLIST (contents, contents) {
    count++;
    return ((from == disallow) ||
      (contents == disallow) || recursive_member (disallow, contents, count));
  }
  return 0;
}

dbref reverse (dbref list)
{
  dbref newlist;
  dbref rest;
  newlist = NOTHING;
  while (list != NOTHING) {
    rest = db[list].next;
    PUSH (list, newlist);
    list = rest;
  }
  return newlist;
}

/* takes a dbref and returns a pointer to the head of a dblist */
struct dblist *listcreate (dbref ref)
{
  struct dblist *ptr;

  ptr = (struct dblist *) malloc ((unsigned) sizeof (struct dblist));
  if (!ptr)
    panic ("Out of memory.");
  ptr->obj = ref;
  ptr->next = NULL;
  return (ptr);
}

/*
 * takes a pointer to a dblist and a dbref and adds the dbref to the
 * end of the list.
 */
void listadd (struct dblist *head, dbref ref)
{
  struct dblist *ptr = head;


  while (ptr->next)
    ptr = ptr->next;

  ptr->next = listcreate (ref);
}

/* takes a pointer to a dblist and recursively frees it */
void listfree (struct dblist *head)
{
  struct dblist *ptra = head, *ptrb;

  while (ptra->next) {
    ptrb = ptra->next;
    free (ptra);
    ptra = ptrb;
  }
}

static int my_random (int x)
{
  int result;
  result = (int) (((float) x * (float) OS_RAND ()) / 2147477000.0);
  return result;
}

int getrandom (int x)
{
  int temprandoms[20];
  int i;
  if (x < 1)
    x = 1;
  for (i = 0; i < 20; i++)
    temprandoms[i] = my_random (x);
  i = my_random (20);

  return temprandoms[i];
}