// RAN 2015-06-26 - Added Zulu Zone label
//   - Removed the onclick functions for the buttons that are no longer used

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "secondwindow.cpp"

#include <QDebug>
#include <QtCore/qmath.h>
#include <QMessageBox>
#include "functions.h"
#include <QDesktopWidget>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    //These are the size of the arrays of widgets 'line-edit',
    //'label' and 'button'
    buttonSize = 2;
    lineSize = 7;
    labelSize = 8;

    // We set every pointer member to point NULL because we
    // when we delete every pointer we dont want to delete a
    // pointer that was already deleted in other moment or
    // was never used
    layout = NULL;
    for (int i = 0; i<buttonSize ; i++){
        button[i] = 0;
    }
    for (int i = 0; i < lineSize ; i++){
        line[i] = 0;
    }
    for (int i = 0; i<labelSize ; i++){
        label[i] = 0;
    }

    window = new secondwindow;

    QDesktopWidget desktop;


    window->move( ( desktop.screenGeometry().width() - window->width() )/2,
                 ( desktop.screenGeometry().height()- window->height() ) /2);


    // We need to know whenever the second window is closed to show the
    // main window, or to hide when the second one is showed
    connect(window, SIGNAL(cerrado(bool)), this, SLOT(mostrar(bool)));

    if(!dice1.load(":/images/resources/d1.png") || !dice2.load(":/images/resources/d1.png")){
        qDebug() << "Error1 Loading image";
    }

    initCheckWMaps();
}

MainWindow::~MainWindow()
{
    delete ui;
}

//This function show the main window and delete all the items created on the closed one or hide the mainwindow
void MainWindow::mostrar(bool si){
    if (si==true){
        show();

        // Deleting pointers and point them to NULL
        for (int i = 0; i<buttonSize ; i++){
            delete button[i];
            button[i] = NULL;
        }
        for (int i = 0; i<lineSize ; i++){
            delete line[i];
            line[i] = NULL;
        }
        for (int i = 0; i<labelSize ; i++){
            delete label[i];
            label[i] = NULL;
        }
        delete layout;
        layout = NULL;
        delete window;

        // Create the new window and connecting it again with the signal
        window = new secondwindow;

        QDesktopWidget desktop;


        window->move( ( desktop.screenGeometry().width() - window->width() )/2,
                     ( desktop.screenGeometry().height()- window->height() ) /2);


        connect(window, SIGNAL(cerrado(bool)), this, SLOT(mostrar(bool)));
    }
    else hide();
}

//It is a slot that reads what item of the combo box was selected and save it
//into a member
void MainWindow::whatOption(QString str){
    option = str;
}

//Clear all the lines that are used
void MainWindow::clearLines(){
    for (int i = 0; i < lineSize; i++){
        if (line[i] != NULL){
            line[i]->clear();
        }
    }
    score1 = score2 = 0;
}

//It forces the input 1 to be valid
void MainWindow::RPSnormalizer1(QString str){
    //For every character in the string only allow
    //the character 'R' for rock, 'P' for paper and
    //'S' for scissors. Delete all the other characters
    //different from this three, and if is 'r', 'p' or 's'
    //make it uppercase.
    for (int i = 0; i< str.size(); i++){
        if      (str[i] == 'r'){
            str[i] = 'R';
        }
        else if (str[i] == 'p'){
            str[i] = 'P';
        }
        else if (str[i] == 's'){
            str[i] = 'S';
        }

        else if (str[i] == 'R' || str[i] == 'P' ||
                 str[i] == 'S');//then its ok, do nothing
        else{
            str = str.mid(0,i).append(str.mid(i+1));
        }
    }

    line[0]->setText(str);
}

//It forces the input 2 to be valid
void MainWindow::RPSnormalizer2(QString str){
    for (int i = 0; i< str.size(); i++){
        if      (str[i] == 'r'){
            str[i] = 'R';
        }
        else if (str[i] == 'p'){
            str[i] = 'P';
        }
        else if (str[i] == 's'){
            str[i] = 'S';
        }
        else if (str[i] == 'R' || str[i] == 'P' ||
                 str[i] == 'S');//then its ok, do nothing
        else{
            str = str.mid(0,i).append(str.mid(i+1));
        }
    }

    line[1]->setText(str);
}

//It forces the input 3 to be valid
void MainWindow::RPSnormalizer3(QString str){
    //Verify that the string do not contains other thing than
    //numbers
    for (int i = 0; i< str.size(); i++){
        if (!str[i].isDigit()){
            str = str.mid(0,i).append(str.mid(i+1));
        }
    }

    //Left zeros do not count, delete them
    while (str[0] == '0'){
        str = str.mid(1);
    }

    //If the player exagerates the number of games to win
    //change the string to the maximum number allowed
    if (str.toInt() > 150){
        str = "150";
    }

    line[2]->setText(str);
}

//It forces the input to be valid
void MainWindow::CheckWnormalizer(QString str){
    //Just allow numbers
    for (int i = 0; i< str.size(); i++){
        if (!str[i].isDigit()){
            str = str.mid(0,i).append(str.mid(i+1));
        }
    }

    //Zeros on the left side do not count (delete them)
    while (str[0] == '0'){
        str = str.mid(1);
    }

    //The maximum is 999,999,999
    if (str.toDouble() > 999999999){
        str = "999999999";
    }

    line[0]->setText(str);
}



//It forces the first input of Zulu to be valid
void MainWindow::Zulunormalizer1(QString str){
    //Just allow numbers to be written
    for (int i = 0; i< str.size(); i++){
        if (!str[i].isDigit()){
            str = str.mid(0,i).append(str.mid(i+1));
        }
    }

    //The maximum here is 2359, so force it to be the
    //maximum when the user write a larger number
    if (str.toInt() > 2359){
        str = "2359";
    }

    line[0]->setText(str);
}

//It forces the second input of Zulu to be valid
void MainWindow::Zulunormalizer2(QString str){
    //Just allow one character to be written
    if (str.size() > 1){
        str = str[1];
    }

    //If that only character is 'e', 'c', 'm' or 'p'
    //the uppercase it
    if (str[0] == 'e' || str[0] == 'c' ||
            str[0] == 'm' || str[0] == 'p'){
        str = str[0].toUpper();
    }
    //If we get here is because the character is not
    //the lowercase letters allowed... so if they are
    //not the uppercase letters that we admit we have
    //to delete it.
    else if (str[0] != 'E' || str[0] != 'C' ||
             str[0] != 'M' || str[0] != 'P'){
        str = "";
    }

    line[1]->setText(str);
}

//It forces the first input of APFT to be valid
void MainWindow::APFTnormalizer1(QString str){
    //Just admit numbers, delete the other type of
    //characters
    for (int i = 0; i< str.size(); i++){
        if (!str[i].isDigit()){
            str = str.mid(0,i).append(str.mid(i+1));
        }
    }

    //Left zeros are not valid
    while (str[0] == '0'){
        str = str.mid(1);
    }

    line[0]->setText(str);
}

//It forces the second input of APFT to be valid
void MainWindow::APFTnormalizer2(QString str){
    //Just allow the numbers to be written
    for (int i = 0; i< str.size(); i++){
        if (!str[i].isDigit()){
            str = str.mid(0,i).append(str.mid(i+1));
        }
    }

    //Left-hand zeros? Delete them
    while (str[0] == '0'){
        str = str.mid(1);
    }

    line[1]->setText(str);
}

//It forces the third input of APFT to be valid
void MainWindow::APFTnormalizer3(QString str){
    //Allow just numbers on the string only if the
    //character is not in the position 2
    for (int i = 0; i< str.size(); i++){
        if (!str[i].isDigit() && i != 2){
            str = str.mid(0,i).append(str.mid(i+1));
        }
    }

    //Then if there is a character in the position 2
    //and it is not ':', then add it between the
    //position 1 and 3
    if (str.size() > 2 && str[2] != ':'){
        while (str.size()>2 && !str[2].isDigit()){
            str = str.mid(0,2).append(str.mid(3));
        }
        str = str.mid(0, 2).append(':').append(str.mid(2));
    }
    //If the size exceeds 5, then take the first five
    //so then we will have the format mm:ss
    if (str.size() > 5){
        str = str.mid(0, 5);
    }

    line[2]->setText(str);
}

//Checks which version of sort is selected and call it
void MainWindow::sorts(){
    QString a = line[0]->text();
    QString b = line[1]->text();
    QString c = line[2]->text();

    if (!validateSorts(a,b,c)) {
        QMessageBox::warning(this, "Alert",
             "Please provide the three non-empty strings");
        return;
    }

    if (option == "Version Alpha"){
        mySortAlpha(a,b,c);
    }
    else if (option == "Version Beta"){
        mySortBeta(a,b,c);
    }
    else if (option == "Version Gamma"){
        mySortGamma(a,b,c);
    }
    else{
        mySortDelta(a,b,c);
    }
    line[3]->setText(a);
    line[4]->setText(b);
    line[5]->setText(c);
}




//Checks which version of RPS is selected and call it
void MainWindow::RPSs(){

    QString p1 = this->cmbPlayer01->currentText();
    QString p2 = this->cmbPlayer02->currentText();

    if (p1.length() * p2.length() == 0) {
        QMessageBox::warning(this, "Alert",
                             "Please provide a play for both players and the number of games to win");
        return;
    }

    int winnerNum;
    if (option == "Version Alpha")
        winnerNum = RPSDelta(p1.toStdString()[0], p2.toStdString()[0]);
    else if (option == "Version Beta")
        winnerNum = RPSBeta(p1.toStdString()[0], p2.toStdString()[0]);
    else if (option == "Version Gamma")
        winnerNum = RPSGamma(p1.toStdString()[0], p2.toStdString()[0]);
    else
        winnerNum = RPSDelta(p1.toStdString()[0], p2.toStdString()[0]);

    QString st;

    qDebug() << winnerNum;

    switch(winnerNum) {
        case 1:  st = "Player 1"; break;
        case 2:  st = "Player 2"; break;
        case 0:  st = "Tie"; break;
        default: st = "Error";
    }

    line[0]->setText(st);



}

#include <QTimer>

void MainWindow::paintDice() {
    this->timerCounter++;
    int a, b;
    a = rand()%6;
    b = rand()%6;
    label[3]->setPixmap(QPixmap::fromImage(diceImages[a]));
    label[4]->setPixmap(QPixmap::fromImage(diceImages[b]));
    if (this->timerCounter == 10) {
        aTimer->stop();
        diceFinal01 = a;
        diceFinal02 = b;
        if (option == "Version Alpha")
            diceAlpha();
        else if (option == "Version Beta")
            diceBeta();
        else if (option == "Version Gamma")
            diceGamma();
        else
            diceAlpha();
    }
}

//Checks which version of dice is selected and call it
void MainWindow::dices(){
    // [rafa] Voy a hacer la animación aqui



    for (int i = 1; i <= 6; i++)
        this->diceImages.push_back(QImage(":/images/resources/d" + QString::number(i) + ".png"));


    aTimer = new QTimer;
    aTimer->setInterval(100);
    aTimer->setSingleShot(false);
    aTimer->start();
    timerCounter = 0;
    QObject::connect(aTimer,&QTimer::timeout, this, &MainWindow::paintDice); //[&](){ birth(w, juana, avelardo, piolin);});


}


//Checks which version of check-writer is selected and call it
void MainWindow::checkWs(){
    unsigned int qty;
    if (!validateCheckQty(line[0]->text(),qty)) {
        QMessageBox::warning(this, "Alert",
                             "Enter a valid amount!");
    }

    if (option == "Version Alpha")
        line[1]->setText( checkWAlpha(qty) );
    else if (option == "Version Beta")
        line[1]->setText( checkWBeta(qty) );
    else if (option == "Version Gamma")
        line[1]->setText( checkWGamma(qty) );
    else
        line[1]->setText( checkWDelta(qty) );
}

//Checks which version of zulu is selected and call it
void MainWindow::zulus(){
    QString zuluTime = line[0]->text();
    QString zuluZone = line[1]->text();
    int hours, minutes;

    if (!validZuluTime(zuluTime, zuluZone, hours, minutes) ) {

        QMessageBox::warning(this, "Alert",
                             "Either Zulu Time or Zone is not valid");
        line[2]->setText("Error");
        return;
    }
    if (option == "Version Alpha")
        line[2]->setText( zuluAlpha(hours, minutes, zuluZone.toStdString()[0]) );
    else if (option == "Version Beta")
        line[2]->setText( zuluBeta(hours, minutes, zuluZone.toStdString()[0]) );
    else if (option == "Version Gamma")
        line[2]->setText( zuluGamma(hours, minutes, zuluZone.toStdString()[0]) );
    else
        line[2]->setText( zuluDelta(hours, minutes, zuluZone.toStdString()[0]) );

}

//Checks which version of APFT is selected and call it
void MainWindow::APFTs(){
    if (option == "Version Alpha"){
        APFTAlpha();
    }
    else if (option == "Version Beta"){
        APFTBeta();
    }
    else if (option == "Version Gamma"){
        APFTGamma();
    }
    else{
        APFTDelta();
    }
}

//Here is what happend when Sort-button is clicked
void MainWindow::on_SortsButton_clicked()
{
    //Create a new QComboBox and add the items in it
    method = new QComboBox;
    method->addItem("Version Alpha");
    method->addItem("Version Beta");
    method->addItem("Version Gamma");
    method->addItem("Version Delta");
    option = "Version Alpha"; //Default option is alpha

    //We create a new layout and insert the comboBox to it
    layout = new QGridLayout;
    layout->addWidget(method, 0, 0, 1, -1);

    //The buttons needed are sort and clear so we create them
    button[0] = new QPushButton("Sort");
    button[1] = new QPushButton("Clear");

    //3 lines for input and 3 for output
    for (int i = 0; i<6 ; i++){
        line[i] = new QLineEdit;
    }

    //The user is not able to write on the output lines
    line[3]->setEnabled(false);
    line[4]->setEnabled(false);
    line[5]->setEnabled(false);

    //Labels to let the user understand the app
    label[0] = new QLabel("Input");
    label[1] = new QLabel("Output");

    //Here we insert the widgets on the layout
    layout->addWidget(label[0], 1, 0);
    layout->addWidget(label[1], 1, 2);
    layout->addWidget(line[0], 2, 0);
    layout->addWidget(line[1], 3, 0);
    layout->addWidget(line[2], 4, 0);
    layout->addWidget(button[0], 1, 1, 2, 1);
    layout->addWidget(button[1], 3, 1, 2, 1);
    layout->addWidget(line[3], 2, 2);
    layout->addWidget(line[4], 3, 2);
    layout->addWidget(line[5], 4, 2);

    //Here we connect the signals of the widgets generated
    //by code to their respective functions
    connect(method, SIGNAL(currentIndexChanged(QString)), this, SLOT(whatOption(QString)));
    connect(button[0], SIGNAL(clicked()), this, SLOT(sorts()));
    connect(button[1], SIGNAL(clicked()), this, SLOT(clearLines()));

    //Now that we have set our new window, we hide the main-window
    //and show the new one. The new-window has a signal that
    //notify when it was closed so we can shor the main-window
    window->setLayout(layout);
    mostrar(false);

    QDesktopWidget desktop;


    window->move( ( desktop.screenGeometry().width() - window->width() )/2,
                 ( desktop.screenGeometry().height()- window->height() ) /2);

    window->show();
}

//Here is what happend when Dice-button is clicked
void MainWindow::on_DiceButton_clicked()
{
    //Create a new QComboBox and add the items in it
    method = new QComboBox;
    method->addItem("Version Alpha");
    method->addItem("Version Beta");
    method->addItem("Version Gamma");
    method->addItem("Version Delta");
    option = "Version Alpha"; //Default option is alpha

    //We create a new layout and insert the comboBox to it
    layout = new QGridLayout;
    layout->addWidget(method, 0, 0, 1, -1);

    //Labels to let the user understand the app
    label[0] = new QLabel("Dice 1");
    label[1] = new QLabel("Dice 2");
    label[2] = new QLabel("Total");

    //The user is not able to write on the output line
    line[0] = new QLineEdit;
    line[0]->setEnabled(false);

    //Here we just need one button to roll the dices
    button[0] = new QPushButton("Roll them!");

    //Labels to put the dices' images on them
    label[3] = new QLabel;
    label[4] = new QLabel;
    label[3]->setPixmap(QPixmap::fromImage(dice1));
    label[4]->setPixmap(QPixmap::fromImage(dice2));

    //Here we insert the widgets on the layout
    layout->addWidget(label[0], 1, 0);
    layout->addWidget(label[3], 1, 1);
    layout->addWidget(label[1], 2, 0);
    layout->addWidget(label[4], 2, 1);
    layout->addWidget(label[2], 3, 0);
    layout->addWidget(line[0], 3, 1);
    layout->addWidget(button[0], 1, 2, 2, 1);

    //Here we connect the signals of the widgets generated
    //by code to their respective functions
    connect(method, SIGNAL(currentIndexChanged(QString)), this, SLOT(whatOption(QString)));
    connect(button[0], SIGNAL(clicked()), this, SLOT(dices()));

    //Now that we have set our new window, we hide the main-window
    //and show the new one. The new-window has a signal that
    //notify when it was closed so we can shor the main-window
    window->setLayout(layout);
    mostrar(false);
    window->show();
}

//Here is what happend when RPS-button is clicked
void MainWindow::on_RPSButton_clicked()
{
    //Create a new QComboBox and add the items in it
    method = new QComboBox;
    method->addItem("Version Alpha");
    method->addItem("Version Beta");
    method->addItem("Version Gamma");
    method->addItem("Version Delta");
    option = "Version Alpha"; //Default option is alpha

    cmbPlayer01 = new QComboBox;
    cmbPlayer02 = new QComboBox;
    cmbPlayer01->addItem("rock");       cmbPlayer02->addItem("rock");
    cmbPlayer01->addItem("paper");      cmbPlayer02->addItem("paper");
    cmbPlayer01->addItem("scisors");    cmbPlayer02->addItem("scisors");





    //The buttons needed here are the 'play' and 'clear' buttons
    button[0] = new QPushButton("Play");
//    button[1] = new QPushButton("Clear");

    //3 inputs and 1 output
//    for (int i = 0; i<4; i++){
//        line[i] = new QLineEdit;
//    }
    line[0] = new QLineEdit;
    //The user is not able to write on the output line
    line[0]->setEnabled(false);

    //Labels to let the user understand the app
    label[0] = new QLabel("Player 1's moves");
    label[1] = new QLabel("Player 2's moves");
//    label[2] = new QLabel("How many games to win:");
    label[2] = new QLabel("Winner:");
//    label[4] = new QLabel("Tournament:");
//    //lines for score
//    line[4] = new QLineEdit;
//    line[4]->setEnabled(false);


    //We create a new layout and insert the comboBox to it
    int row = 0;
    layout = new QGridLayout;
    layout->addWidget(method,       row++, 0);
    layout->addWidget(label[0],     row, 0);
    layout->addWidget(cmbPlayer01,  row++, 1);
    layout->addWidget(label[1],     row, 0);
    layout->addWidget(cmbPlayer02,  row++, 1);
    layout->addWidget(button[0],    row++, 1);
    layout->addWidget(line[0],      row, 1);
    layout->addWidget(label[2],      row++, 0);


    //Here we connect the signals of the widgets generated
    //by code to their respective functions
    connect(method, SIGNAL(currentIndexChanged(QString)), this, SLOT(whatOption(QString)));
    connect(button[0], SIGNAL(clicked()), this, SLOT(RPSs()));

    //Now that we have set our new window, we hide the main-window
    //and show the new one. The new-window has a signal that
    //notify when it was closed so we can shor the main-window
    window->setLayout(layout);
    mostrar(false);
    window->show();
//    score1 = score2 = 0;
}



//Here is what happend when Zulu-button is clicked
void MainWindow::on_ZuluButton_clicked()
{
    //Create a new QComboBox and add the items in it
    method = new QComboBox;
    method->addItem("Version Alpha");
    method->addItem("Version Beta");
    method->addItem("Version Gamma");
    method->addItem("Version Delta");
    option = "Version Alpha"; //Default option is alpha

    //We create a new layout and insert the comboBox to it
    layout = new QGridLayout;
    layout->addWidget(method, 0, 0, 1, -1);

    //Labels to let the user understand the app
    label[0] = new QLabel("Zulu time:");
    label[1] = new QLabel("Standard time");
    label[2] = new QLabel("Zulu zone:");

    //Just the buttons to clear and convert the time
    button[0] = new QPushButton("Clear");
    button[1] = new QPushButton("Convert");

    //2 inputs and 1 output
    for (int i = 0; i<3; i++){
        line[i] = new QLineEdit;
    }

    //The user is not able to write on the output line
    line[2]->setEnabled(false);

    //Here we insert the widgets on the layout
    layout->addWidget(label[0], 1, 0);
    layout->addWidget(label[2], 1, 1);
    layout->addWidget(line[0], 2, 0);
    layout->addWidget(line[1], 2, 1);
    layout->addWidget(button[0], 3, 0);
    layout->addWidget(button[1], 3, 1);
    layout->addWidget(label[1], 4, 0);
    layout->addWidget(line[2], 4, 1);

    //Here we connect the signals of the widgets generated
    //by code to their respective functions
    connect(method, SIGNAL(currentIndexChanged(QString)), this, SLOT(whatOption(QString)));
    connect(button[0], SIGNAL(clicked()), this, SLOT(clearLines()));
    connect(button[1], SIGNAL(clicked()), this, SLOT(zulus()));

    // Rafa 2014-09-16 - Validation will be done when button is clicked
    //    connect(line[0], SIGNAL(textEdited(QString)), this, SLOT(Zulunormalizer1(QString)));
    //    connect(line[1], SIGNAL(textEdited(QString)), this, SLOT(Zulunormalizer2(QString)));

    //Now that we have set our new window, we hide the main-window
    //and show the new one. The new-window has a signal that
    //notify when it was closed so we can shor the main-window
    window->setLayout(layout);
    mostrar(false);
    window->show();
}
