#include <iostream>
#include <string>
#include "list.h"
#include "Iterator.h"
#include "SortedSLL.h"
#include "list_test.h"

using namespace std;
using namespace uprm_icom4035;

int main() {
  int opt;
  list* L = make_list();
  
  cout << "Welcome to the Sorted Singly Linked List Test Program." << endl;
  do{
    print_menu();
    opt = get_option();
    cout << "Option entered: " << opt << endl;
    switch(opt){
    case LIST_INSERT:
      list_insert(L);
      break;
    case LIST_FIND:
      list_find(L);
      break;
    case LIST_FIRST:
      list_first(L);
      break;
    case LIST_ERASE:
      list_erase(L);
      break;
    case LIST_SIZE:
      list_size(L);
      break;
    case LIST_ISEMPTY:
      list_isempty(L);
      break;
    case LIST_MEMPTY:
      list_mempty(L);
      break;
    case LIST_PRINT:
      list_print(L);
      break;
    case LIST_DUP:
      list_dup(L);
      break;
    case LIST_EXIT:
      break;
    default:
      cout << "Unknown option: " << opt << endl;
    }
  }
  while(opt != LIST_EXIT);
  cout << "Thanks for using the SortedSLL test program." << endl;
  exit(0);
}

list *make_list(){
  return new SortedSLL();
}
void print_menu(){
  cout << "***************************" << endl;
  cout << "Available Operations:"<< endl;
  cout << "\t 1. Insert" << endl;
  cout << "\t 2. Find" << endl;
  cout << "\t 3. First" << endl;
  cout << "\t 4. Erase" << endl;
  cout << "\t 5. Size" << endl;
  cout << "\t 6. Check Empty List" << endl;
  cout << "\t 7. Make Empty List" << endl;
  cout << "\t 8. Print List" << endl;
  cout << "\t 9. Duplicate List " << endl;
  cout << "\t 10. Exit" << endl;
}

int get_option(){
  string data_in, eof;
  char c[1024];

  cout << "Enter your option number: ";
  cin >> data_in;
  
  cin.getline(c, 1024);
  
  if (data_in == "1"){
    return LIST_INSERT;
  }
  else if (data_in == "2"){
    return LIST_FIND;
  }
  else if (data_in == "3"){
    return LIST_FIRST;
  }
  else if (data_in == "4"){
    return LIST_ERASE;
  }
  else if (data_in == "5"){
    return LIST_SIZE;
  }
  else if (data_in == "6"){
    return LIST_ISEMPTY;
  }
  else if (data_in == "7"){
    return LIST_MEMPTY;
  }
  else if (data_in == "8"){
    return LIST_PRINT;
  }
  else if (data_in == "9"){
    return LIST_DUP;
  }
  else if (data_in == "10"){
    return LIST_EXIT;
  }
  else {
    return -1;
  }
}

void list_insert(list *L){
  string obj;
  
  cout << "Enter the value to be inserted: ";
  cin >> obj;
  L->insert(obj);
  cout << "Object " << obj << " was inserted." << endl;
  
}

void list_find(list *L){
  string obj;
  
  cout << "Enter the element to be found: ";
  cin >> obj;
  Iterator *iter = L->find(obj);
  if (iter->has_data()){
    cout << "Object " << iter->get_data() << " was found." << endl;
  }
  else {
    cout << "Object " << obj << " was not found." << endl;
  }
}

void list_first(list *L){
  Iterator *iter = L->first();
  if (iter->has_data()){
    cout << "The first element in the list is: " << iter->get_data() << endl;
  }
  else {
    cout << "There is not first element since the list is empty." << endl;
  }
}

void list_erase(list *L){
  string obj;
  
  cout << "Enter the object to be erased: ";
  cin >> obj;
  
  if (L->erase(obj)){
    cout << "The first copy of object " << obj << " has been erased." << endl;
  }
  else {
    cout << "The object " << obj << " was not erased because it " <<
      " was not found." << endl;
  }
}

void list_size(list *L){
  list::size_type len = 0;
  len = L->size();
  cout << "The current list size is: " << len << endl;
}

void list_isempty(list *L){
  bool empty = false;

  empty = L->is_empty();
  if (empty){
    cout << "The list is empty." << endl;
  } 
  else {
    cout << "The list is not empty." << endl;
  }
}

void list_mempty(list *L){
  L->make_empty();
  cout << "The list has been cleared of all object." << endl;
}

void list_print(list *L){
  cout << "The elements in the list are: " << endl;
  L->print_list(cout);
}

void list_dup(list *L){
  cout << "Duplicating the list:" << endl;
  L->print_list(cout);
  list *L2 = new SortedSLL(*((SortedSLL *)L));
  cout << "The data in the duplicated list is : " << endl;
  L2->print_list(cout);

}
