/******************************************************************************
* Cagd_Wrt.c - Generic Curve/Surface writing to files.			      *
*******************************************************************************
* Written by Gershon Elber, July. 90.					      *
******************************************************************************/

#ifdef USE_VARARGS
#    include <varargs.h>
#else
#    include <stdarg.h>
#endif /* USE_VARARGS */

#include <string.h>
#include "cagd_loc.h"
#include "irit_soc.h"

static int
    GlblWriteSocket = FALSE;		       /* If TRUE - write to socket. */
static CagdPrintfFuncType
    RedirCagdPrintfFunc = NULL;

/*****************************************************************************
* Same as fprintf but with indentation.					     *
*****************************************************************************/
void CagdSetCagdFprintf(CagdPrintfFuncType Func)
{
    RedirCagdPrintfFunc = Func;
}

/*****************************************************************************
* Same as fprintf but with indentation.					     *
*****************************************************************************/
#ifdef USE_VARARGS
void _CagdFprintf(FILE *f, int Indent, char *va_alist, ...)
{
    static char AccumLine[LINE_LEN_LONG];
    char *p, *Format, Line[LINE_LEN_LONG];
    int i;
    va_list ArgPtr;

    va_start(ArgPtr);
    Format = va_arg(ArgPtr, char *);
#else
void _CagdFprintf(FILE *f, int Indent, char *Format, ...)
{
    static char AccumLine[LINE_LEN_LONG];
    char *p, Line[LINE_LEN_LONG];
    int i;
    va_list ArgPtr;

    va_start(ArgPtr, Format);
#endif /* USE_VARARGS */

    vsprintf(Line, Format, ArgPtr);
    va_end(ArgPtr);

    if (GlblWriteSocket) {
	/* No need for intentation if writing to a socket. */
	SocServerWriteLine(Line, strlen(Line));
    }
    else if (RedirCagdPrintfFunc && f == NULL) {
	for (i = 0, p = &AccumLine[strlen(AccumLine)]; i < Indent; i++)
	    *p++ = ' ';
	*p = 0;

	if ((p = strchr(Line, '\n')) != NULL ||
	    (p = strchr(Line, '\r')) != NULL)
	    *p = 0;
	strcat(AccumLine, Line);
	if (p != NULL) {
	    RedirCagdPrintfFunc(AccumLine);
	    AccumLine[0] = 0;
	}
    }
    else {
	for ( ; Indent >= 8; Indent -= 8)
	    fputc('\t', f);
	while (Indent--)
	    fputc(' ', f);
	fputs(Line, f);
    }
}

/*****************************************************************************
* Generic routine to write curve(s) to the given file.			     *
( If Comment is NULL, no comment is printed, if "" only internal coment.     *
*****************************************************************************/
int CagdCrvWriteToFile2(CagdCrvStruct *Crvs, FILE *f, int Indent, char *Comment,
								char **ErrStr)
{
    int RetVal = TRUE;
    CagdCrvStruct *NextCrv;

    for (; Crvs != NULL && RetVal; Crvs = Crvs -> Pnext) {
	NextCrv = Crvs -> Pnext;      /* To make sure we dump one at a time. */
	Crvs -> Pnext = NULL;

	switch(Crvs -> GType) {
	    case CAGD_CBEZIER_TYPE:
		RetVal = BzrCrvWriteToFile2(Crvs, f, Indent, Comment, ErrStr);
		break;
	    case CAGD_CBSPLINE_TYPE:
		RetVal = BspCrvWriteToFile2(Crvs, f, Indent, Comment, ErrStr);
		break;
	    case CAGD_CPOWER_TYPE:
		FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
		return FALSE;
	    default:
		FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
		return FALSE;
	}

	Crvs -> Pnext = NextCrv;
    }

    return RetVal;
}

/*****************************************************************************
* Generic routine to write surface(s) to the given file.		     *
( If Comment is NULL, no comment is printed, if "" only internal coment.     *
*****************************************************************************/
int CagdSrfWriteToFile2(CagdSrfStruct *Srfs, FILE *f, int Indent, char *Comment,
								char **ErrStr)
{
    int RetVal = TRUE;
    CagdSrfStruct *NextSrf;

    for (; Srfs != NULL && RetVal; Srfs = Srfs -> Pnext) {
	NextSrf = Srfs -> Pnext;      /* To make sure we dump one at a time. */
	Srfs -> Pnext = NULL;

	switch (Srfs -> GType) {
	    case CAGD_SBEZIER_TYPE:
		RetVal = BzrSrfWriteToFile2(Srfs, f, Indent, Comment, ErrStr);
		break;
	    case CAGD_SBSPLINE_TYPE:
		RetVal = BspSrfWriteToFile2(Srfs, f, Indent, Comment, ErrStr);
		break;
	    case CAGD_SPOWER_TYPE:
		FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
		return FALSE;
	    default:
		FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
		return FALSE;
	}

	Srfs -> Pnext = NextSrf;
    }

    return RetVal;
}

/*****************************************************************************
* Generic routine to write curve(s) to the given file.			     *
( If Comment is NULL, no comment is printed, if "" only internal coment.     *
*****************************************************************************/
int CagdCrvWriteToFile(CagdCrvStruct *Crvs, char *FileName, int Indent,
						 char *Comment, char **ErrStr)
{
    int RetVal = TRUE;
    CagdCrvStruct *NextCrv;

    for (; Crvs != NULL && RetVal; Crvs = Crvs -> Pnext) {
	NextCrv = Crvs -> Pnext;      /* To make sure we dump one at a time. */
	Crvs -> Pnext = NULL;

	switch(Crvs -> GType) {
	    case CAGD_CBEZIER_TYPE:
		RetVal = BzrCrvWriteToFile(Crvs, FileName, Indent, Comment, ErrStr);
		break;
	    case CAGD_CBSPLINE_TYPE:
		RetVal = BspCrvWriteToFile(Crvs, FileName, Indent, Comment, ErrStr);
		break;
	    case CAGD_CPOWER_TYPE:
		FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
	    default:
		FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
		return FALSE;
	}

	Crvs -> Pnext = NextCrv;
    }

    return RetVal;
}

/*****************************************************************************
* Generic routine to write surface(s) to the given file.		     *
( If Comment is NULL, no comment is printed, if "" only internal coment.     *
*****************************************************************************/
int CagdSrfWriteToFile(CagdSrfStruct *Srfs, char *FileName, int Indent,
						 char *Comment, char **ErrStr)
{
    int RetVal = TRUE;
    CagdSrfStruct *NextSrf;

    for (; Srfs != NULL && RetVal; Srfs = Srfs -> Pnext) {
	NextSrf = Srfs -> Pnext;      /* To make sure we dump one at a time. */
	Srfs -> Pnext = NULL;

	switch (Srfs -> GType) {
	    case CAGD_SBEZIER_TYPE:
		RetVal = BzrSrfWriteToFile(Srfs, FileName, Indent, Comment, ErrStr);
		break;
	    case CAGD_SBSPLINE_TYPE:
		RetVal = BspSrfWriteToFile(Srfs, FileName, Indent, Comment, ErrStr);
		break;
	    case CAGD_SPOWER_TYPE:
		FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
		return FALSE;
	    default:
		FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
		return FALSE;
	}

	Srfs -> Pnext = NextSrf;
    }

    return RetVal;
}

/*****************************************************************************
*   Routine to request writing to a socket (if non zero) instead of a file.  *
*****************************************************************************/
void CagdWriteSocket(int WriteSocket)
{
    GlblWriteSocket = WriteSocket;
}
