/*
 * $Header: /home/gene/library/website/docsrc/vwu/src/RCS/avi-ar.c,v 395.1 2008/04/20 17:25:48 gene Exp $
 *
 * Copyright (c) 2006 Gene Michael Stover.  All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
 * USA
 */

#include "this.h"

/*
 */
enum { ACTION_RUN, ACTION_HELP };
static int S_action = ACTION_RUN;

/*
 * Pathname of output file.
 */
static char *S_aviname = "avi-ar.avi";

/*
 * The CODEC to use.  Defaults to "MSVC", but you can change it
 * with the "-c" command line option.
 */
static char *S_codec = "MSVC";

/*
 */
static unsigned long S_quality = 10000;

/*
 * Number of frames per second.  Set it with the "-r" command
 * line option.
 */
static unsigned S_fps = 24;

/*
 */
static Boolean S_isErase = FALSE;

/*
 */
static int
S_Init ()
{
  int rc = 0;

  setbuf (stdout, NULL);
  AVIFileInit ();
  return rc;
}

static int
S_CommandLine (int argc, char *argv[])
{
  extern char *optarg;
  extern int optind, optopt;
  int rc = 0, c;

  while (rc == 0 && (c = getopt (argc, argv, "Ec:f:hq:")) != EOF) {
    switch (c) {
    case 'E':
      S_isErase = TRUE;
      break;
    case 'c':
      S_codec = optarg;
      break;
    case 'h':
      S_action = ACTION_HELP;
      break;
    case 'f':
      if (sscanf (optarg, "%u", &S_fps) == 1) {
        /* good */
      } else {
        printf ("\n%s:%d: sscanf: %s", __FILE__, __LINE__, strerror (errno));
        printf ("%s:%d: sscanf of \"%s\" into an unsigned integer failed.",
                __FILE__, __LINE__, optarg);
        rc = 70;
      }
      break;
    case 'q':
      if (sscanf (optarg, "%lu", &S_quality) == 1) {
        /* good */
      } else {
        printf ("\n%s:%d: sscanf: %s", __FILE__, __LINE__, strerror (errno));
        printf ("%s:%d: sscanf of \"%s\" into an unsigned long failed.",
                __FILE__, __LINE__, optarg);
        rc = 70;
      }
      break;
    case ':':
      printf ("\n%s:%d: getopt: Problem with the argument for \"-%c\"",
              __FILE__, __LINE__, optopt);
      rc = 39;
      break;
    case '?':
      printf ("\n%s:%d: getopt: Unknown option?  \"-%c\"", __FILE__,
              __LINE__, optopt);
      rc = -40;
      break;
    default:
      printf ("\n%s:%d: Command line error?", __FILE__, __LINE__);
      rc = -41;
    }
  }
  if (rc == 0) {
    if (optind < argc) {
      S_aviname = argv[optind++];
      while (optind < argc) {
        printf ("\n%s:%d: Ignoring argv[%d], \"%s\"", __FILE__, __LINE__,
                optind, argv[optind]);
        ++optind;
      }
    } else {
      /*
       * Leave S_aviname alone.  That'll give us the default output
       * file name.
       */
    }
  }
  return rc;
}

static int
S_Loop (Vidf *vidf)
{
  int rc = 0;
  time_t tt;
  double movie, real;
  Frame *frame;
  unsigned long i;

  time (&tt);
  while (rc == 0 && (frame = FRAME_Next ()) != NULL) {
    real = difftime (time (NULL), tt);
    movie = vidf->n * 1.0 / VIDF_GetFps (vidf);
    i = vidf->n % (11 * VIDF_GetFps(vidf));
    printf ("%c", i == 0 ? '\n' : '\r');
    printf ("[%lu]", vidf->n);
    printf (" Compressed %.2f movie seconds", movie);
    printf (" in %.2f real seconds.", real);
    if (real > 0.0) {
      printf ("  %.2e", movie / real);
    }
    if (VIDF_AppendFrame (frame, vidf) == 0) {
      /* good so far */
    } else {
      printf ("\n%s:%d: VIDF_AppendFrame failed", __FILE__, __LINE__);
      rc = 37;
    }
    if (S_isErase) remove (frame->pathname);
    frame = FRAME_Destroy (frame);
  }
  return rc;
}

/*
 */
static int
S_Run ()
{
  int rc = 0;
  Vidf *vidf;
  
  vidf = VIDF_Create (S_aviname, S_codec, S_fps, S_quality);
  if (vidf != NULL) {
    if (S_Loop (vidf) == 0) {
      /* good */
    } else {
      printf ("\n%s:%d: S_Loop failed", __FILE__, __LINE__);
      rc = 19;
    }
    vidf = VIDF_Close (vidf);
  } else {
    printf ("\n%s:%d: VIDF_Create failed", __FILE__, __LINE__);
    rc = 59;
  }
  return rc;
}

static int
S_Help ()
{
  printf ("\nCopyright (c) 2006 Gene Michael Stover.  All rights reserved.");
  printf ("\nCompiled %s %s", __DATE__, __TIME__);
  printf ("\n");
  printf ("\navi-ar [-E] [-c codec] [-f fps] [-q quality] [avifile]");
  printf ("\n");
  printf ("\nThe complete documentation is available on the world wide web");
  printf (" at");
  printf ("\n<http://cybertiggyr.com/gene/vwu/>.");
  return 0;
}

static int
S_Dispatch (int action)
{
  int rc = 0;

  switch (action) {
  case ACTION_RUN:
    rc = S_Run ();
    break;
  case ACTION_HELP:
    rc = S_Help ();
    break;
  default:
    printf ("\n%s:%d: Unknown action %d. ", __FILE__, __LINE__, action);
    printf (" This should never happen.");
    rc = 3;
  }
  return rc;
}

/*
 */
static void
S_Uninit ()
{
  AVIFileExit ();
}

int
main (int argc, char *argv[])
{
  int rc = 0;

  if (S_Init () == 0) {
    if (S_CommandLine (argc, argv) == 0) {
      if (S_Dispatch (S_action) == 0) {
        /* good */
      } else {
        printf ("\n%s:%d: S_Dispatch failed", __FILE__, __LINE__);
        rc = 110;
      }
    } else {
      printf ("\n%s:%d: S_CommandLine failed", __FILE__, __LINE__);
      rc = 1210;
    }
    S_Uninit ();
  } else {
    printf ("\n%s:%d: S_Init failed", __FILE__, __LINE__);
    rc = -1245;
  }
  return rc == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}

/* --- end of file --- */
