/*
 *  baseio.C from ObjectProDSP
 *  Copyright (C) 1994, Mountain Math Software. All rights reserved.
 *  
 *  This file is part of ObjectProDSP, a tool for Digital Signal
 *  Processing design, development and implementation. It is free
 *  software provided you use and distribute it under the terms of
 *  version 2 of the GNU General Public License as published
 *  by the Free Software Foundation. You may NOT distribute it or
 *  works derived from it or code that it generates under ANY
 *  OTHER terms.  In particular NONE of the ObjectProDSP system is
 *  licensed for use under the GNU General Public LIBRARY License.
 *  Mountain Math Software plans to offer a commercial version of
 *  ObjectProDSP for a fee. That version will allow redistribution
 *  of generated code under standard commercial terms.
 *  
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of version 2 of the GNU General
 *  Public License along with this program. See file COPYING. If not
 *  or if you wish information on commercial versions and licensing
 *  write Mountain Math Software, P. O. Box 2124, Saratoga, CA 95070,
 *  USA, or send us e-mail at: support@mtnmath.com.
 *  
 *  You may also obtain the GNU General Public License by writing the
 *  Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
 *  USA.  However if you received a copy of this program without the
 *  file COPYING or without a copyright notice attached to all text
 *  files, librarys and executables please inform Mountain Math Software.
 *  
 *  ObjectProDSP is a trademark of Mountain Math Software.
 */
#include <strstream.h>
#include <stdio.h>
#include <stream.h>
#include <string.h>
#include <ctype.h>

#include "debug.h"
#include "grphio.h"
#include "baseio.h"

#include "usercom.h"

static void EatNewLine()
{
	char newl  ;
	char& nl = newl ;
	cin.get(nl);
	if (nl == '\04') EndOfFile();
	// else if (nl != '\n') DbgError("EatNewLine","input error"); 
}

char * GetRawBufLine(enum InputType typ)
{
	if (typ < 0) {
		if (GraphicsMode) return 0;
		typ = (InputType) -typ ;
	}
	if (!typ) typ = InputPrompt ;
	static char RawBuf[BufSize];
	for (int i = 0 ; i < BufSize;i++) RawBuf[i]= '\0' ;
	if (GraphicsMode) {
		// LogOut << "GetRawBufLine - calling GetGraphicsRawBufLine\n" ;
		strcpy(RawBuf,GetGraphicsRawBufLine(typ)) ;
		// LogMsg("GetRawBufLine:returning:",RawBuf);
		return RawBuf ;
	}
	static int FirstTime = 1 ;
	if (!FirstTime) EatNewLine();
	FirstTime = 0;
	cin.get(RawBuf,BufSize-1);
	return RawBuf ;
}

static InputType ConvertOutputToInput(OutputType out)
{
switch (out) {
case OutputNotInitialized:
case OutputEndOfOutputTypes:
case OutputUndefined: 
		DbgError("ConvertOutputToInput","bad type");
case OutputCppHelp:
case OutputHelp:
		return InputHelp ;
case OutputMenu:
		return InputMenu ;
case OutputPrompt:
		return InputPrompt ;
case OutputPlot:
		return InputPlot ;
case OutputAcknowledge:
		return InputAcknowledge ;
case OutputCppEntry:
		return InputCppEntry ;
	}
	return InputHelp ;
}


int ReturnOrQuit(enum OutputType typ)
{
	if (!typ) typ = OutputPrompt;
	if (GraphicsMode) return GraphicsReturnOrQuit(typ) ;
	cout << "Type RETURN to continue or `q' to quit:" ;
	char * Ret = GetRawBufLine((InputType) -ConvertOutputToInput(typ));
	if (Ret[0] == 'q') return 0;
	return 1;
}

void ReturnToContinue(enum OutputType typ)
{
	if (!typ) typ = OutputPrompt;
	if (GraphicsMode) {
		GraphicsReturnToContinue(typ) ;
		return ;
	}
	cout << "Type RETURN to continue:" ;
	(void) GetRawBufLine((InputType) -ConvertOutputToInput(typ));
}

NameOrNumber GetNameOrNumber(const char * InBuf)
{
	if (strlen(InBuf) > BufSize-1) DbgError("GetNameOrNumber",
		"buffer to big");
	char RawBuf[BufSize];
	strcpy(RawBuf,InBuf);
	NameOrNumber Ret ;
	Ret.Name=0;
	Ret.Number=0; 
	char Buf[BufSize];
	istrstream Temp(RawBuf,BufSize-1);
	char * Dbuf = Buf ;
	while (Temp >> Dbuf) {
		strcat(Dbuf," ");
		Dbuf+=strlen(Dbuf);
	}
	if (strlen(Buf)) 
		*(Buf+strlen(Buf)-1) = '\0' ; // delete the last blank appended
	if (isdigit(Buf[0]) ) {
		int Number ;
		sscanf(Buf,"%d",&Number);
		Ret.Number = Number ;
	} else Ret.Name = strcpy(new char[strlen(Buf)+1],Buf);
	return Ret ;
}

static const char * cnv_dec(long val)
{
	static char buf[32] ;
	sprintf(buf,"%d",val);
	return buf ;
}

const char * Dec(long V)
{
	const NumberBuffers = 10 ;
	static char Buf[NumberBuffers][32];
	// Trick to allow multiple calls in a single subroutine without
	// overwriting results of previous call.
	static int BufferIndex = 0 ;
	if (++BufferIndex >= NumberBuffers) BufferIndex = 0 ;
	return strcpy(Buf[BufferIndex],cnv_dec(V));
}


