/*ScianRecorders.c
  Eric Pepke
  Operates recorders from within scian
*/

#include "Scian.h"
#include "ScianTypes.h"
#include "ScianIDs.h"
#include "ScianScrDump.h"
#include "ScianRecorders.h"
#include "ScianWindows.h"
#include "ScianObjWindows.h"
#include "ScianScripts.h"
#include "ScianErrors.h"

int nRecorders = 0;			/*Number of recorders*/
int curRecorder = 0;			/*Current recorder*/
Bool recordEnabled = false;		/*True iff recording is enabled*/
extern double videoClock;		/*Clock for the duration of the video*/
real fps = 30.0;			/*Default is 30 fps*/
Bool recording = false;			/*True iff recording*/

ObjPtr recorders[MAXNRECORDERS];

void RegisterRecorder(recorder)
ObjPtr recorder;
/*Registers recorder recorder*/
{
    if (recorder)
    {
	recorders[nRecorders] = recorder;
	AddToReferenceList(recorders[nRecorders++]);
    }
}

extern ObjPtr NewLVR5000();
extern ObjPtr NewTQ2026F();

void InitRecorders(void)
/*Initializes the recorder system*/
{
    RegisterRecorder(NewLVR5000());
    RegisterRecorder(NewTQ2026F());
    RegisterRecorder(NewScrDump());
}

Bool SetRecorder(name)
char *name;
/*Sets the current recorder to a recorder named name*/
{
    int k;
    if (logging)
    {
	char cmd[256];
	char *s;

	sprintf(cmd, "set recorder ");
	s = &(cmd[0]);
	while (*s) ++s;
	*s++ = ' ';
	s = PrintScriptString(s, name);
	*s++ = '\n';
	*s = 0;
	Log(cmd);
    }
    for (k = 0; k < nRecorders; ++k)
    {
	ObjPtr curName;
	curName = GetStringVar("SetRecorder", recorders[k], NAME);
	if (curName)
	{
	    if (0 == strcmp2(GetString(curName), name))
	    {
		/*It's a match*/
		curRecorder = k;
		return true;
	    }
	}
    }
    return false;
}

#ifdef PROTO
Bool SetFPS(real newFPS)
#else
Bool SetFPS(newFPS)
real newFPS;
#endif
/*Sets the number of frames per second to newFPS*/
{
    fps = newFPS;
}

void KillRecorders(void)
/*Gets rid of all the recorders*/
{
    int k;
    for (k = 0; k < nRecorders; ++k)
    {
	DeleteThing(recorders[k]);
    }
    nRecorders = 0;
    return;
}

Bool PrepareToRecord(nFrames)
int nFrames;
/*Prepares to record nFrames*/
{
    int retVal;
    FuncTyp method;

    PushNonVisWindows();
    SetSystemClock(0.0);
    if (recordEnabled)
    {
	method = GetMethod(recorders[curRecorder], PREPARETORECORD);
	if (method)
	{
	    return IsTrue((*method)(recorders[curRecorder], nFrames)) ? true : false;
	}
    }
    else
    {
	return true;
    }
    return false;
}

Bool ConnectRecorder()
/*Connects to the current recorder*/
{
    int retVal;
    FuncTyp method;

    if (recordEnabled)
    {
	method = GetMethod(recorders[curRecorder], CONNECT);
	if (method)
	{
	    Bool truth;
	    truth = IsTrue((*method)(recorders[curRecorder])) ? true : false;
#ifdef IRIS
#ifdef GRAPHICS
	    if (truth)
	    {
		blanktime(0);
	    }
#endif
#endif
	    return truth;
	}
	return false;
    }
    else
    {
	printf("This is a dry run.  Status messages will be printed, but no actual recording\n");
	printf("will be done.  To record for real, rerun SciAn including the -v flag on the\n");
	printf("command line.\n");
	return true;
    }
}

Bool StopRecording()
/*Stops recording on the current recorder*/
{
    int retVal;
    FuncTyp method;

    MySetCursor(0);
    SetSystemClock(0.0);
    if (recordEnabled)
    {
	method = GetMethod(recorders[curRecorder], STOPRECORDING);
	if (method)
	{
	    return IsTrue((*method)(recorders[curRecorder])) ? true : false;
	}
    }
    else
    {
	return true;
    }
    return false;
}

#ifdef PROTO
void Delay(double time)
#else
void Delay(time)
double time;
#endif
/*Delays for time seconds*/
{
    struct tms buffer;
    long started;

    started = times(&buffer);
    do
    {
    } while (times(&buffer) - started < (long) (time * HEARTBEAT));
}

Bool SnapOneFrame()
/*Snaps a single frame shot on the current recorder*/
{
    int retVal = false;
    FuncTyp method;

    MySetCursor(-1);
    PushNonVisWindows();

    if (recordEnabled)
    {
	Delay(0.2);

	method = GetMethod(recorders[curRecorder], SNAPONEFRAME);
	if (method)
	{
	    retVal = IsTrue((*method)(recorders[curRecorder])) ? true : false;
	}
    }
    else
    {
	retVal = true;
	printf("Snap at %lg\n", videoClock);
    }
    if (retVal)
    {
	videoClock += 1.0 / fps;
    }
    return retVal;
}

void DisconnectRecorder()
/*Connects to the current recorder*/
{
    int retVal;
    FuncTyp method;

    if (recordEnabled)
    {
	method = GetMethod(recorders[curRecorder], DISCONNECT);
	if (method)
	{
	    (*method)(recorders[curRecorder]);
	}
    }
#ifdef IRIS
#ifdef GRAPHICS
    blanktime(100000);
#endif
#endif
}

