#include <cstdlib>
#include <cstdio>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <termios.h>
#include "questions.h"
#include <cstdlib>
#include <ctime>
#include<stdint.h>
#include <sys/time.h>
namespace Questions{
Question Deck::create_question(std::ostream &os , std::istream &in ){
struct termios stored_settings;
struct termios new_settings;
std::string input_q, input_a;
char keystroke;
os << "Please Enter your question below \n Enter <esc> when finished" << std::endl;
os << "==================================================================" << std::endl;
tcgetattr(0,&stored_settings);
new_settings = stored_settings;
new_settings.c_lflag &= (~ICANON);
new_settings.c_cc[VTIME] = 0;
new_settings.c_cc[VMIN] = 1;
tcsetattr(0,TCSANOW,&new_settings);
while( in.get(keystroke) ){
if (keystroke == 27)
break;
input_q += keystroke;
}
os << "Please Enter your answer below \n Enter <esc> when finished" << std::endl;
os << "==================================================================" << std::endl;
while( in.get(keystroke) ){
if (keystroke == 27)
break;
input_a += keystroke;
}
Question quest(input_q, input_a);
tcsetattr(0,TCSANOW,&stored_settings);
return quest;
}
void Deck::add_questions(Question &enter){
Deck tmp;
int pos;
std::ofstream all_quest( tmp.database.c_str(), std::ios::binary|std::ios::app );
if(!all_quest){
std::cerr << "can't open question database for writing" << std::endl;
exit(1);
}
all_quest.seekp( 0, std::ios_base::end);
pos = all_quest.tellp();
std::cout << "We are at Pos ==>" << pos << std::endl;
std::cout << "value of enter.quest ============> \n\n" << enter.quest << "Size of string\n" << sizeof(char) *enter.quest.size() << std::endl;
all_quest.write(enter.quest.c_str(), sizeof(char) * enter.quest.size() );
all_quest.write(enter.answer.c_str(), sizeof(char) * enter.answer.size() );
all_quest.close();
return;
}
void Deck::fresh_deck(){
unsigned int index = 0;
char buf[4096];
deck.resize(25);
std::ifstream fetch_questions( this->database.c_str(), std::ios::binary|std::ios::app );
if(!fetch_questions){
std::cerr << "can't open question database for reading" << std::endl;
exit(1);
}
for( index = 0; index < deck.size(); index++){
if(fetch_questions){
fetch_questions.read(buf, 4096 );
this->pos = fetch_questions.tellg();
std::cout << "POS IS " << pos << std::endl;
this->deck[index].quest = buf ;
}
if(fetch_questions){
fetch_questions.read(buf, 4096 );
this->pos = fetch_questions.tellg();
std::cout << "POS IS " << pos << std::endl;
this->deck[index].answer = buf;
}else{
deck.resize(index);
}
}
fetch_questions.close();
}
void Deck::fill_deck(){
unsigned int index = deck.size();
char buf[4096];
deck.resize(25);
std::ifstream fetch_questions( this->database.c_str(), std::ios::binary|std::ios::app );
if(!fetch_questions){
std::cerr << "can't open question database for reading" << std::endl;
exit(1);
}
fetch_questions.seekg(this->pos);
std::cout << "POS IS " << pos << std::endl;
for( ; index < deck.size(); index++){
if(fetch_questions){
std::cout << "We are fetching new questions" << std::endl;
fetch_questions.read(buf, 4096 );
this->pos = fetch_questions.tellg();
this->deck[index].quest = buf ;
}
if(fetch_questions){
fetch_questions.read(buf, 4096 );
this->pos = fetch_questions.tellg();
this->deck[index].answer = buf;
}else{
std::cout << "We are resizing the deck" << std::endl;
deck.resize(index);
}
}
}
void Deck::shuffle(){
timeval tmpseed;
uintmax_t seed;
unsigned int index;
std::vector<Question> tmp;
int ran;
gettimeofday(&tmpseed, NULL);
seed = (tmpseed.tv_sec * 1000000) + tmpseed.tv_usec;
std::string const line = "___________________________________________________________________________\n\n\n\n";
srand(seed);
std::vector<Question>::iterator place;
std::vector<Question>::iterator card;
place = tmp.begin();
std::cout << "DUMP DATABASE" << std::endl;
for(index = 0; index < deck.size(); index++){
std::cout << "SET # " << index << "\n" << deck[index].quest << std::endl;
std::cout << deck[index].answer << std::endl;
std::cout << line << std::endl;
}
while(deck.size() > 0){
ran = rand();
index = ran % deck.size();
card = deck.begin();
card = card + index;
place = tmp.begin();
tmp.insert(place, *card);
deck.erase(card);
std::cout << "tmp size " << tmp.size() << std::endl;
}
deck = tmp;
}
void Deck::give_quiz(std::istream &in, std::ostream &os){
unsigned int index;
char keep;
std::vector<Question>::iterator card;
std::string const line = "___________________________________________________________________________\n\n\n\n";
this->shuffle();
card = deck.begin();
index = 0;
os << "DUMP DATABASE" << " Deck Size " << deck.size() << std::endl;
for(index = 0; index < deck.size(); index++){
os << "SET # " << index << "\n" << deck[index].quest << std::endl;
os << deck[index].answer << std::endl;
os << line << std::endl;
}
index = 0;
while(deck.size() > 0){
os << deck[index].quest << line << std::endl;
in >> deck[index].response;
os << deck[index].answer << line << std::endl;
os << "Keep (k) or Dump (d)";
in >> keep;
if(keep == 'd'){
deck.erase(card);
card = deck.begin();
if( (deck.size() < 5) && (this->pos > 0 ) ) {
os << "Refilling deck. POS is ==> " << this->pos << std::endl;
this->fill_deck();
this->shuffle();
}
}
if(keep == 'k'){
card = deck.end();
deck.insert(card, *( deck.begin() ) );
card = deck.begin();
deck.erase(card);
card = deck.begin();
}
}
this->pos = 1;
}
void menu(std::ostream &os){
os << "Welcome the the C++ Quiz" << "\n\n\n\n" << std::endl;
std::string tmp = " \n "
"Select from one of the following: \n\n"
"a) Insert Question and Answer into the database\n"
"b) Read 25 Questions and run Quiz\n"
"c) End Program\n\nResponse==> \n\n\n";
os << tmp;
}
int selection(Deck &stack, std::ostream &os, std::istream &is) {
char choice;
Question tmp;
if(is >> choice){
switch ( choice ) {
case 'a':
tmp = stack.create_question();
stack.add_questions(tmp);
break;
case 'b':
std::cout << "CASE B" << std::endl;
stack.fresh_deck();
stack.give_quiz();
break;
case 'c':
os << "Bye .. " << std::endl;
return -99;
break;
default:
os << "Incorrect Choise: " << std::endl;
Questions::menu();
Questions::selection(stack);
break;
}
}
return 99;
}
}