/********************************************************************
 *                                                                  *
 *       oggcut - cut ogg files without reencoding                *
 *                (c) 2002 <j@thing.net>                            *
 *                                                                  *
 *                                                                  *
 ********************************************************************/

#include <stdlib.h>
#include <stdio.h>
#include "vorbis/codec.h"
#include "vorbis/vorbisfile.h"

#include "argtable.h"

#ifdef _WIN32 /* We need the following two to set stdin/stdout to binary */
# include <io.h>
# include <fcntl.h>
#endif

split_stream(char *input_file, char *output_file,double header_length,double cut_point_begin,double cut_point_end)
{
  double i,pos;
  int lettre;
  FILE *input,*output;
  /* copy first part to new file */
  input=fopen(input_file,"r");
  output=fopen(output_file,"w");
  
  for (i=1;i<=header_length; i++)
    {
      if((lettre = fgetc(input)) != EOF) 
	{ 
	  fputc(lettre,output); //put text in the new file
	}
    }
  if(cut_point_begin>=header_length) {
    for (i=1;i<=(cut_point_begin-header_length); i++)
      {
	if((lettre = fgetc(input)) != EOF) {}
      }
  }

  for (i=1;i<=(cut_point_end-header_length-cut_point_begin); i++)
    {
      if((lettre = fgetc(input)) != EOF) 
	{ 
	  fputc(lettre,output); //put text in the new file
	}
    }
  fclose(input);
  fclose(output);
  
}

double seek_cut_point(OggVorbis_File *pov,double time) {
  if(ov_time_seek(pov, time)) {
    fprintf(stderr,"could not find second %ld in stream\n",(long)time);	
  }
  return ov_raw_tell(pov);
}



int main(int argc, char **argv)
{
  OggVorbis_File ov;
  int i,ret;
  ogg_int64_t pcmlength;
  char *bigassbuffer;
  char inputfile[1024],outputfile[1024],outputfile_t[1024];
  FILE *input,*output_t,*output;
  int dummy;
  double time_begin,time_end,header_length;
  double cut_point_end,cut_point_begin;
  arg_rec argtable[] =
  {
    { "-begin"," seconds", arg_dbl, &time_begin, NULL,     "\t\t cut file here" },
    { "-end"," seconds", arg_dbl, &time_end, NULL,     "\t\t cut file here" },
    { "-o ","outputfile",  arg_str, outputfile, NULL, "\t output\n\togg stream from begin[in seconds] to end[in seconds]" },
    { NULL ,"inputfile",  arg_str, inputfile, NULL, "\t\t input file" }

  };
  const size_t narg = sizeof(argtable)/sizeof(arg_rec);
 
  
#ifdef _WIN32 /* We need to set stdin/stdout to binary mode. Damn windows. */
  _setmode( _fileno( stdin ), _O_BINARY );
  _setmode( _fileno( stdout ), _O_BINARY );
#endif

  /* read the params */
  /*-- process the command line args --*/
  if (argc==1)
    {
      /*-- display program usage and exit. --*/
      fprintf(stderr,"Usage: %s %s\n", argv[0], arg_syntax(argtable,narg));
      fprintf(stderr,"%s\n",arg_glossary(argtable,narg,"   "));
      return 0;
    }
  else
    {
      /*-- scan command line arguments from argv[] --*/
      char cmdline[200], errmsg[200], errmark[200];
      if (!arg_scanargv(argc,argv,argtable,narg,cmdline,errmsg,errmark))
	{
	  /*-- arg error occurred, print error message and exit --*/
	  fprintf(stderr,"ERROR: %s\n", cmdline);
	  fprintf(stderr,"       %s %s\n", errmark, errmsg);
	  return 1;
	}
    }

  /*-- get here only if command line args ok --*/
  
  /* open the file/pipe on stdin */
  input=fopen(inputfile,"r");
  if(ov_open(input,&ov,NULL,-1)<0){
    fprintf(stderr,"Could not open input as an OggVorbis file.\n\n");
    exit(1);
  }

  if(ov_seekable(&ov)){
      header_length=(ov.dataoffsets[0]-ov.offsets[0]);
    /* search the raw location */
    {
      cut_point_begin=seek_cut_point(&ov,time_begin);
      cut_point_end=seek_cut_point(&ov,time_end);

      if(ov_time_seek(&ov, time_end)) {
	fprintf(stderr,"could not find second %ld in stream\n",(long)time_end);	
      }



      /*      fprintf(stderr,"stream begin:  %ld\n",(long)cut_point_begin);
      fprintf(stderr,"stream end:    %ld\n",(long)cut_point_end);
      */
      ov_clear(&ov);
      fprintf(stderr,"copied %ld sec (%ld bytes)\n",(long)(time_end-time_begin),(long)(cut_point_end-cut_point_begin));

      sprintf(outputfile_t,"%s.fix.tmp",outputfile);
      split_stream(inputfile,outputfile_t,header_length,cut_point_begin,cut_point_end);
      /* fix output ogg stream */
      output_t=fopen(outputfile_t,"r");
      if(!output_t) {
	fprintf(stderr,"Couldn't open %s for reading\n", outputfile_t);
	exit(1);
      }
      output=fopen(outputfile,"w");
      if(!output) {
	fprintf(stderr,"Couldn't open %s for writing\n", outputfile);
	exit(1);
      }
      oggfix(output_t,output);
      fclose(output_t);
      fclose(output);
      remove(outputfile_t);
      printf ("done.\n");


      /* fixed */

    }
  }else{
    fprintf(stderr,"Standard input was not seekable.\n");
  }

  return 0;
}












