/*
 * CDTOOL is a program to play and catalog audio compact discs on
 * a cdrom drive
 *
 * Copyright 1994 Thomas Insel.
 * Copyright 1995,96 Sven Oliver Moll
 *
 * 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; version 2 dated June, 1991.
 *
 * 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
 * with this program; if not, write to the Free Software Foundation,
 * Inc., 675 Mass Ave., Cambridge, MA 02139, USA.
 *
 * For information on CDTOOL, alternate licensing, or whatever, 
 * contact Thomas Insel via email (tinsel@uiuc.edu) or write to
 * Thomas Insel, 210 Parkview Drive, Bloomington, IL 61701-2038.
 * 
 * Multiple cdrom drive support
 * cdinfo command
 * skip track option
 * some minor enhanchments
 * and some bugs fixed
 * by
 * Sven Oliver Moll
 * 
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <strings.h>
#include <sys/stat.h>

#include "config.h"
#include "cdtool.h"
#include "commands.h"
#include "shuffle.h"
#include "hardware.h"
#include "info.h"
#include "util.h"

#define CD_DEVICE "/dev/cdrom"

static char *svnid = "$Id: cdtool.c 1529 2005-10-17 18:24:22Z max $";
void do_usage(char *progname);

/************************************************************************/
/* Procedure:  main
 * Purpose:    C code main function
 * 
 * Inputs:     command line args
 * Outputs:    to stdout
 * Returns:    error code (0 if exit is OK)
 * Notes:  
 *   1.
 */
/************************************************************************/
int main(int argc, char *argv[]) 
{
  cdtool_t      cdtool;
  int		info=I_AUDIOSTATUS, error=0, opt, trk0=0, trk1=0;
  extern int	optind, getopt();
  extern char	*optarg;

  char p_format = P_LONG;
  char *device = NULL;
  char *progname = NULL;
  int  usedb = 1;
  int  iRepeat = 1;
  int  iTracks = 100;
  int  iCDNum = 0;

  progname = setprogname(argv[0]);
  cdtool.device = NULL;
  cdtool_show_debug = FALSE;
  cdtool_show_verbose = FALSE;
  cdtool_show_crlf = DOLF;
  
  while((opt = getopt(argc,argv,"0123456789?ad:Dhi:nrstvVp:R:T:")) != EOF)
    {
      switch(opt)
	{    
	 case '0':
	 case '1':
	 case '2':
	 case '3':
	 case '4':
	 case '5':
	 case '6':
	 case '7':
	 case '8':
	 case '9':
	  device = strdup(CD_DEVICE "?");
	  *(device + sizeof(CD_DEVICE)-1) = opt;
	  iCDNum = opt - '0';
	  break;
	 case 'a':
	  error = 1;
	  if (strcmp(progname, "cdinfo") == 0)
	    {
	      error = 0;
	      info = I_DISP_ABS;
	    }
	  break;
	 case 'd':
	  device=optarg;
	  break;
	 case 'n':
	  error = 1;
	  if (strcmp(progname, "cdir") == 0)
	    {
	      error = 0;
	      usedb = 0;
	    }
	  break;
	 case 'r':
	  error = 1;
	  if (strcmp(progname, "cdir") == 0)
	    {
	      error = 0;
	      p_format = P_RAW; 
	    }
	  if (strcmp(progname, "cdinfo") == 0)
	    {
	      error = 0;
	      info = I_DISP_REL;
	    }
	  break;
	 case 's':
	  error = 1;
	  if (strcmp(progname, "cdir") == 0)
	    {
	      error = 0;
	      p_format = P_QUICK;
	    }
	  if (strcmp(progname, "cdinfo") == 0)
	    {
	      error = 0;
	      info = I_AUDIOSTATUS;
	    }
	  break;
	 case 't':
	  error = 1;
	  if (strcmp(progname, "cdir") == 0)
	    {
	      error = 0;
	      p_format = P_TEMPL;
	    }
	  if (strcmp(progname, "cdinfo") == 0)
	    {
	      error = 0;
	      info = I_TRACK;
	    }
	  break;

	  /* verbose info printout */
	 case 'v':
	  cdtool_show_verbose = TRUE;
	  error = 1;
	  if ((strcmp(progname, "cdshuffle") == 0) ||
	      (strcmp(progname, "cdvolume") == 0) ||
	      (strcmp(progname, "cdplay") == 0) ||
	      (strcmp(progname, "cdstart") == 0)) {
	      error = 0;
	  }
	  else if (strcmp(progname, "cdir") == 0) {
	      error = 0;
	      usedb = 1;
	  }
	  else if (strcmp(progname, "cdinfo") == 0) {
	      error = 0;
	      info = I_DISP_ALL;
	  }
	  break;

	  /* for debug, overload the program name, e.g., */
	  /* cdtool -p info is the same as cdinfo */
	case 'p':
	  progname = setprogname(optarg);
	  error = 0;
	  break;

	case 'R':
	  if ((strcmp(progname, "cdshuffle") == 0) ||
	      (strcmp(progname, "cdstart") == 0) ||
	      (strcmp(progname, "cdplay") == 0)) {
	      error = 0;
	      iRepeat = atoi(optarg);
	  }
	  break;

	case 'T':
	  if ((strcmp(progname, "cdshuffle") == 0) ||
	      (strcmp(progname, "cdstart") == 0) ||
	      (strcmp(progname, "cdplay") == 0)) {
	      error = 0;
	      iTracks = atoi(optarg);
	  }
	  break;
	  
         case 'D':
             /* enable debugging */
             cdtool_show_debug = TRUE;
             break;

	 /* print version number and then standard HELP */
	 case 'V':
	     printf("%s %s\n", progname, VERSION_STRING);
	     printf("Build: %s %s [%s]\n",__DATE__,__TIME__, svnid);
             exit(0);

	  /* general options */
	 case '?':
	 case 'h':
	 default:
	  error = 1;
	  break;
	}
    }

  if (error)
    {
      do_usage(progname);
      exit(1);
    }

  if (cdtool_open(&cdtool, device) < 0)
    {
      exit(1);
    }

  if ((strcmp(progname, "cdplay") == 0) ||
      (strcmp(progname, "cdstart") == 0))
    {
	if (optind < argc)
	    trk0=atoi(argv[optind++]);
	
	if (optind < argc)
	    trk1=atoi(argv[optind]);
	
	optind--;
        
	if (strcmp(argv[optind],"-") == 0) {
	    do_skip(&cdtool, SKIPBACK, 1);
            close(cdtool.fd);
            exit(0);
        }
	
	if (strcmp(argv[optind],"+") == 0 ) {
	    do_skip(&cdtool, SKIPFORWARD, 1);
            close(cdtool.fd);
            exit(0);
        }
	
	if (strcmp(argv[optind],"?") == 0 ) {
	    do_usage(progname);
	    exit(0);
	}

	if ((strcmp(argv[optind],"start") == 0) ||
	     (strcmp(argv[optind],"x") == 0 ) ||
	     (strcmp(argv[optind],"0") == 0 )) {
	    trk0=SKIPSTART;
        }

	if (strcmp(argv[optind],"stop") == 0) {
            do_stop(&cdtool, iCDNum);
	    close(cdtool.fd);
	    exit(0);
        }
	if (strcmp(argv[optind],"pause") == 0) {
            do_pause(&cdtool);
	    close(cdtool.fd);
	    exit(0);
        }
	if (strcmp(argv[optind],"eject") == 0) {
            do_eject(&cdtool);
	    close(cdtool.fd);
	    exit(0);
        }
	if (strcmp(argv[optind],"close") == 0) {
            do_close(&cdtool);
	    close(cdtool.fd);
	    exit(0);
        }
	if (strcmp(argv[optind],"info") == 0) {
            do_info(&cdtool, I_DISP_ALL);
	    do_crlf(stdout);
	    close(cdtool.fd);
	    exit(0);
        }

	if (strcmp(argv[optind],"dir") == 0) {
            do_dir(&cdtool, P_RAW, 0);
	    close(cdtool.fd);
	    exit(0);
        }
        
	if (strcmp(argv[optind],"resume") == 0)
            do_play(&cdtool, 0, 0);

	if (strcmp(argv[optind],"shuffle") == 0)
            do_shuffle(&cdtool, iCDNum, iTracks, iRepeat);
        
	if (strcmp(argv[optind],"volume") == 0) {
	     if(++optind < argc) {
		  int vol=atoi(argv[optind]);
                  int ret;
                  ret = do_volume(&cdtool, vol);
		  exit(ret);
	     }
	}

	do_play(&cdtool, trk0, trk1);
    }

  else if (strcmp(progname, "cdstop") == 0)
    do_stop(&cdtool, iCDNum);
  
  else if (strcmp(progname, "cdeject") == 0)
    do_eject(&cdtool);

  else if (strcmp(progname, "cdclose") == 0)
    do_close(&cdtool);

  else if (strcmp(progname, "cdreset") == 0)
    do_reset(&cdtool);

  else if (strcmp(progname, "cdpause") == 0)
    do_pause(&cdtool);

  else if (strcmp(progname, "cdshuffle") == 0)
    do_shuffle(&cdtool, iCDNum, iTracks, iRepeat);

  else if (strcmp(progname, "cdinfo") == 0) {
    do_info(&cdtool, info);
    do_crlf(stdout);
  }

  else if (strcmp(progname, "cdir") == 0)
    do_dir(&cdtool, p_format, usedb);

  else if (strcmp(progname, "cdvolume") == 0) {
    if (optind < argc) {
      int vol=atoi(argv[optind]);
      int ret;
      ret = do_volume(&cdtool, vol);
      exit(ret);
    }
    else
      do_usage(progname);
  }
  else do_usage(progname);

  close(cdtool.fd);

  exit(0);
}

/************************************************************************/
/* Procedure:  do_usage
 * Purpose:    to print usage info (help)
 * 
 * Inputs:     program name
 * Outputs:    to stderr
 * Returns:    n/a
 * Notes:  
 *   1.
 */
/************************************************************************/
void do_usage(char *progname)
{
  fprintf(stderr, "%s", VERSION_STRING); fprintf(stderr,"\n");
  
  if ((strcmp(progname, "cdplay") == 0) ||
      (strcmp(progname, "cdstart") == 0)) {
    fprintf(stderr, "usage: %s [start [stop]]\n", progname);
    fprintf(stderr, " +             next track\n");
    fprintf(stderr, " -             previous track\n");
    fprintf(stderr, " x             restart at track 1\n");
    fprintf(stderr, " S             play track S\n");
    fprintf(stderr, " S E           play track S..E\n");
    fprintf(stderr, " start         play from track 1\n");
    fprintf(stderr, " stop          stop playing\n");
    fprintf(stderr, " resume        resume playing\n");
    fprintf(stderr, " eject         eject CD-ROM\n");
    fprintf(stderr, " close         close CD-ROM tray\n");
    fprintf(stderr, " info          display info\n");
    fprintf(stderr, " dir           display directory\n");
    fprintf(stderr, " shuffle       shuffle play\n");
    fprintf(stderr, " -v            verbose output\n");
    fprintf(stderr, " -R rr         times to repeat the CDROM (shuffle only)\n");
    fprintf(stderr, " -T tt         max tracks to play (shuffle only)\n");
  }
  
  else if (strcmp(progname, "cdshuffle") == 0) {
    fprintf(stderr, "usage: cdshuffle [options]\n");
    fprintf(stderr, " -R rr         times to repeat the CDROM\n");
    fprintf(stderr, " -T tt         max tracks to play\n");
    fprintf(stderr, " -v            verbose output\n");
  }
  else if (strcmp(progname, "cdstop") == 0)
    fprintf(stderr, "usage: cdstop  [options]\n");
  else if (strcmp(progname, "cdeject") == 0)
    fprintf(stderr, "usage: cdeject  [options]\n");
  else if (strcmp(progname, "cdclose") == 0)
    fprintf(stderr, "usage: cdclose  [options]\n");
  else if (strcmp(progname, "cdvolume") == 0) 
      fprintf(stderr, "usage: cdvolume [0-255]\n");
  else if (strcmp(progname, "cdpause") == 0)
    {
      fprintf(stderr, "usage: cdpause  [options]\n");
      fprintf(stderr, "  resume play with cdplay/cdstart\n");
    } 
  else if (strcmp(progname, "cdir") == 0) 
    {
      fprintf(stderr, "usage: cdir [ [-n] {-s|-t} ]\n");
      fprintf(stderr, " -n            listing without titles\n");
      fprintf(stderr, " -r            raw read of toc\n");
      fprintf(stderr, " -s            short listing (title/artist/track)\n");
      fprintf(stderr, " -t            print template for database entry\n");
    } 
  else if (strcmp(progname, "cdinfo") == 0) 
    {
      fprintf(stderr, "usage: cdinfo [ {-a|-r|-s|-t} ]\n");
      fprintf(stderr, " -a            print absolute disc time\n");
      fprintf(stderr, " -r            print relative track time\n");
      fprintf(stderr, " -s            print audiostatus\n");
      fprintf(stderr, " -t            print current track\n");
      fprintf(stderr, " -v            print status, track, absolute, relative\n");
    }
  else 
    fprintf(stderr, "Please call as cdplay/cdstart, cdstop, cdeject, cdclose,\n\
cdvolume, cdpause, cdir, cdinfo, or cdshuffle\n");

  /* standard options below here: */
  fprintf(stderr, " -V            build, version, and this help\n");
  fprintf(stderr, " -? -h         print this message\n");
  fprintf(stderr, " -[0-9]        use device " CD_DEVICE "[0-9]\n");
  fprintf(stderr, " -d dev        use device dev\n");
  fprintf(stderr, " -D            enable debugging information\n");
}
