/*
 * BRLTTY - A background process providing access to the console screen (when in
 *          text mode) for a blind person using a refreshable braille display.
 *
 * Copyright (C) 1995-2023 by The BRLTTY Developers.
 *
 * BRLTTY comes with ABSOLUTELY NO WARRANTY.
 *
 * This is free software, placed under the terms of the
 * GNU Lesser General Public License, as published by the Free Software
 * Foundation; either version 2.1 of the License, or (at your option) any
 * later version. Please see the file LICENSE-LGPL for details.
 *
 * Web Page: http://brltty.app/
 *
 * This software is maintained by Dave Mielke <dave@mielke.cc>.
 */

#include "prologue.h"

#include <string.h>

#include "log.h"
#include "cmd_utils.h"
#include "cmd_queue.h"
#include "cmd_touch.h"
#include "brl_cmds.h"
#include "brl_utils.h"
#include "report.h"
#include "bitmask.h"
#include "prefs.h"

typedef struct {
  struct {
    ReportListenerInstance *brailleWindowUpdated;
  } reportListeners;

  BITMASK(touched, 88, int);
  unsigned char cells[88];
  unsigned int count;
  unsigned int activeCells;
  unsigned int lastActive;
  int lastTouched;
} TouchCommandData;

static void
resetTouched (TouchCommandData *tcd) {
  tcd->activeCells = 0;
  tcd->lastTouched = -1;
  BITMASK_ZERO(tcd->touched);

  for (int i = 0; i < tcd->count; ++i) {
    if (tcd->cells[i]) {
      BITMASK_SET(tcd->touched, i);
      tcd->lastActive = i;
      tcd->activeCells += 1;
    }
  }
}

static void
handleTouchAt (int offset, TouchCommandData *tcd) {
  tcd->lastTouched = offset;
  BITMASK_CLEAR(tcd->touched, offset);
}

static void
handleTouchOff (TouchCommandData *tcd) {
  int ok = 0;

  if (prefs.touchNavigation && (tcd->lastTouched > ((int)tcd->lastActive - 2))) {
    BITMASK_COUNT(tcd->touched, unread);

    if (tcd->activeCells && unread == 0) {
      ok = 1;
    }

    if (!ok && tcd->activeCells && unread) {
      float factor = (float)tcd->activeCells / unread;

      if (factor > 6) ok = 1;
    }
  }

  if (ok) {
    resetTouched(tcd);
    handleCommand(BRL_CMD_NXNBWIN);
  }
}

static void
handleBrailleWindowUpdated (
  const BrailleWindowUpdatedReport *report, TouchCommandData *tcd
) {
  if (cellsHaveChanged(&tcd->cells[0], report->cells, report->count, NULL, NULL, NULL)) {
    tcd->count = report->count;

    resetTouched(tcd);
  }
}

REPORT_LISTENER(brailleWindowUpdatedListener) {
  TouchCommandData *tcd = parameters->listenerData;
  const BrailleWindowUpdatedReport *report = parameters->reportData;

  handleBrailleWindowUpdated(report, tcd);
}

static TouchCommandData *
newTouchCommandData (void) {
  TouchCommandData *tcd;

  if ((tcd = malloc(sizeof(*tcd)))) {
    memset(tcd, 0, sizeof(*tcd));

    if ((tcd->reportListeners.brailleWindowUpdated = registerReportListener(REPORT_BRAILLE_WINDOW_UPDATED, brailleWindowUpdatedListener, tcd))) {
      return tcd;
    }

    free(tcd);
  } else {
    logMallocError();
  }

  return NULL;
}

static void
destroyTouchCommandData (TouchCommandData *tcd) {
  unregisterReportListener(tcd->reportListeners.brailleWindowUpdated);
  free(tcd);
}

static int
handleTouchCommands (int command, void *data) {
  switch (command & BRL_MSK_BLK) {
    case BRL_CMD_BLK(TOUCH_AT): {
      int arg = command & BRL_MSK_ARG;

      if (arg == BRL_MSK_ARG) {
        handleTouchOff(data);
      } else {
        int at;
        if (isTextOffset(arg, &at, NULL, 0)) handleTouchAt(at, data);
      }

      break;
    }

    default:
      return 0;
  }

  return 1;
}

static void
destructTouchCommandData (void *data) {
  TouchCommandData *tcd = data;

  destroyTouchCommandData(tcd);
}

int
addTouchCommands (void) {
  TouchCommandData *tcd;

  if ((tcd = newTouchCommandData())) {
    if (pushCommandHandler("touch", KTB_CTX_DEFAULT, handleTouchCommands,
                           destructTouchCommandData, tcd)) {
      return 1;
    }

    destroyTouchCommandData(tcd);
  }

  return 0;
}
