/*
    beer.c - Frontend for SAFT for X11
    Copyright (c) 1999,2001,6  Joey Schulze <joey@infodrom.org>

    This file is part of the Gerstensaft package.

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*/

#define _GNU_SOURCE

#include <getopt.h>
#include <gtk/gtk.h>
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <ctype.h>
#include "main.h"
#include "nls.h"
#include "config.h"
#include "beer.h"
#include "io.h"

char progname[] = "Gerstensaft";
char version[] = "0.3";

struct s_conf config = { NULL, 1 };

int beer_exitcode = EXIT_OK;

extern int errno;

static struct option long_options[] =
{
  {"help", no_argument, 0, 'h'},
  {0, 0, 0, 0}
};

void read_config ()
{
  char *fname;
  char buf[300];
  char *cp, *xp;
  FILE *f;
  int remainder;

  config.addrs = NULL; 
  config.keep = TRUE; 
  config.closewindow = FALSE; 
  config.protocol = PROTOCOL_AUTO;
  config.dotfiles = FALSE;

  if (asprintf (&fname, "%s/.gerstensaft/history", getenv("HOME")) == -1)
    return;

  if ((f = fopen (fname, "r")) != NULL) {
    for (cp = fgets(buf, sizeof(buf)-1, f); cp != NULL;
	 cp = fgets(buf, sizeof(buf)-1, f) ) {
      remainder = !(buf[strlen(buf)-1] == '\n');
      if (!remainder)
	buf[strlen(buf)-1] = '\0';

      if (strlen(buf) && !strncasecmp(buf, "Recipient", 9) && isspace(buf[9])) {
	for (cp=buf+10; *cp && isspace(*cp); cp++);
	xp = (char *)malloc (strlen(cp)+1);
	sprintf (xp, cp);
	config.addrs = g_list_insert_sorted (config.addrs, xp, (GCompareFunc)strcmp);
      }
      /* throw away superflous stuff */
      if (remainder) {
	for (cp = fgets(buf, sizeof(buf)-1, f); cp != NULL && buf[strlen(buf)-1] != '\n';
	     cp = fgets(buf, sizeof(buf)-1, f) );
      }
    }
    fclose (f);
  }
  free (fname);

  if (asprintf (&fname, "%s/.gerstensaft/config", getenv("HOME")) == -1)
    return;

  if ((f = fopen (fname, "r")) != NULL) {
    for (cp = fgets(buf, sizeof(buf)-1, f); cp != NULL;
	 cp = fgets(buf, sizeof(buf)-1, f) ) {
      remainder = !(buf[strlen(buf)-1] == '\n');
      if (!remainder)
	buf[strlen(buf)-1] = '\0';

      if (strlen(buf)) {
	if (!strncasecmp(buf, "KeepFiles", 9) && isspace(buf[9])) {
	  for (cp=buf+10; *cp && isspace(*cp); cp++);
	  if (!strncasecmp(cp, "false", 5))
	    config.keep = FALSE;
	} else if (!strncasecmp(buf, "DotFiles", 8) && isspace(buf[8])) {
	  for (cp=buf+9; *cp && isspace(*cp); cp++);
	  if (!strncasecmp(cp, "true", 4))
	    config.closewindow = TRUE;
	} else if (!strncasecmp(buf, "CloseWindow", 11) && isspace(buf[11])) {
	  for (cp=buf+12; *cp && isspace(*cp); cp++);
	  if (!strncasecmp(cp, "true", 4))
	    config.dotfiles = TRUE;
	} else if (!strncasecmp(buf, "Protocol", 8) && isspace(buf[8])) {
	  for (cp=buf+9; *cp && isspace(*cp); cp++);
	  if (!strncasecmp(cp, "ipv4", 4))
	    config.protocol = PROTOCOL_IPV4;
	  else if (!strncasecmp(cp, "ipv6", 4))
	    config.protocol = PROTOCOL_IPV6;
	}
      }

      /* throw away superflous stuff */
      if (remainder) {
	for (cp = fgets(buf, sizeof(buf)-1, f); cp != NULL && buf[strlen(buf)-1] != '\n';
	     cp = fgets(buf, sizeof(buf)-1, f) );
      }
    }
    fclose (f);
  }
  free (fname);
}

void write_config()
{
  char *fname;
  int i;
  FILE *f;

  if (!getenv("HOME"))
    return;

  if (asprintf (&fname, "%s/.gerstensaft", getenv("HOME")) == -1)
    return;

  if (!is_dir (fname, NULL))
    mkdir (fname, 0700);

  free (fname);
  if (asprintf (&fname, "%s/.gerstensaft/history", getenv("HOME")) == -1)
    return;

  if (!g_list_length (config.addrs)) {
    unlink (fname);
    return;
  }

  if ((f=fopen (fname,"w")) != NULL) {
    for (i=0;i<g_list_length (config.addrs); i++)
      fprintf (f, "Recipient %s\n", (char *)g_list_nth (config.addrs, i)->data);
    fclose (f);
  }

  free (fname);
  if (asprintf (&fname, "%s/.gerstensaft/config", getenv("HOME")) == -1)
    return;

  if ((f=fopen (fname,"w")) != NULL) {
    fprintf (f, "KeepFiles %s\n", config.keep?"true":"false");

    fprintf (f, "CloseWindow %s\n", config.closewindow?"true":"false");

    fprintf (f, "DotFiles %s\n", config.dotfiles?"true":"false");

    switch (config.protocol) {
    case PROTOCOL_AUTO:
      fprintf (f, "Protocol auto\n");
      break;
    case PROTOCOL_IPV4:
      fprintf (f, "Protocol ipv4\n");
      break;
    case PROTOCOL_IPV6:
      fprintf (f, "Protocol ipv6\n");
      break;
    }

    fclose (f);
  }

  free (fname);
}

void clear_history ()
{
  GList *elem;

  while (g_list_length (config.addrs)) {
    elem = g_list_nth (config.addrs, 0);
    free (elem->data);
    config.addrs = g_list_remove_link (config.addrs, elem);
    g_list_free (elem);
  }
  g_list_free (config.addrs);

  config.addrs = NULL;
}

void clear_config ()
{
  clear_history();
}

void usage()
{
  printf ("%s %s\n\n", progname, version);
  printf (_("Usage: %s"), "beer [-hv] [-srm]\n\n");
  printf ("  -h  %s\n", _("display help and exit"));
  printf ("  -m  %s\n", _("run in message mode"));
  printf ("  -r  %s\n", _("run in receive mode"));
  printf ("  -s  %s\n", _("run in send mode"));
  printf ("  -v  %s\n", _("display version and exit"));
}

int main (int argc, char *argv[])
{
  int c;
  int longindex;
  unsigned short int startmode = MOD_SEND;

  bindtextdomain ("gerstensaft", LOCALE_DIR);
  textdomain ("gerstensaft");

  /* Pass arguments to GTK
   * --display
   * --debug-level
   * --no-xshm
   * --sync
   * --show-events
   * --no-show-events
   * --name
   * --class
   */
  gtk_init (&argc, &argv);

  optind = 0;
  while ( (c = getopt_long(argc, argv, "hmrsv", long_options, &longindex)) != -1 ) {
    switch (c) {
    case 'h':
      usage();
      exit (beer_exitcode);
    case 'm':
      startmode = MOD_MESSAGE;
      break;
    case 'r':
      startmode = MOD_RECEIVE;
      break;
    case 's':
      startmode = MOD_SEND;
      break;
    case 'v':
      printf ("%s %s\n", progname, version);
      exit (beer_exitcode);
    } /* switch */
  } /* while */

  read_config ();

  main_window (startmode);
  gtk_main();

#ifdef DEBUG
  for (longindex=0;longindex<g_list_length (config.addrs); longindex++) {
    printf ("%d: %s\n", longindex, (char *)g_list_nth (config.addrs, longindex)->data);
  }
#endif

  write_config();
  clear_config();

#ifdef DEBUG
  printf ("return %d\n", beer_exitcode);
#endif

  return beer_exitcode;
}
