#include "webbyphone.h"

URL *current;
char filename[256];
int audio_fd;
char *history_list[HISTORY];
int historylist_counter;
char *prefix[2] = 
{
  "http://",
  "ftp://"
};
int mode; /** 0 is http; 1 is ftp **/

void free_node(NODE *node)
{
  if(node->next){
    free_node(node->next);
    free(node->next);
  }
  else{
    int i;
    free(node->url->url);
    free(node->url->text);
    for(i = 0; i < node->url->numLinks; i++)
      free(node->url->linkNames[i]);
    free(node->url);
  }
}

void sound()
{
  /** play a file thru tts **/
  char command[500];
  int i;

  sprintf(command, "cat %s.au > /dev/audio &\n", filename);
  if((i = system(command)) < 0){
    perror("system"); 
  }
}

void _play_file()
{
  /** play a file thru tts **/
  char command[500];
  int i;

#ifdef REAL
  sprintf(command, "tts -mulaw -8k -line -amp 8  %s &\n", filename);
#else
  sprintf(command, "tts -mulaw -8k -speaker -amp 6  %s &\n", filename);
#endif

  if((i = system(command)) < 0){
    perror("system"); 
  }

}

void insert_historylist(char *url)
{
  int i;

  for(i = 0; i < historylist_counter; i++){
    if(strcmp(url, history_list[i]) == 0){
      return;
    }
  }
  if(historylist_counter >= HISTORY){
    for(i = 0; i < historylist_counter-1; i++){
      free(history_list[i]);
      history_list[i] = history_list[i+1];
    }
    history_list[historylist_counter] = strdup(url);
  }else{
    history_list[historylist_counter++] = strdup(url);
  }
}

void song()
{
  /** play a file thru tts **/
  char command[500];
  int i;

  sprintf(command, "cat %s > /dev/audio &\n", filename);
  if((i = system(command)) < 0){
    perror("system"); 
  }
}

int play_song(char *file)
{
  thread_t sound_tid;
  strcpy(filename, file);
  thr_create(NULL, NULL, song, NULL, NULL, &sound_tid);
  return 0;
}

int play_file(char *file)
{
  thread_t sound_tid;
  strcpy(filename, file);
  thr_create(NULL, NULL, _play_file, NULL, NULL, &sound_tid);
  sleep(1);
  return 0;
}

void kill_sound()
{
  /** stop playing a file **/
  char command[500];
  int i;
  sprintf(command, "kill -9 ` ps | grep wavesynt | cut -b1-7 `");
  if((i = system(command)) < 0){
    perror("system"); 
  }
  bzero(command, 500);
  sprintf(command, "kill -9 ` ps | grep cat | cut -b1-7 `");
  if((i = system(command)) < 0){
    perror("system"); 
  }
  bzero(command, 500);
  sprintf(command, "kill -9 ` ps | grep tts | cut -b1-7 `");
  if((i = system(command)) < 0){
    perror("system"); 
  }
}

int play_sound(char *file)
{
  thread_t sound_tid;
  strcpy(filename, file);
  thr_create(NULL, NULL, sound, NULL, NULL, &sound_tid);
  return 0;
}

int play_history_summary()
{
  char filename[256];
  char string[256];

  {
    FILE *file;

    strcpy(filename, "history_file");
    file = fopen(filename, "w");
    if(file == NULL){
      fprintf(stderr, "cannot open file %s for writing\n", filename);
      return;
    }
    sprintf(string, "The current history list has %d URL.\n", historylist_counter);
    fwrite(string, 1, strlen(string), file);

    fclose(file);
  }

  return play_file(filename);
}

int play_url(char *url_in)
{
  char filename[256];
  char string[] = "You entered ";
  {
    FILE *file;

    char url[256];
    int i, counter = 0;

    strcpy(filename, "url_file");
    file = fopen(filename, "w");
    if(file == NULL){
      fprintf(stderr, "cannot open file %s for writing\n", filename);
      return -1;
    }

    for(i = 0; i < strlen(url_in); i++){
      switch(url_in[i]){
      case '.':
	{
	  url[counter++] = ' ';
	  url[counter++] = 'd';
	  url[counter++] = 'o';
	  url[counter++] = 't';
	  url[counter++] = ' ';
	}
      break;
      default:
	  url[counter++] = ' ';
	  url[counter++] = toupper(url_in[i]);
	  url[counter++] = '.';
	  url[counter++] = ' ';
      }
    }
    fwrite(string, 1, strlen(string), file);
    fwrite(url, 1, counter, file);
    fwrite(".", 1, 1, file);

    fclose(file);
  }

  return play_file(filename);
}

int play_page_url(URL *page, char *url_in, char *string, int which)
{
  char filename[256];
  {
    FILE *file;

    char url[256];
    int i, counter = 0;

    strcpy(filename, page->filename);
    strcat(filename, "_title");
    file = fopen(filename, "w");
    if(file == NULL){
      fprintf(stderr, "cannot open file %s for writing\n", filename);
      return -1;
    }

    for(i = 0; i < strlen(url_in); i++){
      switch(url_in[i]){
      case '.':
	{
	  url[counter++] = ' ';
	  url[counter++] = 'd';
	  url[counter++] = 'o';
	  url[counter++] = 't';
	  url[counter++] = ' ';
	}
      break;
      default:
	  url[counter++] = url_in[i];
      }
    }
    fwrite(string, 1, strlen(string), file);
    fwrite(url, 1, counter, file);
    fwrite(".", 1, 1, file);

    if(strstr(current->filename, ".au") == NULL && current->numLinks < 0){
      char file[] = "emptypage";
      fprintf(stderr, "empty page\n");
      play_sound(file);
      sleep(1);
    }

    if(which){
      char summary[256];
      sprintf(summary, "It has %d links.", current->numLinks + 1);
      fwrite(summary, 1, strlen(summary), file);      
    }

    fclose(file);
  }

  return play_file(filename);
}

int goto_page(char *url)
{
  char *buffer;
  int i, counter = 0;
  char *temp;
  char filename[256];
  struct stat buf;  

  current->url = (char*)malloc(sizeof(char)*(strlen(url)+1));
  strcpy(current->url, url);

  {
    char *temp = strstr(url, "//");
    if(temp == NULL){
      char file[] = "wrongurl";
      fprintf(stderr, "url is wrong format\n");
      play_sound(file);
      return -1;
    }

    strcpy(filename, url + (temp-url+2));
    for(i = 0; i < strlen(url)-(temp-url+2); i++){
      if(!isalnum(filename[i]) && filename[i] != '.'){
	filename[i] = 'x';
      }
    }
    strcpy(current->filename, filename);
  }


  /** fetch and dump webpage **/
  {
    char command[500];
    sprintf(command, "lynx -dump -ismap -cfg=lynxrc %s > %s \n", url, filename);
    fprintf(stderr, "command: %s.\n", command);
    if((i = system(command)) < 0){
      char file[] = "wrongurl";
      perror("system"); 
      fprintf(stderr, "url is wrong format\n");
      play_sound(file);
      return -1;
    }
  }

  if(strstr(url, ".au") == url + strlen(url) - 3){
    fprintf(stderr, "sound file\n");
    play_song(filename);
    return;
  }
  /**read in webpage(file) **/
  {

    FILE *file;
    int bytes;

    if(stat(filename, &buf) != 0){
      char file[] = "wrongurl";
      perror("stat");
      fprintf(stderr, "url is wrong format\n");
      play_sound(file);
      return -1;
    }
    if(buf.st_size == 0){
      char file[] = "emptypage";
      fprintf(stderr, "empty page\n");
      play_sound(file);
      return -1;
    }
    buffer = (char*)malloc(sizeof(char)*buf.st_size);

    current->text = (char*)malloc(sizeof(char)*2*buf.st_size);
    file = fopen(filename, "rb");
    if(file == NULL){
      char file[] = "wrongurl";
      fprintf(stderr, "cannot open url file: %s\n", filename);
      play_sound(file);
      return -1;
    }
    bytes = fread(buffer, 1, buf.st_size, file);
    if(bytes != buf.st_size){
      char file[] = "wrongurl";
      perror("fread");
      play_sound(file);
      return -1;
    }
    fclose(file);
  }


  /**separate text body and links **/
  /** process text body **/
  {
    int flag = 0, flag1 = 0;
    char *back;

    back = temp = buffer;
    while((temp = strstr(buffer+(temp-buffer), "References\n\n")) > 0){
      back = temp;
      temp = temp + 12;
    }
    temp = back;

    i = 0;
    while(i < temp-buffer){
      switch(buffer[i]){

      case '[':
	{
	  current->text[counter++] = ' ';
	  if(flag==0)
	    flag = 1;
	}
      break;

      case ']':
	{
	  current->text[counter++] = ' ';	
	  if(flag > 0)
	    flag = 0;
	}
      break;

      case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
	{
	  /** get rid of number **/
	  if(flag > 0)
	    current->text[counter++] = ' ';	
	  else
	    current->text[counter++] = buffer[i];
	}
      break;
      
      case '\n':
	{
	  if(flag1 == 1)
	    current->text[counter++] = '.';	
	  flag1 = 0;
	}
	break;
      case '.':
	{
	  if(flag1 == 1)
	    flag1 = 0;
	  current->text[counter++] = buffer[i];
	}
      case '*':case '+':case '~': case '^': case '<': case '>':case '#': case '_': case '-': case '|': case '{': case '}': case '\\': case '`':
	{
	  current->text[counter++] = ' ';	
	}
	break;

      default:
	{
	  if( strstr(&(buffer[i]), "LINK") == &(buffer[i]) ){
	    int j;
	    for(j = 0; j < strlen("LINK"); j++)
	      current->text[counter++] = tolower(buffer[i++]);	      
	    current->text[counter++] = '.';
	    i--;
	  }else if( strstr(&(buffer[i]), "USEMAP") == &(buffer[i]) ){
	    int j;
	    for(j = 0; j < strlen("USEMAP"); j++)
	      current->text[counter++] = tolower(buffer[i++]);	      
	    current->text[counter++] = '.';
	    i--;
	  }else if( strstr(&(buffer[i]), "INLINE") == &(buffer[i]) ){
	    int j;
	    for(j = 0; j < strlen("INLINE"); j++)
	      current->text[counter++] = tolower(buffer[i++]);
	    current->text[counter++] = '.';
	    i--;
	  }else{
	    if(isalnum(buffer[i]))
	      flag1 = 1;
	    current->text[counter++] = buffer[i];
	  }
	}
      }

      i++;
    }
  }

  /** dump processed text body to file **/
  {
    struct stat buf;
    FILE *file;
    int bytes;
    
    file = fopen(filename, "wb");
    if(file == NULL){
      fprintf(stderr, "cannot open url file: %s\n", filename);
      exit(1);
    }
    bytes = fwrite(current->text, 1, counter, file);
    if(bytes != counter){
      char file[] = "internalerror";
      perror("fwrite");
      play_sound(file);
      return -1;
    }
    fclose(file);
  }

  /** parse all links **/
  {
    char *temp1;
    int counter = 0;

    while(temp - buffer < buf.st_size){
      temp = strstr(temp, prefix[mode]);
      if(temp == NULL)
	break;
      temp1 = strchr(temp + 4, '\n');
      if(temp1){
	char *p;
	current->linkNames[counter] = (char*)malloc(sizeof(char)*(temp1 - temp));
	strncpy(current->linkNames[counter],temp, temp1 - temp);
	current->linkNames[counter][temp1 - temp] = 0;
	if((p = strchr(current->linkNames[counter], '\n')))
	  current->linkNames[counter][p-current->linkNames[counter]] = 0;
	fprintf(stderr, "link %d: %s.\n", counter, current->linkNames[counter]);
      }else{
	char *p;
	current->linkNames[counter] = (char*)malloc(sizeof(char)*(buf.st_size - (temp - buffer)));
	strncpy(current->linkNames[counter], temp, strlen(temp));
	current->linkNames[counter][strlen(temp)] = 0;
	if((p = strchr(current->linkNames[counter], '\n')))
	  current->linkNames[counter][p-current->linkNames[counter]] = 0;
	fprintf(stderr, "link %d: %s.\n", counter, current->linkNames[counter]);
	break;
      }
      counter++;
      temp += temp1 - temp;
      if(counter >= MAXLINKS)
	break;
    }
    current->numLinks = counter - 1;
  }
  
  return play_file(current->filename);
}

URL *new_url()
{
  URL *return_val = (URL*)malloc(sizeof(URL));
  return_val->url = 0;
  return_val->text = 0;
  return_val->numLinks = -2;
  return return_val;
}

#ifndef REAL
void main()
#else
void dummy()
#endif
{
  char command[20];
  char url[200];
  NODE *list = (NODE*)malloc(sizeof(NODE));
  NODE *traverse = list;
  NODE *back;
  int i;
  traverse->back = NULL;
  traverse->next = NULL;
  traverse->url = NULL;
  current = NULL;

  for(i = 0; i < 10 ; i ++){
    history_list[i] = NULL;
    historylist_counter = 0;
  }

  thr_setconcurrency(10);

  mode = 0;

  play_sound("welcome");
  
  while(1){
    scanf("%s", command);

    if(strcmp(command, "1") == 0 || strcmp(command, "2") == 0){
      int linkNum = -1;

      kill_sound();      

      if(strcmp(command, "1") == 0){
	char file1[] = "enteringURL";
	char file2[] = "enteringFTP";
	char buffer[256];
	if(mode == 0)
	  play_sound(file1);
	else
	  play_sound(file2);
	scanf("%s", buffer);      
	strcpy(url, prefix[mode]);
	strcat(url, buffer);
	kill_sound();      
	play_url(buffer);
	sleep(3);
      }else{
	char file[] = "enteringLinkNum";
	kill_sound();      
	if(current == NULL){
	  char file1[] = "pagenotloaded";
	  play_sound(file1);
	  continue;
	}else{
	  play_sound(file);
	  scanf("%d", &linkNum);
	  kill_sound();      
	}
      }

      if( ((strcmp(command, "2") == 0) && (current!= NULL && (linkNum > current->numLinks || linkNum < 0))) ){
	char file[] = "wronglinknum";
	play_sound(file);
      }else{
	if(traverse->url == NULL){
	  traverse->url = new_url();
	  current = traverse->url;
	  insert_historylist(url);
	  goto_page(url);
	}else{
	  back = traverse;
	  if(traverse->next)
	    free_node(traverse->next);
	  traverse->next = (NODE*)malloc(sizeof(NODE));
	  traverse = traverse->next;
	  back->next = traverse;
	  traverse->back = back;
	  traverse->next = NULL;
	  
	  traverse->url = new_url();
	  current = traverse->url;
	  if(strcmp(command, "1") == 0){
	    insert_historylist(url);
	    goto_page(url);
	  }else{
	    insert_historylist(url);
	    goto_page(back->url->linkNames[linkNum]);
	  }
	}
      }

    }else if(strcmp(command, "3") == 0){
      kill_sound();      
      if(traverse->back){
	char string[] = "Going back to ";
	traverse = traverse->back;
	current = traverse->url;
	fprintf(stderr, "going back\n");
	play_page_url(current, current->url, string, 0);
      }else{
	char file[] = "cannotgoback";
	play_sound(file);
	fprintf(stderr, "cannot go back anymore\n");
      }

    }else if(strcmp(command, "4") == 0){
      kill_sound();      
      if(traverse->next){
	char string[] = "Going forward to ";
	traverse = traverse->next;
	current = traverse->url;
	fprintf(stderr, "going forward\n");
	play_page_url(current, current->url, string, 0);
      }else{
	char file[] = "cannotgoforward";
	play_sound(file);
	fprintf(stderr, "cannot go forward anymore\n");
      }

    }else if(strcmp(command, "5") == 0){
      kill_sound();      
      fprintf(stderr, "playing page again\n");
      if(current){
	if(current->text == NULL){
	  char file[] = "emptypage";
	  fprintf(stderr, "empty page\n");
	  play_sound(file);
	}else{
	  play_file(current->filename);
	}
      }
      else{
	char file[] = "pagenotloaded";
	play_sound(file);
      }

    }else if(strcmp(command, "6") == 0){
      int linkNum = -1;
      char file[] = "wronglinknum";
      kill_sound();      
      if(current){
	char string[] = " The current page is  ";
	char file[] = "enteringLinkNum";
	play_page_url(current, current->url, string, 1);
	if(current->text != NULL){
	  sleep(1);
	  play_sound(file);
	  scanf("%d", &linkNum);
	  if(linkNum > current->numLinks || linkNum < 0){
	    play_sound(file);
	  }else{
	    char string[256];
	    sprintf(string, "The %dth link of the page is ", linkNum);
	    play_page_url(current, current->linkNames[linkNum], string, 0);
	  }
	}
      }else{
	char file[] = "pagenotloaded";
	play_sound(file);
      }

    }else if(strcmp(command, "7") == 0){
      char file[] = "historylist";
      int linkNum = -1;
      fprintf(stderr, "use history list\n");
      kill_sound();      

      if(historylist_counter){
	play_history_summary();
	sleep(2);
	play_sound(file);
	scanf("%d", &linkNum);
	kill_sound();
	if(linkNum >= 0 && linkNum < historylist_counter){
	  char file[] = "usehistory";
	  char buffer[256], url[256];
	  bzero(buffer, 256);
	  play_url(history_list[linkNum]);
	  sleep(2);
	  play_sound(file);
	  scanf("%s", buffer);
	  if(strcmp(buffer, "#*") != 0){
	    kill_sound();
	    strcpy(url, history_list[linkNum]);
	    strcat(url, buffer);
	    
	    back = traverse;
	    if(traverse->next)
	      free_node(traverse->next);
	    traverse->next = (NODE*)malloc(sizeof(NODE));
	    traverse = traverse->next;
	    back->next = traverse;
	    traverse->back = back;
	    traverse->next = NULL;
	      
	    traverse->url = new_url();
	    current = traverse->url;
	    insert_historylist(url);
	    goto_page(url);
	  }
	}else{
	  char file[] = "wronghistorylinknum";
	  play_sound(file);
	}
      }else{
	char file[] = "emptyhistorylist";
	play_sound(file);
	sleep(2);
      }

    }else if(strcmp(command, "8") == 0){
      char command[256];
      kill_sound();      
      fprintf(stderr, "stop playing\n");
    }else if(strcmp(command, "9") == 0){
      char file[] = "welcome";
      kill_sound();      
      fprintf(stderr, "play help\n");
      play_sound(file);

    }else if(strcmp(command, "0") == 0){
      char file1[] = "http_to_ftp";
      char file2[] = "ftp_to_http";
      kill_sound();
      if(mode == 1){
	mode = 0;
	play_sound(file2);
      }else{
	mode = 1;
	play_sound(file1);
      }
    }else{
      char file[] = "wrongcommand";
      kill_sound();      
      fprintf(stderr, "your command is not understood\n");
      play_sound(file);
    }
  }
}


