#include "connectortoserver.h"
#include <QThread>

ConnectorToServer::ConnectorToServer(QObject *parent) :
    QObject(parent),
    connectionThread(nullptr),
    client(nullptr),
    dataParser(nullptr),
    sendSystem(nullptr),
    recognizeSystem(nullptr),
    versionSelectWidget(nullptr),
    versionContainer(nullptr),
    notifyController(nullptr),
    waitAnimationWidget(nullptr)
{
    initialize();
}

bool ConnectorToServer::authorizationInstructorLocal(QString login, QString password)
{
    if (!client->getIsConnected())
    {
        return false;
    }

    ClientAutorization *autorization = new ClientAutorization;
    autorization->Login = login;
    autorization->Password = password;
    autorization->TypeClient = TypeClientAutorization::TYPE_GUI;

    QByteArray array = dataParser->createAuthMessage(autorization);
    emit signal_sendXMLmsgGUItoServer(array);

    return true;
}

bool ConnectorToServer::deAuthorizationInstructorLocal(QString login)
{
    if (!client->getIsConnected())
    {
        return false;
    }

    ClientDeAutorization *deAutorization = new ClientDeAutorization;
    deAutorization->Login = login;

    QByteArray array = dataParser->createDeAuthMessage(deAutorization);
    emit signal_sendXMLmsgGUItoServer(array);

    return true;
}

bool ConnectorToServer::sendQueryToDB(TypeQueryToDB typeQuery, int id, void* data)
{
    if (!client->getIsConnected())
    {
        return false;
    }

    ClientQueryToDB *queryToDB = new ClientQueryToDB;
    queryToDB->typeQuery = typeQuery;

    QByteArray array = dataParser->createQueryToDBMessage(queryToDB, id, data);
    emit signal_sendXMLmsgGUItoServer(array);

    return true;
}

bool ConnectorToServer::sendMessageForClient(int id, QString login, QString text)
{
    if (!client->getIsConnected())
    {
        return false;
    }

    ToClientMessage *toClientMessage = new ToClientMessage;
    toClientMessage->id = id;
    toClientMessage->Login = login;
    toClientMessage->Text = text;

    QByteArray array = dataParser->createToClientMessage(toClientMessage);
    emit signal_sendXMLmsgGUItoServer(array);

    return true;
}

bool ConnectorToServer::sendQueryTasksXML(QString type)
{
    if (!client->getIsConnected())
    {
        return false;
    }

    QByteArray array = dataParser->createQueryTasksXMLMessage(type);
    emit signal_sendXMLmsgGUItoServer(array);

    return true;
}

void ConnectorToServer::setLoginName(QString name)
{
    versionSelectWidget->setAuthor(name);
}

void ConnectorToServer::SetConnectToServer()
{
    emit sigSetConnect(dataParser->getServerSettings(),connectionThread);

}

QByteArray ConnectorToServer::getListTaskFimArray()
{
    return listTaskFimArray;
}

QByteArray ConnectorToServer::getListTaskAmmArray()
{
    return listTaskAmmArray;
}

QList<Instructor> ConnectorToServer::getListInstructors()
{
    return listInstructors;
}

QList<Trainee> ConnectorToServer::getListTrainees()
{
    return listTrainees;
}

QList<Group> ConnectorToServer::getListGroups()
{
    return listGroups;
}

QList<Computer> ConnectorToServer::getListComputers()
{
    return  listComputers;
}

QList<Classroom> ConnectorToServer::getListClassrooms()
{
    return listClassrooms;
}

QList<Task> ConnectorToServer::getListTasks()
{
    return listTasks;
}

bool ConnectorToServer::isArchivedInstructor(int id)
{
    for(Instructor instructor : listInstructors)
    {
        if(instructor.getID() == id)
        {
            if(instructor.getArchived()) return true; else return false;
        }
    }
    return false;
}

bool ConnectorToServer::isAdminInstructor(int id)
{
    for(Instructor instructor : listInstructors)
    {
        if(instructor.getID() == id)
        {
            if(instructor.getIsAdmin()) return true; else return false;
        }
    }
    return false;
}

bool ConnectorToServer::isLoggedInInstructor(int id)
{
    for(Instructor instructor : listInstructors)
    {
        if(instructor.getID() == id)
        {
            if(instructor.getLoggedIn()) return true; else return false;
        }
    }
    return false;
}

Instructor ConnectorToServer::getInstructor(int id)
{
    for(Instructor instructor : listInstructors)
    {
        if(instructor.getID() == id)
            return instructor;
    }
    return Instructor();
}

QList<Trainee> ConnectorToServer::getListTraineesInGroup(int id)
{
    QList<Trainee> list;
    for(Trainee trainee : listTrainees)
    {
        if(trainee.getGroup().getID() == id)
            list.append(trainee);
    }
    return list;
}

bool ConnectorToServer::isArchivedTrainee(int id)
{
    for(Trainee trainee : listTrainees)
    {
        if(trainee.getID() == id)
        {
            if(trainee.getArchived()) return true; else return false;
        }
    }
    return false;
}

bool ConnectorToServer::isLoggedInTrainee(int id)
{
    for(Trainee trainee : listTrainees)
    {
        if(trainee.getID() == id)
        {
            if(trainee.getLoggedIn()) return true; else return false;
        }
    }
    return false;
}

Trainee ConnectorToServer::getTrainee(int id)
{
    for(Trainee trainee : listTrainees)
    {
        if(trainee.getID() == id)
            return trainee;
    }
    return Trainee();
}

Group ConnectorToServer::getGroup(int id)
{
    for(Group group : listGroups)
    {
        if(group.getID() == id)
            return group;
    }
    return Group();
}

int ConnectorToServer::getIdTraineeByLogin(QString login)
{
    for(Trainee trainee : listTrainees)
    {
        if(trainee.getLogin() == login)
            return trainee.getID();
    }
    return 0;
}

void ConnectorToServer::showVersionSelect()
{
    QByteArray answer = dataParser->xmlAnswer_notify(cmd_CheckVersionList);
    emit sigSendAnswerToServer(answer);
}

/*
void ConnectorToServer::slot_AnswerQueryToDB(QList<Instructor>* listInstructors,
                                             QList<Trainee>* listTrainees,
                                             QList<Group>* listGroups)
{
    this->listInstructors = *listInstructors;
    this->listTrainees = *listTrainees;
    this->listGroups = *listGroups;
    emit signal_UpdateDB(true, true);
}*/

void ConnectorToServer::slot_AnswerQueryToDB_ListInstructors(QList<Instructor> listInstructors)
{
    this->listInstructors = listInstructors;
    emit signal_UpdateDB(true, false);
}

void ConnectorToServer::slot_AnswerQueryToDB_ListGroups(QList<Group> listGroups)
{
    this->listGroups = listGroups;
    emit signal_UpdateDB(false, true);
}

void ConnectorToServer::slot_AnswerQueryToDB_ListTrainees(QList<Trainee> listTrainees)
{
    this->listTrainees = listTrainees;
    emit signal_UpdateDB(false, true);
    emit signal_InitMessanger(listTrainees);
}

void ConnectorToServer::slot_AnswerQueryToDB_ListComputers(QList<Computer> listComputers)
{
    this->listComputers = listComputers;
    //emit signal_UpdateDB(false, true);
}

void ConnectorToServer::slot_AnswerQueryToDB_ListClassrooms(QList<Classroom> listClassrooms)
{
    this->listClassrooms = listClassrooms;
    //emit signal_UpdateDB(false, true);
}

void ConnectorToServer::slot_AnswerQueryToDB_ListTasks(QList<Task> listTasks)
{
    this->listTasks = listTasks;
    //emit signal_UpdateDB(false, true);
}

void ConnectorToServer::slot_AnswerQueryTasksXML_FIM(QByteArray array)
{
    this->listTaskFimArray = array;
    emit signal_UpdateTasksFIM();
}

void ConnectorToServer::slot_AnswerQueryTasksXML_AMM(QByteArray array)
{
    this->listTaskAmmArray = array;
    emit signal_UpdateTasksAMM();
}

void ConnectorToServer::slot_msgToClientReady(QString login, QString text)
{
    int id = getIdTraineeByLogin(login);
    if(id)
        sendMessageForClient(id, login, text);
}

void ConnectorToServer::showServerList(QList<StreamingVersionData *> *serverList)
{
    versionSelectWidget->fillView(serverList);
}

void ConnectorToServer::initialize()
{
    createObjects();

    bindConnection();

    emit sigInitializeClient(recognizeSystem,sendSystem,connectionThread);

    emit sigSetConnect(dataParser->getServerSettings(),connectionThread);

//    QByteArray answer = dataParser->xmlAnswer_notify()
//    sendSystem->sendXMLAnswer()

}

void ConnectorToServer::activateLoadAnimation(bool flag)
{
    if (flag)
    {
        waitAnimationWidget->showWithPlay();
    }
    else
    {
        waitAnimationWidget->hideWithStop();
    }
}

void ConnectorToServer::bindConnection()
{
    connect(this,&ConnectorToServer::sigInitializeClient,client,&TCPClient::initialize,Qt::AutoConnection);
    connect(this,&ConnectorToServer::sigSetConnect,client,&TCPClient::setConnect,Qt::AutoConnection);
    connect(this,&ConnectorToServer::signal_sendXMLmsgGUItoServer,sendSystem,&SendSystem::sendXMLmsgGUItoServer);
    connect(this,&ConnectorToServer::sigSendAnswerToServer,sendSystem,&SendSystem::sendXMLAnswer,Qt::AutoConnection);

    connect(recognizeSystem,&RecognizeSystem::sigAuth,this,&ConnectorToServer::sigLoginResult);
    connect(recognizeSystem,&RecognizeSystem::sigDeAuth,this,&ConnectorToServer::sigDeLoginResult);
    connect(recognizeSystem,&RecognizeSystem::signal_MessageForGUI,this,&ConnectorToServer::signal_msgFromClientReady);
    connect(recognizeSystem,&RecognizeSystem::sigShowServerDataList,this,&ConnectorToServer::showServerList);
    connect (recognizeSystem,&RecognizeSystem::sigSetVersion,versionContainer,&VersionContainer::setServerVersionData);
    //connect(recognizeSystem,&RecognizeSystem::sigAnswerQueryToDB,this,&ConnectorToServer::slot_AnswerQueryToDB);

    connect(recognizeSystem,&RecognizeSystem::sigAnswerQueryToDB_ListInstructors,this,&ConnectorToServer::slot_AnswerQueryToDB_ListInstructors);
    connect(recognizeSystem,&RecognizeSystem::sigAnswerQueryToDB_ListGroups,this,&ConnectorToServer::slot_AnswerQueryToDB_ListGroups);
    connect(recognizeSystem,&RecognizeSystem::sigAnswerQueryToDB_ListTrainees,this,&ConnectorToServer::slot_AnswerQueryToDB_ListTrainees);
    connect(recognizeSystem,&RecognizeSystem::sigAnswerQueryToDB_ListComputers,this,&ConnectorToServer::slot_AnswerQueryToDB_ListComputers);
    connect(recognizeSystem,&RecognizeSystem::sigAnswerQueryToDB_ListClassrooms,this,&ConnectorToServer::slot_AnswerQueryToDB_ListClassrooms);
    connect(recognizeSystem,&RecognizeSystem::sigAnswerQueryToDB_ListTasks,this,&ConnectorToServer::slot_AnswerQueryToDB_ListTasks);

    connect(recognizeSystem,&RecognizeSystem::sigAnswerQueryTasksXML_FIM,this,&ConnectorToServer::slot_AnswerQueryTasksXML_FIM);
    connect(recognizeSystem,&RecognizeSystem::sigAnswerQueryTasksXML_AMM,this,&ConnectorToServer::slot_AnswerQueryTasksXML_AMM);
    connect(recognizeSystem,&RecognizeSystem::sigAnimationActivated,this,&ConnectorToServer::activateLoadAnimation,Qt::AutoConnection);

    connect(client,&TCPClient::signal_ConnectedToServer,this,&ConnectorToServer::signal_ConnectedToServer,Qt::AutoConnection);

    connect(recognizeSystem,&RecognizeSystem::sigNotify,notifyController,&NotifyController::showWarning,Qt::AutoConnection);
}

void ConnectorToServer::createObjects()
{
    connectionThread = new QThread;

    client = new TCPClient;
    client->moveToThread(connectionThread);

    dataParser = new DataParser;

    waitAnimationWidget = new WaitAnimationWidget;

    sendSystem = new SendSystem;
    sendSystem->moveToThread(connectionThread);

    recognizeSystem = new RecognizeSystem;
    recognizeSystem->moveToThread(connectionThread);

    notifyController = new NotifyController;
    versionContainer = new VersionContainer;
    versionSelectWidget = new VersionSelectWidget;
    versionSelectWidget->initialize(sendSystem,versionContainer,notifyController);

    QMovie *movie = new QMovie(":/resources/icons/762.gif");

    waitAnimationWidget->setParent(versionSelectWidget);
    waitAnimationWidget->initialize(movie,versionSelectWidget);
    waitAnimationWidget->moveToThread(connectionThread);

    connectionThread->start();
    connectionThread->setPriority(QThread::HighestPriority);
}
