#ifndef _LCR_GENERAL_H
#define _LCR_GENERAL_H

/** @file general.h

  Licar: general

  This file holds general definitions used by all modules.
*/

#include <stdint.h>
#include "settings.h"

// constants (not supposed to be changed, doing so may break stuff):

#define LCR_EFFECTIVE_RESOLUTION_X \
  (LCR_SETTING_RESOLUTION_X / LCR_SETTING_RESOLUTION_SUBDIVIDE)

#define LCR_EFFECTIVE_RESOLUTION_Y \
  (LCR_SETTING_RESOLUTION_Y / LCR_SETTING_RESOLUTION_SUBDIVIDE)

#define LCR_MAP_SIZE_BLOCKS 64

/** Physics FPS, i.e. the number of physics ticks per second. */
#define LCR_RACING_FPS 30

#define LCR_RACING_TICK_MS \
  (100000 / (LCR_RACING_FPS * LCR_SETTING_TIME_MULTIPLIER))

#if LCR_SETTING_332_COLOR
  #define LCR_CONVERT_COLOR(c) \
    (((c & 0xe000) >> 8) | ((c & 0x0700) >> 6) | ((c & 0x001f) >> 3))
#else
  #define LCR_CONVERT_COLOR(c) c
#endif

char _LCR_hexDigit(int i)
{
  return i < 10 ? '0' + i : ('a' - 10 + i);
}

int _LCR_hexDigitVal(char c)
{
  if (c >= '0' && c <= '9')
    return c - '0';

  if (c >= 'a' && c <= 'f')
    return c - 'a' + 10;

  return -1;
}

/**
  Computes simple hash of a string represented by a function returning next
  string character, ending at 0 or endChar. This is intended for simple (but
  not 100% reliable) string comparison.
*/
uint16_t _LCR_simpleStrHash(char (*nextChar)(void), char endChar)
{
  uint16_t r = 0;
 
  while (1)
  {
    char c = nextChar();

    if (c == 0 || c == endChar)
      break;

    r = ((r << 5) | (r >> 11)) + c;
  }

  return r;
}

int _LCR_strCmp(const char *s1, const char *s2)
{
  while (1)
  {
    if (*s1 != *s2)
      return 0;

    if (*s1 == 0)
      break;

    s1++;
    s2++;
  }
 
  return 1;
}

char _LCR_triangleWinding(int x0, int y0, int x1, int y1, int x2, int y2)
{
  x0 = (y1 - y0) * (x2 - x1) - (x1 - x0) * (y2 - y1);
  return x0 != 0 ? (x0 > 0 ? 1 : -1) : 0;
}

#endif // guard
