/*******************************************************************************
*    ALMA - Atacama Large Millimiter Array
*    (c) Associated Universities Inc., 2002 *
*    (c) European Southern Observatory, 2002
*    Copyright by ESO (in the framework of the ALMA collaboration)
*    and Cosylab 2002, All rights reserved
*
*    This library is free software; you can redistribute it and/or
*    modify it under the terms of the GNU Lesser General Public
*    License as published by the Free Software Foundation; either
*    version 2.1 of the License, or (at your option) any later version.
*
*    This library is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*    Lesser General Public License for more details.
*
*    You should have received a copy of the GNU Lesser General Public
*    License along with this library; if not, write to the Free Software
*    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
*
*
*
* "@(#) $Id: isabellasmart_LampLoopImpl.cpp,v 1.1 2004/01/28 11:38:34 bjeram Exp $"
*
*/
 
#include <isabellasmartLampLoopImpl.h>
#include "../object/ACSErrTypeISABELLA.h"

// Control loop time interval [sec]
const static int CTRL_INTERVAL  = 1;

/* ----------------------------------------------------------------*/
smart_LampLoopImpl::smart_LampLoopImpl(PortableServer::POA_ptr poa, const ACE_CString &_name) :
    CharacteristicComponentImpl(poa, _name),
    smart_LampImpl(poa, _name),
    thread(NULL)

{
    // ACS_TRACE is used for debugging purposes
    ACS_TRACE("::smart_LampLoopImpl::smart_LampLoopImpl");



    ACS_SHORT_LOG((LM_INFO,"brightnessControl thread spawned.")); 

    cout << "***********************************************" << endl;
    cout << "***********************************************" << endl;
    cout << "***********************************************" << endl;
    cout << "***********************************************" << endl;
    cout << "***********************************************" << endl;
    cout << "***********************************************" << endl;
    cout << "***********************************************" << endl;
    cout << "***********************************************" << endl;
    cout << "***********************************************" << endl;
}

/* ----------------------------------------------------------------*/
smart_LampLoopImpl::~smart_LampLoopImpl()
{
    // ACS_TRACE is used for debugging purposes
    ACS_TRACE("::smart_LampLoopImpl::~smart_LampLoopImpl");
}

//
// Position control loop
// When the commanded position changes the actual position is moved to this
// new position.
//
void 
smart_LampLoopImpl::brightnessControl (void *param_p) 
{
    ACS::CBDescOut dso;    
    if (param_p == 0) 
	{
	return;
	}
    
    
    ACS::Completion completion;
    
    completion.type = ACSErr::ACSErrTypeOK;		// no error
    completion.code = ACSErrTypeOK::ACSErrOK;

    //
    // TODO: Error/Exception handling
    // 
    
    BACIThreadParameter *baciParameter_p = static_cast<BACIThreadParameter *>(param_p);
    BACIThread *myself_p = baciParameter_p->getBACIThread();
    
    // The thread worker is a static method.
    // The instance comes with the param_p structure
    smart_LampLoopImpl *lamp_p = const_cast<smart_LampLoopImpl *>(static_cast<const smart_LampLoopImpl *>(baciParameter_p->getParameter()));

    ACS_SHORT_LOG((LM_INFO, "Starting Brightness control loop."));

    if (BACIThread::InitThread != 0) 
	{
	BACIThread::InitThread("brightnessControl");
	}

    int errcode;
    unsigned long long timestamp;
    static double brightnessValue = 0.0;

    // Control loop
    while(myself_p->check() == true)
        {
	if(myself_p->isSuspended() == false)
	    {           
	    double stateValue = lamp_p->m_state_p->getDevIO()->read(errcode, timestamp);
	    stateValue = stateValue;

	    brightnessValue += 1.0;
	    // Simulated control
            ACS_SHORT_LOG((LM_INFO, "Setting brightnessValue to %.3f...", brightnessValue));
	    lamp_p->m_brightness_p->getDevIO()->write(brightnessValue, errcode, timestamp);
	    
	    if (brightnessValue == 30.0  ||  brightnessValue == 50.0)
		{
		completion.timeStamp = getTimeStamp();
		lamp_p->cbID->working(brightnessValue,completion,dso);
		}
	    if (brightnessValue == 60.0)
		{
		cout << "smart_LampLoopImpl::Exeption Call" << endl;

		ACSError erp = ACS_ERROR (ACSErr::ACSErrTypeISABELLA, ACSErrTypeISABELLA::Pointing, 
					  "pointing error");
		ACS_COMPLETION(completion, erp);
		
		lamp_p->cbID->done(brightnessValue, completion, dso);
		cout << "smart_LampLoopImpl:: suspending" << endl;
		myself_p->suspend();
		}
	    if (brightnessValue == 70.0)
		{
		completion.timeStamp = getTimeStamp();
		lamp_p->cbID->done(brightnessValue,completion,dso);
		brightnessValue = 0.0;
		cout << "smart_LampLoopImpl:: suspending" << endl;
		myself_p->suspend();
		}

	    myself_p->sleep();
	    }
	ACE_OS::sleep(CTRL_INTERVAL);
	}
    
    if (BACIThread::DoneThread != 0) 
	{
	BACIThread::DoneThread();
	}
    delete baciParameter_p;
    myself_p->setStopped();
    
}

void smart_LampLoopImpl::on_async (const char *colour, 
                               CORBA::Double brightness,
                               ACS::CBdouble *cb,
			       const ACS::CBDescIn &desc)
	throw (CORBA::SystemException)
{

    cbID = cb;
    dsc = desc;
    getComponent()->registerAction(BACIValue::type_null, cb, desc, this, 0);

}


ActionRequest 
smart_LampLoopImpl::onAction (BACIComponent *cob_p, 
                   const int &callbackID,
                   const CBDescIn &descIn, 
                   BACIValue *value_p,
                   Completion &completion, 
                   CBDescOut &descOut)
{
    cout << "smart_LampLoopImpl::onAction" << endl;

    // Initialize control loop thread
    if(thread == NULL)
	thread = getComponent()->getThreadManager()->create("brightnessControl", 
					       (void *)	smart_LampLoopImpl::brightnessControl, 
					       static_cast<void *>(this));
    else
	thread->resume();

    cout << "smart_LampLoopImpl::Thread created!!!!!!!!" << endl;
     
    return reqNone;
}
 

ActionRequest
smart_LampLoopImpl::invokeAction (int function,
                     BACIComponent *cob_p, 
                     const int &callbackID, 
                     const CBDescIn &descIn, 
                     BACIValue *value_p, 
                     Completion &completion, 
                     CBDescOut &descOut) 
{
    cout << "smart_LampLoopImpl::invokeAction" << endl;

    return onAction(cob_p, callbackID, descIn, value_p, completion, descOut);
}




/* --------------- [ MACI DLL support functions ] -----------------*/
#include <maciACSComponentDefines.h>
MACI_DLL_SUPPORT_FUNCTIONS(smart_LampLoopImpl)
/* ----------------------------------------------------------------*/


/*___oOo___*/