#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dpstring.h>
#include <dpstringlist.h>
#include "dpuser.h"
#include "dpuser2c/tools.h"
#include "dpuser_utils.h"
#include <fits.h>

#ifdef WIN
#pragma warning (disable: 4996) // disable warning for deprecated POSIX name
#endif

char *readlinebuffer;
char *bbuf;

int include_stack_ptr = 0;
extern int scriptlock;
#define MAX_INCLUDE_DEPTH 10
FILE* include_stack[MAX_INCLUDE_DEPTH];
extern int parseError;
extern char* yytext;

//#ifndef NO_READLINE
//#ifdef __cplusplus
//extern "C" {
//#endif
//char *readline(char *);
//void add_history(char *);
//extern FILE *rl_instream;
//#ifdef __cplusplus
//}
//#endif
//#endif /* !NO_READLINE */

//#ifdef NO_READLINE
//FILE *rl_instream = NULL;
//#endif /* NO_READLINE */

// tweak the input such that the parser can savely go through
/*
char *tweakInput(char *buf) {
	int i, l, p;
	char *result, *pp;
	dpString inp;

	p = 1;
	l = strlen(buf);
	for (i = 0; i < l; i++) if (buf[i] == '}') p++;
	result = (char *)malloc((l + p + 1) * sizeof(char));
	strcpy(result, buf);

// delete trailing blanks
	while ((result[l - 1] == ' ') || (result[l - 1] == '\t')) {
		l--;
		result[l] = (char)0;
	}

// Insert a ';' before each '}', if necessary
	pp = result;
	while ((pp = strchr(pp, '}')) != NULL) {
		if (pp != result) {
// is this within a string?
			dpString test;
			int i;
			for (i = 0; result + i < pp; i++) test += result[i];
			if (!(test.contains('"') % 2) && !(test.contains('\'') % 2)) {
				p = -1;
				while ((pp[p] == ' ') || (pp[p] == '\t')) p--;
				if ((pp[p] != '}') && (pp[p] != ';')) {
					for (i = l; i >= pp-result; i--) result[i + 1] = result[i];
					pp[0] = ';';
				}
			}
		}
		pp++;
		if (pp[0] == (char)0) break;
	}

// Insert a ';' at the end if necessary
	l = strlen(result);
	if ((result[l - 1] != '}') && (result[l - 1] != '{') && (result[l - 1] != ';')) {
		result[l] = ';';
		result[l + 1] = (char)0;
	}

// replace @script; by run "script";
	inp = result;
	i = 0;
	p = -1;
	while ((i = inp.find('@', i)) != -1) {
		inp.replace(i, 1, "run \"");
		p = inp.find(';', i);
		inp.replace(p, 1, "\";");
	}

	if (p != -1) {
		result = (char *)realloc(result, inp.length() * sizeof(char) + 1);
        strcpy(result, inp.c_str());
	}

// replace cd somewhere by cd "somewhere"
//  Commented out again on 07/10/2004, since this introduces a bug:
//   cd <variable> does not work anymore
// 	if (inp.left(2) == "cd") {
// 		if (inp.length() > 2) {
// 			if (inp.find("\"") == -1) {
// 				int pos;
// 				pos = inp.find(" ");
// 				if (pos != -1) {
// 					while (inp[pos].c_str() == ' ') pos++;
// 					inp = "cd \"" + inp.mid(pos, inp.length() - pos - 1) + "\";";
// 					result = (char *)realloc(result, inp.length() * sizeof(char) + 1);
// 					strcpy(result, inp.c_str());
// 				}
// 			}
// 		}
// 	}


// Insert a '\n' after each ';', if there isn't one yet
// 	p = 0;
// 	for (i = 0; i < strlen(result); i++) if (result[i] == ';') p++;
// 	result = (char *)realloc(result, strlen(result) + p + 1 * sizeof(char));
// 	pp = result;
// 	while ((pp = strchr(pp, ';')) != NULL) {
// 		if (pp != result) {
// 			p = 1;
// 			while ((pp[p] == ' ') || (pp[p] == '\t')) p++;
// 			if (pp[p] != '\n') {
// 				for (i = strlen(result); i >= pp-result; i--) result[i + 1] = result[i];
// 				pp[p] = '\n';
// 			}
// 		}
// 		pp++;
// 		if (pp[0] == (char)0) break;
// 	}

	return result;
}		
*/
int getInput(char *buf, int max_size) {
	int n, length, s;
	char *bbuf;

	if (parseError && include_stack_ptr) {
		dp_output("parse error executing script.\n");
		while (include_stack_ptr) {
			fclose(include_stack[include_stack_ptr]);
			include_stack_ptr--;
			rl_instream = include_stack[include_stack_ptr];
		}
	}
	if (ScriptInterrupt && include_stack_ptr) {
		while (include_stack_ptr) {
			fclose(include_stack[include_stack_ptr]);
			include_stack_ptr--;
			rl_instream = include_stack[include_stack_ptr];
		}
		dp_output("script aborted.\n");
	}
	if (ScriptInterrupt || parseError) script.clear();
	ScriptInterrupt = 0;
	s = 0;
	if (script.count() > 0) {
		scriptlock = 1;
		dpString line;
		s = 1;
		line = script.first();
		script.remove(script.begin());
		while (line.right(1) == "\\") {
			line.remove(line.length()-1, 1);
			line += " ";
			line += script.first();
			script.remove(script.begin());
		}
        readlinebuffer = strdup(line.c_str());

        if (!silence) {
			dp_output("%s\n", readlinebuffer);
        }
    } else if (include_stack_ptr) {
		readlinebuffer = readline("");
    } else {
		readlinebuffer = readline("DPUSER> ");
    }

	if (readlinebuffer != NULL) {
        if ((strlen(readlinebuffer) > 0) &&
            (!include_stack_ptr) &&
            (strcmp(readlinebuffer, "exit") != 0) &&
            (strcmp(readlinebuffer, "quit") != 0) &&
            (strcmp(readlinebuffer, "bye") != 0) &&
            (s == 0))
        {
            add_history(readlinebuffer);
        }
		bbuf = tweakInput(readlinebuffer);

		for (n = 0; n < (int)strlen(bbuf); n++) {
			buf[n] = bbuf[n];
		}
		buf[n++] = '\n';
		buf[n+1] = 0;
		length = n;
		free(readlinebuffer);
		free(bbuf);
	} else {
		buf[0] = 'E';
		buf[1] = 'O';
		buf[2] = 'F';
		buf[3] = '\n';
		buf[4] = 0;
		length = 4;
	}

	return length;
}
