#include "app.h"
#include "nexa.h"

struct nexaData_t {
  unsigned char bitNo;
  unsigned short width;
} ;

unsigned short nexaData[LOG_SIZE];

unsigned short logCounter = 0;

//#define LOG(wd) { if(logCounter<LOG_SIZE){/*nexaData[logcounter].bitNo=x_numBits;*/ nexaData[logCounter]=wd;logCounter++;if(logCounter==LOG_SIZE)logCounter=0;}}
#define LOG(x)  {}

enum { UNKNOWN, T0, T1, T2, T3, OK, DONE };

unsigned char state = UNKNOWN;

       unsigned long x_data;
static unsigned int x_numBits;
static boolean x_2ndbit;

volatile unsigned int dbg_periodTime; // For debugging

void resetDecoder () {
	x_data = 0;
	x_numBits = 0;
	x_2ndbit = false;
	state = UNKNOWN;
}

static boolean isDone() { return state == DONE; }

static void done () { state = DONE; }

static void gotBit (char value) {

	// X
	x_numBits++;
	x_data = (x_data << 1) + (value & 0x01);
	if( x_2ndbit == false ) {
		x_2ndbit = true;
	}
	else {
		x_2ndbit = false;
		unsigned int bits = (x_data & 0x03);
		if( bits == 2 ) {
			// Bit is 1
			x_data = (x_data >> 1) | 0x00000001;
		}
		else {
			// Bit is 0
			x_data = (x_data >> 1) & 0xFFFFFFFE;
		}
	}

	state = OK;
}

// Detta är den äldre versionen med bredare siffror
static int decode (unsigned int width) {
  
        if( x_numBits == 3 ) {	// end of frame
          //state = DONE;
          //return 1;
	}
        
	switch (state) {
	case UNKNOWN: // Start of frame
		if ( 2200 <= width && width <= 3500 ) {
			state = T0;
			dbg_periodTime = width;
                        LOG(width);
		}
                else {
                  LOG(width);LOG(55555);
                  return -1;	// error, reset
                }
		break;

	case T0: // First half of pulse : HIGH around 230us

		if ( 150 <= width && width <= 300 ) {
			state = T1;
                        LOG(width);
		}
		else {
                  if( x_numBits == 0 && 2200 <= width && width <= 3500 ) {
                    LOG(44444);
                    state = T0;
                  }
                  else {
                    LOG(width);LOG(55555);
                    return -1;	// error, reset
                  }
                }
		break;

	case T1:
                if ( 200 <= width && width <= 400) {
			gotBit(0);
                        LOG(width);
		} else if ( 900 <= width && width <= 1500 ) {
			gotBit(1);
                        LOG(width);
		} else if( x_numBits == 64 ) {	// end of frame
			state = DONE;
			return 1;
		} else  {
                  LOG(width);LOG(55555);
                  return -1;	// error, reset
                }
		state = T0;
		break;
	}
	return 0;
}

#define TOO_SHORT 100

boolean nextPulseNexa (unsigned int width) {
	unsigned int decodew = 0;
  
	//static unsigned int totw = 0;
	//static int mode=0;
        
        //if( width < 100 ) LOG(width);

/*
	if( state != T0 ) {

		switch( mode ) {
		case 0:
			totw = width;
			mode = 1;
			break;
		case 1:
			if( width < TOO_SHORT ) {
				totw += width;
				mode = 2;
			}
			else {
				decodew = totw;
				totw = width;
			}
			break;
		case 2:
			totw += width;
			//if( width < TOO_SHORT ) {  // This change caused less reception
			//	mode = 2;
			//}
			//else {
				mode = 1;
			//}
			break;
		}
	}
	else {
		// T0-State, send right through
		decodew = totw;
		totw = width;
		if( width < TOO_SHORT ) {
			mode = 2;
		}
		else {
			mode = 1;
		}
	}*/
decodew = width;
	if( decodew > 0 ) {
		if (state != DONE)

			switch (decode(decodew)) {
			case -1:
				resetDecoder();
				break;
			case 1:  done();  break;
		}
	}
	return isDone();
}

