#include "Arduino.h"
#include "InputLine.h"

InputLine::InputLine() { 
	echo=true;
	charsReady=0;
	buff[0]=0;
	atChar=0;
	dropLine=true;
	ready=false;
}
void InputLine::Update() {	// {{{ call often (read Serial); when isReady return true, starts new line
	if (dropLine) drop();
	if (ready) return;
	if (charsReady > INPUTLINE_LENGTH) {	// {{{ should not happen
		charsReady=INPUTLINE_LENGTH;
		buff[charsReady]=0;
		atChar=0;
		ready=true;
		return;
	};	// }}}
	while ( Serial.available() ) {
		char c=Serial.read();
		if (echo) Serial.print(c);
		if (c == '\r' || c == '\n' ) {ready=true; break;};
		if (c==127) { // BackSpace
			if (charsReady>0) {
				if (echo) Serial.print(F(ANSI_back));
				charsReady--;
				buff[charsReady]=0;
			};
		} else {
			buff[charsReady++]=c;
			buff[charsReady]=0;
			if (charsReady == INPUTLINE_LENGTH) {ready=true; break;};
		};
	};
	if (atChar>charsReady) atChar=charsReady;
}	// }}}
bool InputLine::isReady() {	// {{{ after enter (or full buffer); if true, next Update reset line
	if (ready) dropLine=true;
	return ready;
}	// }}}
char InputLine::nextChar() {	// {{{	return next unreaded char or \0 at EOL
	if (charsReady > INPUTLINE_LENGTH) {
		charsReady=INPUTLINE_LENGTH;
		buff[charsReady]=0;
	};
	if (atChar >= charsReady) {
		atChar = charsReady;
		return '\0';
	} else {
		return buff[atChar++];
	};
}	// }}}
char InputLine::peekChar() {	// {{{	return next unreaded char or \0 at EOL, no move
	if (charsReady > INPUTLINE_LENGTH) {
		charsReady=INPUTLINE_LENGTH;
		buff[charsReady]=0;
	};
	if (atChar >= charsReady) {
		atChar = charsReady;
		return '\0';
	} else {
		return buff[atChar];
	};
}	// }}}
void InputLine::drop() {	// {{{ drops line, start new one
	atChar=0;
	charsReady=0;
	buff[charsReady]=0;
	dropLine=false;
	ready=false;
}	// }}}
bool InputLine::get_uint8_t(uint8_t &val) {	// {{{	read uint8_t, success if at least 1 number and no number left
	if (charsReady > INPUTLINE_LENGTH) {
		charsReady=INPUTLINE_LENGTH;
		buff[charsReady]=0;
	};
	if (atChar >= charsReady) {
		atChar = charsReady;
		return false;
	};
	char c=buff[atChar];
	uint16_t x=0;
	if (c<'0' || c>'9') return false;
	while (c>='0' && c<='9' && x<0x100) {
		x=10*x+(c-'0');
		c=buff[++atChar];
	};
	if ((c<'0' || c>'9') && x<0x100 ) { 
		val = x;
		return true;
	};
	return false;
}	// }}}
