#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <time.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <signal.h>
#include "eterm.h"
#include "init.h"
#include "inout.h"

int init_parms = FALSE;
int dumb = FALSE;


int getopts(int argc, char **argv)
{
   int c;
   opterr = 0;

   while ((c = getopt(argc, argv, "di")) != -1) {
       switch(c) {
           case 'd':
               dumb = TRUE;
               break;
           case 'i':
               init_parms = TRUE;
               break;
           case '?':
               if (isprint(optopt))
                   fprintf(stderr, "Unknown option '-%c'.\n", optopt);
               else
                   fprintf(stderr, "Unknown option character '\\x%x'.\n",
                           optopt);
               return 0;
           default:
               abort();
       }
   }
   return 1;
}

void sigint_handler(int sig)
{
   write_tnc(0x03);
}

void sigtstp_handler(int sig)
{
   tcsetattr(STDIN_FILENO, TCSANOW, &console_old_settings);
   signal(sig, SIG_DFL);
   kill(getpid(), sig);
}

void sigcont_handler(int sig)
{
   tcsetattr(STDIN_FILENO, TCSANOW, &console_settings);
   signal(SIGTSTP, sigtstp_handler);
}

void sighup_handler(int sig)
{
   send_string("echo off", 1);
   usleep(300000);
   if (chk_incoming(tnc)) read_tnc(0);
   if (cap) fclose(capf);
   tcsetattr(tnc, TCSANOW, &tnc_old_settings);
   signal(sig, SIG_DFL);
   kill(getpid(), sig);
}

void quit(int retcode)
{
   if (! dumb) {
       send_string("echo off", 1);
       usleep(300000);
       if (chk_incoming(tnc)) read_tnc(1);
   }
   if (cap) fclose(capf);
   tcsetattr(tnc, TCSANOW, &tnc_old_settings);
   tcsetattr(STDIN_FILENO, TCSANOW, &console_old_settings);
   close(tnc);
   printf("\n");
   exit(retcode);
}

void init_tnc_parms(void)
{
   send_string("deadtime 33", 1);
   usleep(150000);
   send_string("acktime 13", 1);
   usleep(150000);
   send_string("resptime 0", 1);
   usleep(150000);
   send_string("dwait 0", 1);
   usleep(150000);
   send_string("maxframe 4", 1);
   usleep(150000);
   send_string("frack 3", 1);
   usleep(150000);
   send_string("paclen 128", 1);
   usleep(150000);
   send_string("radio 2", 1);
   usleep(150000);
   send_string("mode vp", 1);
   usleep(150000);
}

void init(int argc, char **argv)
{
   char tnc_dev[256];
   char *p1 = NULL;

   if (! (p1 = getenv("ETERM_DEV"))) {
       printf("Error: Environment variable ETERM_DEV not set\n");
       exit(1);
   }
   strcpy(tnc_dev, p1);

   if (! getopts(argc, argv))
       exit(1);

   if ((tnc = open(tnc_dev, O_RDWR | O_NONBLOCK)) == -1) {
       perror("Error opening tnc device");
       exit(1);
   }

   tcgetattr(tnc, &tnc_old_settings);
   tcgetattr(tnc, &tnc_settings);
   tnc_settings.c_iflag &= ~(ICRNL | IXOFF | IXON);
   tnc_settings.c_iflag |= IGNCR;
   tnc_settings.c_lflag &= ~(ECHO | ICANON | ISIG);
   tnc_settings.c_cflag |= CRTSCTS;      /* Hardware flow control */
   tnc_settings.c_cflag |= CLOCAL;       /* Ignore modem status lines */
   tnc_settings.c_oflag &= ~OPOST;
   tnc_settings.c_cc[VMIN] = 1;
   tnc_settings.c_cc[VTIME] = 0;
   cfsetispeed(&tnc_settings, B9600);
   cfsetospeed(&tnc_settings, B9600);
   tcsetattr(tnc, TCSANOW, &tnc_settings);

   tcgetattr(STDIN_FILENO, &console_old_settings);
   tcgetattr(STDIN_FILENO, &console_settings);
   console_settings.c_lflag &= ~(ECHO | ICANON);
   tcsetattr(STDIN_FILENO, TCSANOW, &console_settings);

   setbuf(stdout, NULL);

   signal(SIGINT, sigint_handler);
   signal(SIGTSTP, sigtstp_handler);
   signal(SIGCONT, sigcont_handler);
   signal(SIGHUP, sighup_handler);

   if (! dumb) {
       write_tnc(3);
       write_tnc(10);

       if (init_parms)
           init_tnc_parms();

       send_string("echo on", 1);
       usleep(300000);
       if (chk_incoming(tnc))
           read_tnc(1);
       else {
           printf("TNC doesn't respond, aborting...\n");
           quit(1);
       }
   }
}