//this function is a state machine that processes the tweet search json one byte at a time. It works ont he global searchParser structure
//it looks for a tag, and then grabs the tag value into a buffer.
//does OK with escape, removes XMLentities from the text completely, this could be improved.
unsigned char tagSearch(unsigned char inBuf, struct _jsonParser *P ){

#define SEARCHING_FOR_TAG 	0
#define GRABBING_TAG		1

	switch(P->foundTag){
		case SEARCHING_FOR_TAG://search for tag
			//compare current byte to next byte in tag
			//if no match, need to check one more time to see if the beginning of a new sequence
			if( (P->tagCharMatchCnt==0) || (inBuf!=P->searchTag[P->tagCharMatchCnt]) ){
				P->tagCharMatchCnt=0; //no match, reset
				if(inBuf!=P->searchTag[0]) break; //no match, break
			}
			P->tagCharMatchCnt++; //match, increment counter
			if(P->tagCharMatchCnt==P->searchTagLength){//whole tag matches
				P->tagCharMatchCnt=0; //reset the match counter
				P->foundTag=GRABBING_TAG;
				P->xmlencode=0;
				P->escape=0;
				P->UTF=0;	
				P->valueBufferCounter=0;
			}
			break;
		case GRABBING_TAG://tag found, get value

			//discard UTF characters, could decode and do a few umlouts and other international characters the LCD can display
			if(P->UTF>0){//ignore UTF8 characters (LCD can't display, PIC char can't handle)
				P->UTF--;
				break;
			}

			if(P->xmlencode==1){ //already saw &, suck down the code
				if(inBuf==';'){//; is end of code, process and clean up
					P->xmlencode=0; //done grabbing encoded character
					inBuf=XMLdecode(P->xmlenchar[0], P->xmlenchar[1]); //decode it, reuse inBuf character
					if(inBuf!=0){//if 0, error, just skip it, else add to valueBuffer
						addValueByte(inBuf, P);//add character to the value buffer
 					}
					break; 
				}else{ //if not end of xmlencode, get another character
					if(P->xmlencharcnt<2){ //we only need the first 2 character to identify the ecoding
						P->xmlenchar[P->xmlencharcnt]=inBuf;
					}	
					
					P->xmlencharcnt++;
					if(P->xmlencharcnt>5){//quit if it goes over the max of 5 characters
						P->xmlencode=0; //quit encoding, there was an error, resume normal on next character
					}

					break;	//don't save byte
				}
			}

			if(P->escape==1){  //ESCAPED, check for /\" and UTF8
				P->escape=0; //clear escape
				if(inBuf=='u' || inBuf=='U'){//only escape /\", add a \ back to buffer otherwise
					P->UTF=4;	//next 4 bytes are UFT encoded characters, ignore
					break;
				}else if(inBuf=='n' || inBuf=='N'){ //\n is line break, ignore....
					break;
				}
			}else{ //NOT ESCAPED, check for end and escape
				if(inBuf==P->valueEndChar){ //end on value end character
					P->foundTag=SEARCHING_FOR_TAG;
					return 1; //tag complete
					//break;
				}else if(inBuf==0x5c){ //if this is escape char and escape not set, then set escape and break  (0x5c= '\')
					P->escape=1;	
					break;
				}else if(inBuf=='&'){ //begin XML encoded character
					P->xmlencode=1; //set flag
					P->xmlencharcnt=0; //clear encoded character counter
					break; //don't save this character
				}
			}
			
			if(inBuf>=0x20 && inBuf<=0x7e){//only allow standard ASCII characters, otherwise ignore
				addValueByte(inBuf, P);//add character to the value buffer
			}
			break;
	}
	return 0; //tag not complete
//this function is a state machine that processes the tweet search json one byte at a time. It works ont he global searchParser structure
//it looks for a tag, and then grabs the tag value into a buffer.
//does OK with escape, removes XMLentities from the text completely, this could be improved.
void procSearch(unsigned char inBuf){
	switch(searchParser.foundTag){
		case 0://search for tag
			//compare current byte to next byte in tag
			//if no match, need to check one more time to see if the beginning of a new sequence
			if( (searchParser.tagCharMatchCnt==0) || (inBuf!=jsonSearchTag[searchParser.tagCharMatchCnt]) ){
				searchParser.tagCharMatchCnt=0; //no match, reset
				#if defined(__18CXX)//there's something about the C18 compiler that wants this or the next instruction is always false..
				Nop();
				#endif
				if(inBuf!=jsonSearchTag[0]) break; //no match, break
			}
			searchParser.tagCharMatchCnt++; //match, increment counter
			if(searchParser.tagCharMatchCnt==(sizeof(jsonSearchTag)-1)){//whole tag matches
				searchParser.tagCharMatchCnt=0; //reset the match counter
				searchParser.tagTotalCnt++; //increment the total tag counter
				searchParser.foundTag=1;
				searchParser.xmlencode=0;
				searchParser.escape=0;
				searchParser.UTF=0;	
				addToSearchBuffer(' ');
			}
			break;
		case 1://tag found, get value

			//discard UTF characters, could decode and do a few umlouts and other international characters the LCD can display
			if(searchParser.UTF>0){//ignore UTF8 characters (LCD can't display, PIC char can't handle)
				searchParser.UTF--;
				break;
			}

			if(searchParser.xmlencode==1){ //already saw &, suck down the code
				if(inBuf==';'){//; is end of code, process and clean up
					searchParser.xmlencode=0; //done grabbing encoded character
					inBuf=XMLdecode(searchParser.xmlenchar[0], searchParser.xmlenchar[1]); //decode it, reuse inBuf character
					if(inBuf!=0) addToSearchBuffer(inBuf); //if 0, error, just skip it, else add to searchBuffer
					break; 
				}else{ //if not end of xmlencode, get another character
					if(searchParser.xmlencharcnt<2){ //we only need the first 2 character to identify the ecoding
						searchParser.xmlenchar[searchParser.xmlencharcnt]=inBuf;
					}	
					
					searchParser.xmlencharcnt++;
					if(searchParser.xmlencharcnt>5){//quit if it goes over the max of 5 characters
						searchParser.xmlencode=0; //quit encoding, there was an error, resume normal on next character
					}

					break;	//don't save byte
				}
			}

			if(searchParser.escape==1){  //ESCAPED, check for /\" and UTF8
				searchParser.escape=0; //clear escape
				if(inBuf=='u' || inBuf=='U'){//only escape /\", add a \ back to buffer otherwise
					searchParser.UTF=4;	//next 4 bytes are UFT encoded characters, ignore
					break;
				}else if(inBuf=='n' || inBuf=='N'){ //\n is line break, ignore....
					break;
				}
				//don't need this, escape character is always escaped
				//else if(!(inBuf=='/' || inBuf==0x5c || inBuf=='"')){//only escape /\", add a \ back to buffer otherwise
				//	addToSearchBuffer('|'); //continue as normal, add current byte to searchbuffer at the end...
				//}
			}else{ //NOT ESCAPED, check for end and escape
				if(inBuf=='"'){ //end on " if not escaped
					//add block between entries
					addToSearchBuffer(' ');				
					addToSearchBuffer(0xff);
					searchParser.foundTag=0;
					break;
				}else if(inBuf==0x5c){ //if this is escape char and escape not set, then set escape and break  (0x5c= '\')
					searchParser.escape=1;	
					break;
				}else if(inBuf=='&'){ //begin XML encoded character
					searchParser.xmlencode=1; //set flag
					searchParser.xmlencharcnt=0; //clear encoded character counter
					break; //don't save this character
				}
			}
			
			if(inBuf>=0x20 && inBuf<=0x7e){//only allow standard ASCII characters, otherwise ignore
				if(inBuf==0x5c) inBuf='|'; //LCD has no '\', use |
				if(inBuf=='~') inBuf='-'; //LCD has no "~", use - 
				addToSearchBuffer(inBuf);	//add character to output buffer
			}
			break;
	}
}