/* Speak a text file a line at a time  */

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <getopt.h>
#include <pthread.h>
#include <flite.h>

#define LINESIZE 100

cst_voice *register_cmu_us_kal();

/* option handling */
const char* const short_options = "sf:hr:";
const struct option long_options[] = { 
   {"speak" , 0 , NULL , 's'},
   {"file"  , 1 , NULL , 'f'},
   {"help"  , 0 , NULL , 'h'},
   {"resume", 1 , NULL , "r"},
   {NULL    , 0 , NULL ,  0 }
};

FILE *fp;
cst_voice *v;
float total_time = 0.0, line_time = 0.0;
char line[LINESIZE];
int current_line = 0, from_start = TRUE, initial_line = 0;

void speakout(){
  while (fgets(line, LINESIZE-1,fp) != NULL){
    if (current_line < initial_line) {
      current_line++;
    }
    else {
      printf("%d\t%s",current_line,line);
      line_time = flite_text_to_speech(line, v , "play");
      total_time += line_time;
      current_line++;
    }
  }
}

void speaktime(){
  while (fgets(line, LINESIZE-1,fp) != NULL){
    line_time = flite_text_to_speech(line, v , "none");
    total_time += line_time;
  }
}


void print_error(){
  fprintf(stderr, "Need a filename to read.\n");
  fprintf(stderr, "Use -s to get audio output.\n");
  fprintf(stderr, "Usage : spk -f filename -s \n");
  fprintf(stderr, "Use -r to resume from specified line number\n");
}

int main(int argc, char *argv[]) {
  char *filename = NULL;
  int next_option;
  int audio = FALSE;
  pthread_t thread_id;
  if (argc < 2) {
    print_error();
    exit(1);
  } 
  do{
    next_option = getopt_long(argc,argv,short_options,long_options,NULL);
    switch (next_option){
      case 's': /* Speak file  */
        audio = TRUE; 
        printf("Reading file\n");
        break;
      case 'f': /* File to speak */
        filename = optarg;
        break;
      case 'h': /* Print usage */
      case '?':
        print_error();
        exit(1);
        break;       
      case 'r': /* Get line number to start from  */
        initial_line = atoi(optarg);
        from_start = FALSE;
        break; 
      case -1 : /* Done with processing arguments  */
        break;
    }
  } while (next_option != -1);

  
  if (filename == NULL) {
    print_error();
    exit(1);
  }  

  if ((fp = fopen(filename,"r")) == NULL){
    fprintf(stderr,"Error opening file %s\n",filename);
    exit(1);
  }

  flite_init();
  v = register_cmu_us_kal();
  
  if (audio)
    pthread_create(&thread_id, NULL , &speakout , NULL); 
  else 
    pthread_create(&thread_id, NULL , &speaktime , NULL); 
 
  /* Wait for thread to end */
  pthread_join(thread_id, NULL);  

  printf("Total play time is %.2f seconds, or %.2f minutes\n",total_time,total_time/60);
  printf("Total number of lines in file was %d, total lines read were %d\n", current_line, current_line - initial_line);
  fclose(fp);
  return 0;
}
