/*ScianPick.c
  Picking system for spaces in SciAn
  Eric Pepke
  May 30, 1991
*/

#include "Scian.h"
#include "ScianTypes.h"
#include "ScianLists.h"
#include "ScianSpaces.h"
#include "ScianDraw.h"
#include "ScianIDs.h"
#include "ScianErrors.h"
#include "ScianMethods.h"
#include "ScianPick.h"
#include "ScianEvents.h"

#define MAXNPICK	200

short curPick;
short pickBuffer[MAXNPICK * 2];

ObjPtr pickObjects[MAXNPICK];

ObjPtr pickList = NULLOBJ;		/*VOLATILE list of just-picked objects*/

void StartPick()
/*Starts picking mode*/
{
#ifdef GRAPHICS
    pushmatrix();
    pick(pickBuffer, MAXNPICK);
    initnames();
    loadname(-1);
    curPick = 0;
#endif
}

void PickObject(object)
ObjPtr object;
/*Declares that object is about to be drawn for picking*/
{
#ifdef GRAPHICS
    if (curPick >= MAXNPICK - 1)
    {
	ReportError("PickObject", "Too many objects to pick");
	return;
    }
    pickObjects[curPick] = object;
    loadname(curPick);
    ++curPick;
#endif
}

void EndPickObject(object)
ObjPtr object;
/*Ends the picking for object*/
{
#ifdef GRAPHICS
    loadname(-1);
#endif
}

static void ZeroPickList()
/*Deferred routine to zero the pick list*/
{
    pickList = 0;
}

ObjPtr StopPick()
/*Stops picking mode and returns a list of objects*/
{
#ifdef GRAPHICS
    int nHits, k, c;
    ObjPtr retVal;

    pickList = NULLOBJ;

    popmatrix();
    nHits = endpick(pickBuffer);
    if (nHits < 0)
    {
	ReportError("StopPick", "Pick buffer was too small");
	nHits = -nHits;
    }

    /*Go through the hits and make a list of objects*/
    k = 0;
    while (nHits)
    {
	c = pickBuffer[k];

	++k;
	while (c)
	{
	    if (pickBuffer[k] >= 0 && pickObjects[pickBuffer[k]])
	    {
		if (!pickList)
		{
		    pickList = NewList();
		}
		PrefixList(pickList, pickObjects[pickBuffer[k]]);
		pickObjects[pickBuffer[k]] = NULLOBJ;
	    }
	    --c;
	    ++k;
	}
	--nHits;
    }
    retVal = pickList;
    ZeroPickList();
    return retVal;
#endif
}
