#include "AdvFitCommand.hh"

const string AdvFitCommand::className=string("AdvFitCommand");

/** constructor */
AdvFitCommand::AdvFitCommand() {
#ifdef USE_PTHREAD
    //this->mutex = PTHREAD_MUTEX_INITIALIZER;
    pthread_mutex_init( &(this->mutex), NULL);
    //this->gurad = PTHREAD_COND_INITIALIZER;
    pthread_cond_init( &(this->guard), NULL);
    this->writeFlag = false;
    this->readFlag = false;
#endif //  USE_PTHREAD
}

/** destructor */
AdvFitCommand::~AdvFitCommand() {
}

/** set continue command */
void AdvFitCommand::setContinue() {
    string memberName=string("setContinue()");
#ifdef USE_PTHREAD
    pthread_mutex_lock( &(this->mutex) );
    while ( this->readFlag ) {
        DebugMessage(className, memberName, "wait\n");
        pthread_cond_wait( &(this->guard), &(this->mutex) );
    }
#endif //  USE_PTHREAD
    this->writeFlag = true;
    this->commandBit.reset(this->STOP_BIT);
    this->commandBit.reset(this->SUSPEND_BIT);
    this->commandBit.set(this->CONTINUE_BIT);
    this->writeFlag = false;
#ifdef USE_PTHREAD
    pthread_mutex_unlock( &(this->mutex) );
#endif //  USE_PTHREAD
}

/** set suspend command */
void AdvFitCommand::setSuspend() {
    string memberName=string("setSuspend()");
#ifdef USE_PTHREAD
    pthread_mutex_lock( &(this->mutex) );
    while ( this->readFlag ) {
        DebugMessage(className, memberName, "wait\n");
        pthread_cond_wait( &(this->guard), &(this->mutex) );
    }
#endif //  USE_PTHREAD
    this->writeFlag = true;
    this->commandBit.reset(this->STOP_BIT);
    this->commandBit.set(this->SUSPEND_BIT);
    this->commandBit.reset(this->CONTINUE_BIT);
    this->writeFlag = false;
#ifdef USE_PTHREAD
    pthread_mutex_unlock( &(this->mutex) );
#endif //  USE_PTHREAD
}

/** set stop command */
void AdvFitCommand::setStop() {
    string memberName=string("setStop()");
#ifdef USE_PTHREAD
    pthread_mutex_lock( &(this->mutex) );
    while ( this->readFlag ) {
        DebugMessage(className, memberName, "wait\n");
        pthread_cond_wait( &(this->guard), &(this->mutex) );
    }
#endif //  USE_PTHREAD
    this->writeFlag = true;
    this->commandBit.set(this->STOP_BIT);
    this->commandBit.reset(this->SUSPEND_BIT);
    this->commandBit.reset(this->CONTINUE_BIT);
    this->writeFlag = false;
#ifdef USE_PTHREAD
    pthread_mutex_unlock( &(this->mutex) );
#endif //  USE_PTHREAD
}

/**
 *  check command
 *
 *  return true, if the command is "continue"
 */
Bool AdvFitCommand::checkContinue() {
    string memberName=string("checkContinue()");
    Bool retval;
#ifdef USE_PTHREAD
    pthread_mutex_lock( &(this->mutex) );
    while ( this->writeFlag ) {
        DebugMessage(className, memberName, "wait\n");
        pthread_cond_wait(&(this->guard), &(this->mutex));
    }
#endif //  USE_PTHREAD
    this->readFlag = true;
    retval = static_cast<Bool>(this->commandBit.test(this->CONTINUE_BIT));
    this->readFlag = false;
#ifdef USE_PTHREAD
    pthread_mutex_unlock( &(this->mutex) );
#endif //  USE_PTHREAD
    return retval;
}

/**
 *  check command
 *
 *  return true, if the command is "suspend"
 */
Bool AdvFitCommand::checkSuspend() {
    string memberName=string("checkSuspend()");
    Bool retval;
#ifdef USE_PTHREAD
    pthread_mutex_lock( &(this->mutex) );
    while ( this->writeFlag ) {
        DebugMessage(className, memberName, "wait\n");
        pthread_cond_wait(&(this->guard), &(this->mutex));
    }
#endif //  USE_PTHREAD
    this->readFlag = true;
    retval = static_cast<Bool>(this->commandBit.test(this->SUSPEND_BIT));
    this->readFlag = false;
#ifdef USE_PTHREAD
    pthread_mutex_unlock( &(this->mutex) );
#endif //  USE_PTHREAD
    return retval;
}

/**
 *  check command
 *
 *  return true, if the command is "stop"
 */
Bool AdvFitCommand::checkStop() {
    string memberName=string("checkStop()");
    Bool retval;
#ifdef USE_PTHREAD
    pthread_mutex_lock( &(this->mutex) );
    while ( this->writeFlag ) {
        DebugMessage(className, memberName, "wait\n");
        pthread_cond_wait(&(this->guard), &(this->mutex));
    }
#endif //  USE_PTHREAD
    this->readFlag = true;
    retval = static_cast<Bool>(this->commandBit.test(this->STOP_BIT));
    this->readFlag = false;
#ifdef USE_PTHREAD
    pthread_mutex_unlock( &(this->mutex) );
#endif //  USE_PTHREAD
    return retval;
}

