/*
 * frame.c - NewtonScript frames implementation
 *
 * Copyright (C) 1997, George Madrid
 * All rights reserved.
 */

#include <stdlib.h>

#include "config.h"
#include "nsobj.h"
#include "nsref.h"
#include "nsrefarr.h"

/* ---------- Methods ---------- */
struct nsr_ops frame_ops = {
     NULL,			/* NEED */
     NULL,			/* NEED */
     NULL,			/* NEED */
     NULL,
     NULL,
};

/* ------------------------------------------------------------------------ */
struct nsFrmPairS {
     nsObj symbol;		/* the slot name */
     int16 index;		/* The index in the array for this slot */
};

struct nsFrmMapS {
     struct nsFrmPairS *pairs;
     int16 num_pairs;
};

struct nsFrmObjS {
     struct nsFrmMapS *map; /* the frame map */
     nsObj frm_array;		/* The array containing the objects */
};

nsObj make_naked_frame(nsRef *);
int extend_frame_map(struct nsFrmMapS *, int16);

#define get_fop(nsr)  ((struct nsFrmObjS *)(nsr + 1))

/* ------------------------------------------------------------------------ */
nsObj
make_naked_frame(nsRef *nsrp)
{
     size_t index;
     struct nsFrmObjS *fop;
     nsRef nsr;

     /* Error checking --gam */
     index = alloc_slot(sizeof(struct nsRefS) +
			sizeof(struct nsFrmObjS), &nsr);

     /* Fill in general information */
     nsr->primclass = PRIMC_FRAME;
     nsr->ops = &frame_ops;

     /* Fill in specific information */
     /* More error checking */
     fop = get_fop(nsr);
     fop->map = malloc(sizeof(struct nsFrmMapS));
     fop->map->pairs = NULL;
     fop->map->num_pairs = 0;
     fop->frm_array = make_array(0, NS_NIL);

     if (nsrp) *nsrp = nsr;
     return (index << 2) | REFERENCE_BITS;
}
   
nsObj
make_frame(struct nsFrmMapS *map, nsObj *nsos)
{
     nsObj nso;
     nsRef nsr;
     struct nsFrmObjS *fop;
     int i;
     
     /* Error checking -gam */
     nso = make_naked_frame(&nsr);
     fop = get_fop(nsr);

     /* Error checking -gam */

     extend_frame_map(fop->map, map->num_pairs);
     for (i = 0; i < map->num_pairs; i++) {
	  fop->map->pairs[i].symbol = map->pairs[i].symbol;
	  fop->map->pairs[i].index = i;

	  nso_AddArraySlot(fop->frm_array, nsos[i]);
     }

     return nso;     
}

/* ------------------------------------------------------------------------ */
int
extend_frame_map(struct nsFrmMapS *map, int16 new_len)
{
     struct nsFrmPairS *pairs;

     pairs = realloc(pairs, new_len * sizeof(struct nsFrmPairS));
     if (pairs) {
	  map->pairs = pairs;
	  map->num_pairs = new_len;
	  return(0);
     }
     return(1);
}

/* ------------------------------------------------------------------------ */
int
frame_setSlot(nsRef nsr, nsObj slot, nsObj value)
{
     
}
