/*****************************************************************************
*   "Irit" - the 3d (not only polygonal) solid modeller.		     *
*									     *
* Written by:  Gershon Elber				Ver 0.2, Mar. 1990   *
******************************************************************************
* Module to handle the windows used by the solid modeller.		     *
*****************************************************************************/

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "program.h"
#include "irit_soc.h"
#include "iritprsr.h"
#include "windows.h"

#define IRIT_PROMPT	"Irit> "

/*****************************************************************************
*  Routine to toggle the input window log file printing. If turned on, test  *
* is made if file has been opened and if not open it.			     *
*****************************************************************************/
void WndwLogPrint(RealType *Set)
{
    char s[LINE_LEN];

    if (APX_EQ(*Set, 0.0)) {
	GlblPrintLogFile = FALSE;
	fflush(GlblLogFile);
	return;
    }

    if (GlblLogFile == NULL) {		      /* Not open yet - open it now: */
	if ((GlblLogFile = fopen(GlblLogFileName, "w")) == NULL) {
	    sprintf(s, "Failed to open log file \"%s\"", GlblLogFileName);
	    WndwInputWindowPutStr(s);
	    return;
	}
	GlblPrintLogFile = TRUE;
    }
}

/*****************************************************************************
*  Routine to wait for user keystroke while drawing blinking cursor:	     *
* No data is returned - used as pause only.				     *
*****************************************************************************/
void WndwPause(RealType *R)
{
#ifdef DJGCC
    if (!APX_EQ(*R, 0.0))
	while (kbhit())
	    getkey();					     /* Flush stdin. */
    WndwInputWindowPutStr("Type return to continue:");
    getkey();
#else
    fprintf(stderr, "Type return to continue:");
    fflush(stderr);

    getchar();
#endif /* DJGCC */
}

/*****************************************************************************
*  Routine to handle the text on the Input Window. This window echoes all    *
* the input steam - the input parser input. Errors or information is also    *
* displayed in this window.						     *
*****************************************************************************/
void WndwInputWindowPutStr(char *Msg)
{
    char str[INPUT_LINE_LEN];
    int i;

    for (i = 0; *Msg != 0; Msg++) {
	if (*Msg == 0x09)
	    do {
		str[i++] = ' ';
	    }
	    while (i % 8 != 0);
#ifdef AMIGA
	else if (abs(*Msg) < ' ' || (abs(*Msg) > '~' && abs(*Msg) <0xA0))
#else
	else if (*Msg < ' ' || *Msg > '~')
#endif
	    break;
	else
	    str[i++] = *Msg;
    }
    str[i] = 0;

    if (GlblPrintLogFile)
	fprintf(GlblLogFile, "%s\n", str);

#ifdef DJGCC
    if (GlblDoGraphics) {
	IntrPrintf(InputWindowID, TRUE, str);
    }
    else {
	printf("%s\n", str);
	fflush(stdout);
    }
#else
    printf("%s\n", str);
    fflush(stdout);
#endif /* DJGCC */
}

/*****************************************************************************
*  Routine to handle reading one line from stdin into string Str, with max.  *
* length Length in the Input Window.					     *
*  Note Str may be non empty and can be used to fix wrong entry.	     *
*****************************************************************************/
void WndwInputWindowGetStr(char *Str, int Length)
{
#ifdef DJGCC
    if (GlblDoGraphics) {
	Str[0] = 0;
    	IntrGetLineWindow(InputWindowID, Str, Length);
    }
    else {
	printf(IRIT_PROMPT);
	fgets(Str, Length - 1, stdin);
	if (feof(stdin))
	    IritExit(0);	   /* Eof typed on keyboard (usually CtrlD). */
	if (Str[strlen(Str) - 1] < ' ')
	    Str[strlen(Str) - 1] = 0;				/* No CR/LF. */
	puts(Str);
	fflush(stdout);
    } 
#else
    printf(IRIT_PROMPT);
    fgets(Str, Length - 1, stdin);
    if (feof(stdin))
	IritExit(0);		   /* Eof typed on keyboard (usually CtrlD). */
    if (Str[strlen(Str) - 1] < ' ') 
	Str[strlen(Str) - 1] = 0;				/* No CR/LF. */
    puts(Str);
    fflush(stdout);
#endif /* DJGCC */
}

/*****************************************************************************
*  Display one object.							     *
*****************************************************************************/
void WndwViewObject(IPObjectStruct *PObj)
{
    if (!GlblDoGraphics)
	return;

    if (IP_IS_STR_OBJ(PObj)) {
	if (!SocServerActive())
	    return;

	SocServerWriteOneObject(PObj);

	if (strcmp(PObj -> Name, "COMMAND_") == 0 &&
	    (strcmp(PObj -> U.Str, "EXIT") == 0 ||
	     strcmp(PObj -> U.Str, "DISCONNECT") == 0))
	    SocServerCloseSocket();
    }
    else
	SocServerWriteOneObject(PObj);
}

/*****************************************************************************
*  Clear the display device.						     *
*****************************************************************************/
void WndwViewClearScreen(void)
{
    IPObjectStruct
	*PObj = IPAllocObject("COMMAND_", IP_OBJ_STRING, NULL);

    strcpy(PObj -> U.Str, "CLEAR");
    WndwViewObject(PObj);
    IPFreeObject(PObj);
}

/*****************************************************************************
*  Clear the display device.						     *
*****************************************************************************/
void WndwViewSaveMatrix(char *FileName)
{
    IPObjectStruct
	*PObj = IPAllocObject("COMMAND_", IP_OBJ_STRING, NULL);

    sprintf(PObj -> U.Str, "MSAVE %s", FileName);
    WndwViewObject(PObj);
    IPFreeObject(PObj);
}

/*****************************************************************************
*  Disconnect from the display device.					     *
*****************************************************************************/
void WndwViewDisconnect(void)
{
    IPObjectStruct
	*PObj = IPAllocObject("COMMAND_", IP_OBJ_STRING, NULL);

    strcpy(PObj -> U.Str, "DISCONNECT");
    WndwViewObject(PObj);
    IPFreeObject(PObj);
}

/*****************************************************************************
*  Force the display device to quit.					     *
*****************************************************************************/
void WndwViewExit(void)
{
    IPObjectStruct
	*PObj = IPAllocObject("COMMAND_", IP_OBJ_STRING, NULL);

    /* The second exit should fail on write closing the connection locally. */
    strcpy(PObj -> U.Str, "EXIT");
    WndwViewObject(PObj);

    IPFreeObject(PObj);

}
