/*
 * 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"

/* Source file for range list management module */
/* For a description of what each function does, see rangelist.h */

#include <stdio.h>

#include "brlapi_keyranges.h"
#include "log.h"

static int inKeyrange(KeyrangeList *l, KeyrangeElem e)
{
  uint32_t flags = KeyrangeFlags(e);
  uint32_t val = KeyrangeVal(e);
  return (l->minVal <= val && val <= l->maxVal && (flags | l->minFlags) == flags && ((flags & ~l->maxFlags) == 0));
}

/* Function : createKeyrange */
static KeyrangeList **createKeyrange(KeyrangeList **p, uint32_t minFlags, uint32_t minVal, uint32_t maxFlags, uint32_t maxVal, KeyrangeList *n)
{
  KeyrangeList *c = malloc(sizeof(KeyrangeList));
  if (c==NULL) return NULL;
  c->minFlags = minFlags; c->minVal = minVal;
  c->maxFlags = maxFlags; c->maxVal = maxVal;
  c->next = n;
  *p = c;
  return &c->next;
}

/* Function : freeKeyrange */
static void freeKeyrange(KeyrangeList **p, KeyrangeList *c)
{
  if (c==NULL) return;
  *p = c->next;
  free(c);
}

/* Function : freeKeyrangeList */
void freeKeyrangeList(KeyrangeList **l)
{
  KeyrangeList *p1, *p2;
  if (l==NULL) return;
  p2 = *l;
  while (p2!=NULL) {
    p1 = p2;
    p2 = p1->next;
    free(p1);
  }
  *l = NULL;
}

/* Function : inKeyrangeList */
KeyrangeList *inKeyrangeList(KeyrangeList *l, KeyrangeElem n)
{
  KeyrangeList *c = l;
  while (c!=NULL) {
    if (inKeyrange(c, n)) return c;
    c = c->next;
  }
  return NULL;
}

/* Function : DisplayKeyrangeList */
void DisplayKeyrangeList(KeyrangeList *l)
{
  if (l==NULL) printf("emptyset");
  else {
    KeyrangeList *c = l;
    while (1) {
      printf("[%lx(%lx)..%lx(%lx)]",(unsigned long)c->minVal,(unsigned long)c->minFlags,(unsigned long)c->maxVal,(unsigned long)c->maxFlags);
      if (c->next==NULL) break;
      printf(",");
      c = c->next;
    }
  }
  printf("\n");
}

/* Function : addKeyrange */
int addKeyrange(KeyrangeElem x0, KeyrangeElem y0, KeyrangeList **l)
{
  KeyrangeList *c;
  uint32_t minFlags = KeyrangeFlags(x0) & KeyrangeFlags(y0);
  uint32_t maxFlags = KeyrangeFlags(x0) | KeyrangeFlags(y0);
  uint32_t minVal   = MIN(KeyrangeVal(x0), KeyrangeVal(y0));
  uint32_t maxVal   = MAX(KeyrangeVal(x0), KeyrangeVal(y0));
  KeyrangeElem min = KeyrangeElem(minFlags, minVal);
  KeyrangeElem max = KeyrangeElem(maxFlags, maxVal);

  logMessage(LOG_CATEGORY(SERVER_EVENTS) | LOG_DEBUG,
    "adding range [%"PRIx32"(%"PRIx32")..%"PRIx32"(%"PRIx32")]",
    minVal, minFlags, maxVal, maxFlags
  );

  c = *l;
  while (c) {
    if (inKeyrange(c, min) && inKeyrange(c, max))
      /* Falls completely within an existing range */
      return 0;

    if (c->minVal <= maxVal && maxVal <= c->maxVal && minFlags == c->minFlags && maxFlags == c->maxFlags) {
      /* May just change lower bound */
      /* Note that minVal can't be >= c->minVal */
      c->minVal = minVal;
      return 0;
    }

    if (c->minVal <= minVal && minVal <= c->maxVal && minFlags == c->minFlags && maxFlags == c->maxFlags) {
      /* May just change upper bound */
      /* Note that maxVal can't be <= c->maxVal */
      c->maxVal = maxVal;
      return 0;
    }

    c = c->next;
  }

  /* Else things are not easy, just add */
  if ((createKeyrange(l,minFlags,minVal,maxFlags,maxVal,*l)) == NULL) return -1;
  return 0;
}

int removeKeyrange(KeyrangeElem x0, KeyrangeElem y0, KeyrangeList **l)
{
  uint32_t minFlags = KeyrangeFlags(x0) & KeyrangeFlags(y0);
  uint32_t maxFlags = KeyrangeFlags(x0) | KeyrangeFlags(y0);
  uint32_t minVal   = MIN(KeyrangeVal(x0), KeyrangeVal(y0));
  uint32_t maxVal   = MAX(KeyrangeVal(x0), KeyrangeVal(y0));
  KeyrangeList *c, **p, *tmp;

  if ((l==NULL) || (*l==NULL)) return 0;

  logMessage(LOG_CATEGORY(SERVER_EVENTS) | LOG_DEBUG,
    "removing range [%"PRIx32"(%"PRIx32")..%"PRIx32"(%"PRIx32")]",
    minVal, minFlags, maxVal, maxFlags
  );

  /* Need to intersect with every range */
  p = l; c = *p;
  while (c) {
    if (c->minVal > maxVal || c->maxVal < minVal ||
        !(c->maxFlags | ~minFlags) || !(~c->minFlags | maxFlags)) {
      /* don't intersect */
      p = &c->next;
      c = *p;
      continue;
    }

    if (minVal <= c->minVal && maxVal >= c->maxVal &&
        (c->minFlags | minFlags) == c->minFlags &&
        (c->maxFlags & ~maxFlags) == 0) {
      /* range falls completely in deletion range, just drop it */
      tmp = c; c = c->next;
      freeKeyrange(p,tmp);
      continue;
    }

    /* Partly intersect */

    if (c->minVal < minVal) {
      /* lower part should be kept intact, save it. */
      p = createKeyrange(p, c->minFlags, c->minVal, c->maxFlags, minVal - 1, c);
      if (p == NULL) return -1;
      c->minVal = minVal;
    }

    if (c->maxVal > maxVal) {
      /* upper part should be kept intact, save it. */
      p = createKeyrange(p, c->minFlags, maxVal + 1, c->maxFlags, c->maxVal, c);
      if (p == NULL) return -1;
      c->maxVal = maxVal;
    }

    /* Now values are contained in suppression, intersect against flags */

    if (~minFlags & maxFlags) {
      /* At least some flag must now be neither cleared nor set, drop range */
      tmp = c; c = c->next;
      freeKeyrange(p,tmp);
      continue;
    }

    /* Clamp flags on the value interval */
    c->minFlags |= ~maxFlags;
    c->maxFlags &= ~minFlags;

    p = &c->next;
    c = *p;
  }

  return 0;
}
