
// SPDX-License-Identifier: CC-BY-NC-SA-4.0
//
// Copyright (C) 2026 Bit by Bit Signal Processing LLC (https://bxbsp.com)
//
// This work is placed under the "Creative Commons Attribution
// NonCommercial ShareAlike 4.0 International" license, known
// by the shortened acronym "CC-BY-NC-SA-4.0".
//
// This work 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.
//
// A CC-BY-NC-SA-4.0 license allows you to use this work for
// noncommercial purposes so long as attribution is made to the
// original author.  Modified versions of this work may be distributed,
// but only under the same license.  For further details, see the
// Creative Commons License "CC-BY-NC-SA-4.0".
//
// You should have received a copy of the CC-BY-NC-SA-4.0 license
// along with this work. If not, see
// <https://creativecommons.org/licenses/by-nc-sa/4.0/>.
//

#include "touch_state.hh"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

touch_state::touch_state()
{
  current_slot  =  0;
  num_touches   =  0;
  debug         =  true;
  syn_dropped   = false;
}


bool touch_state::handle_touch_event(input_event& ie)
{
  if(ie.type==EV_SYN && ie.code==SYN_REPORT)
    {
      if(syn_dropped)
	{
	  syn_dropped = false;
	  return false;
	}
      return true;
    }

  if(ie.type==EV_SYN && ie.code==SYN_DROPPED)
    {
      printf("LOST SYNC.  NEED TO RECOVER VIA EVIOCG* ioctls.  Not coded yet.\n");
      fflush(stdout);
      sleep(1);
      exit(20);
      syn_dropped = true;
      return false;
    }

  if(ie.type!=EV_ABS)
    return false;
  
  if(ie.code == ABS_MT_SLOT)
    {
      current_slot = ie.value;
    }
  else if(ie.code == ABS_MT_TRACKING_ID)
    {
      if(ie.value==-1 && slot[current_slot].x_valid && slot[current_slot].y_valid )
	{
	  num_touches--;
	}
      slot[current_slot].tracking_id  = ie.value;
      slot[current_slot].x_valid      = false;
      slot[current_slot].y_valid      = false;
    }
  else if(ie.code == ABS_MT_POSITION_X)
    {
      if(slot[current_slot].y_valid && !slot[current_slot].x_valid)
	num_touches++;

      slot[current_slot].x       = ie.value;
      slot[current_slot].x_valid = true;
    }
  else if(ie.code == ABS_MT_POSITION_Y)
    {
      if(slot[current_slot].x_valid && !slot[current_slot].y_valid)
	num_touches++;

      slot[current_slot].y       = ie.value;
      slot[current_slot].y_valid = true;
    }

  return false;
}


void touch_state::print_touch_state()
{
  printf("TOUCH STATE:  %d touches", num_touches);

  if(num_touches==0)
    {
      printf(".\n");
    }
  else
    {
      printf(" at positions");
      for(int i=0; i<TOUCH_STATE_MAX_SLOTS; i++)
	{
	  bool x_valid = slot[i].x_valid;
	  bool y_valid = slot[i].y_valid;

	  if(x_valid && y_valid)
	    {
	      int x        = slot[i].x;
	      int y        = slot[i].y;
	      printf(" (%d,%d)", x, y);
	    }
	}
      printf("\n");
    }
}
