/* cflight: copyright (c) 2006 Chris Fallin <chris@cfallin.org>

   released under the MIT open-source license */

#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/uio.h>
#include <stdio.h>
#include <curses.h>

#define cliph(x) ( ( (x) > 255) ? 255 : (x) )
#define clipl(x) ( ( (x) < 0)   ? 0   : (x) )
#define clip(x)  cliph(clipl(x))

int set_channel(int fd, int channel, int value)
{
  char buf[4];

  buf[0] = 0x40 | (channel & 0x1f);
  buf[1] = 0x60 | ( (channel >> 5) & 0x0f);
  buf[2] = 0x00 | (value & 0x1f);
  buf[3] = 0x20 | ( (value >> 5) & 0x07 );

  if(write(fd, buf, 4) < 4)
    return 1;

  return 0;
}

int send_update(int fd)
{
  char buf[1];

  buf[0] = 0x80;

  if(write(fd, buf, 1) < 1)
    return 1;

  return 0;
}

int open_fd()
{
  int fd;

  if((fd = open("/tmp/udmx-control", O_WRONLY)) < 0)
    return -1;

  return fd;
}

int close_fd(int fd)
{
  close(fd);
}

int main()
{
  int fd;
  int c1 = 0, c2 = 0, c3 = 0, c4 = 0;

  int b1 = 0, b2 = 0, b3 = 0, b4 = 0;

  fd = open_fd();
  if(fd < 0)
  {
    fprintf(stderr, "Error opening control FIFO.\n");
    return 1;
  }

  initscr();
  clear();

  while(1)
  {
    char c;
    
    mvprintw(5, 5, "Channels: %03d %03d %03d %03d", c1, c2, c3, c4);
    c = getch();
    if(c == EOF)
      break;

    if(c == 'q') c1 += 16;
    if(c == 'a') c1 = 128;
    if(c == 'z') c1 -= 16;
    if(c == 'w') c2 += 16;
    if(c == 's') c2 = 128;
    if(c == 'x') c2 -= 16;
    if(c == 'e') c3 += 16;
    if(c == 'd') c3 = 128;
    if(c == 'c') c3 -= 16;
    if(c == 'r') c4 += 16;
    if(c == 'f') c4 = 128;
    if(c == 'v') c4 -= 16;

    c1 = clip(c1);
    c2 = clip(c2);
    c3 = clip(c3);
    c4 = clip(c4);

    if(b1) b1 = 0;
    if(b2) b2 = 0;
    if(b3) b3 = 0;
    if(b4) b4 = 0;

    if(c == '5')
      b1 = 64;
    if(c == '6')
      b2 = 64;
    if(c == '7')
      b3 = 64;
    if(c == '8')
      b4 = 64;

    if(c == '1')
    {
      if(c1)
        c1 = 0;
      else
        c1 = 255;
    }
    if(c == '2')
    {
      if(c2)
        c2 = 0;
      else
        c2 = 255;
    }
    if(c == '3')
    {
      if(c3)
        c3 = 0;
      else
        c3 = 255;
    }
    if(c == '4')
    {
      if(c4)
        c4 = 0;
      else
        c4 = 255;
    }

    set_channel(fd, 0, clip(c1 + b1));
    set_channel(fd, 1, clip(c2 + b2));
    set_channel(fd, 2, clip(c3 + b3));
    set_channel(fd, 3, clip(c4 + b4));
    send_update(fd);
//    usleep(1000000 / 16);
  }

  endwin();

  return 0;
}
