/*******************************************************************************
*    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: acscourseAsm2Impl.cpp,v 1.1 2004/01/28 11:38:34 bjeram Exp $"
*
*/
 
#include <acscourseAsm2Impl.h>
#include <ACSErrTypeAsm.h>
/* ----------------------------------------------------------------*/
Asm2Impl::Asm2Impl(PortableServer::POA_ptr poa, const ACE_CString &_name) :
    CharacteristicComponentImpl(poa, _name),
    m_cmdNbOfAveragedValues_p(0),
    m_actTemp_p(0)
{
    // ACS_TRACE is used for debugging purposes
    ACS_TRACE("::Asm2Impl::Asm2Impl");

    // properties
    // the property's name must be composed of the server's name and the
    //   property name.
    m_cmdNbOfAveragedValues_p = new RWdouble(_name+":cmdNbOfAveragedValues", getComponent());	
    CHARACTERISTIC_COMPONENT_PROPERTY(cmdNbOfAveragedValues, m_cmdNbOfAveragedValues_p);

    m_actTemp_p = new ROdouble(_name+":actTemp", getComponent());
    CHARACTERISTIC_COMPONENT_PROPERTY(actTemp, m_actTemp_p);
}

/* ----------------------------------------------------------------*/
Asm2Impl::~Asm2Impl()
{
    // ACS_TRACE is used for debugging purposes
    ACS_TRACE("::Asm2Impl::~Asm2Impl");
    ACS_DEBUG_PARAM("::Asm2Impl::~Asm2Impl", "Destroying %s...", name());

    // stop threads
    if (getComponent() != 0)
	{
	getComponent()->stopAllThreads();
	}
    
    // properties
    if (m_cmdNbOfAveragedValues_p != 0) 
	{ 
	m_cmdNbOfAveragedValues_p->destroy(); 
	m_cmdNbOfAveragedValues_p = 0; 
	}
    if (m_actTemp_p != 0) 
	{ 
	m_actTemp_p->destroy(); 
	m_actTemp_p = 0; 
	}

}
ActionRequest 
Asm2Impl::invokeAction (int function,
                        BACIComponent *cob_p, 
                        const int &callbackID, 
                        const CBDescIn &descIn, 
                        BACIValue *value_p, 
                        Completion &completion, 
                        CBDescOut &descOut) 
{
    ACE_DEBUG((LM_DEBUG, "(Asm2Impl::invokeAction) %s - function %d\n", getComponent()->getName(), function));
    if (function == 0)
    {
        // call the asynchronous method
    ACE_DEBUG((LM_DEBUG, "Call Asm2Impl::setAverageValueAction %s - function %d\n", getComponent()->getName(), function));
        return (this->setAverageValueAction)(cob_p, callbackID, descIn, value_p, completion, descOut);
    }
    else
    {
        return reqDestroy;
    }
}

/* ------------------ [ Action implementations ] ----------------- */

ActionRequest 
Asm2Impl::setAverageValueAction (BACIComponent *cob_p, 
                                 const int &callbackID,
                                 const CBDescIn &descIn, 
                                 BACIValue *value_p,
                                 Completion &completion, 
                                 CBDescOut &descOut)
{
    ACE_UNUSED_ARG(cob_p);
    ACE_UNUSED_ARG(callbackID);
    ACE_UNUSED_ARG(descIn);
    ACE_UNUSED_ARG(descOut);

    ACE_DEBUG((LM_DEBUG, "(Asm2Impl::setAverageValueAction) %s\n", getComponent()->getName()));

    ACE_DEBUG((LM_DEBUG, "(Asm2Impl::setAverageValueAction) value_p=0x%x\n",value_p));
    // convert the methods parameters back into something we can use
    double *param_p = 
        static_cast<double *>(const_cast<void *>(value_p->pointerValue()));
    ACE_DEBUG((LM_DEBUG, "(Asm2Impl::setAverageValueAction) ptr=0x%x\n",param_p));
    int errcode;
    unsigned long long timestamp;

    if (param_p != 0)
    {
        int nbOfValues = (int)*param_p;  
        ACE_DEBUG((LM_DEBUG, "(Asm2Impl::setAverageValueAction) value=%d\n",nbOfValues));
        m_cmdNbOfAveragedValues_p->getDevIO()->write(nbOfValues, errcode, timestamp);
    }
    else
    {
        CompletionImpl *comp;

        ACE_DEBUG((LM_DEBUG, "(Asm2Impl::handleError)\n"));
        comp=new ACSErrTypeAsm::NullPointerCompletion(__FILE__, __LINE__, "Asm2Impl::setAverageValueAction");
        // here we have to do convertion form CompletionImpl to
        // ACS::Completion by hand because returnCompletion() returns
        // ACSErr::Completion !!!  will be fixed in next ACS release
        completion.type = comp->getErrorType();
        ACE_DEBUG((LM_DEBUG, "(Asm2Impl::getErrorType done)\n"));
        completion.code = comp->getErrorCode();
        ACE_DEBUG((LM_DEBUG, "(Asm2Impl::getErrorCode done)\n"));
        completion.timeStamp = comp->getTimeStamp();
        ACE_DEBUG((LM_DEBUG, "(Asm2Impl::getTimeStamp done)\n"));
        //completion.previousError[0] = comp->getErrorTrace();



        ACE_DEBUG((LM_DEBUG, "(Asm2Impl::return done)\n"));
        return reqInvokeDone;
    }
    double *newValue=new double(1.234);
    value_p->setValue(*newValue);
    ACE_DEBUG((LM_DEBUG, "(Asm2Impl::setAverageValueAction) set=%f\n",*param_p));
    completion.timeStamp=getTimeStamp();
    completion.type=ACSErr::ACSErrTypeOK;
    completion.code=ACSErrTypeOK::ACSErrOK;

    // if OK action will be destroyed and we do not need it anymore
    ACE_DEBUG((LM_DEBUG, "(Asm2Impl::setAverageValueAction) END\n"));

    // if OK action will be destroyed and we do not need it anymore
    if (param_p!=0) 
    {
   //     delete param_p;
    }
    // complete action requesting done invokation, 
    // otherwise return reqInvokeWorking and set descOut.estimated_timeout
    sleep(1);
    return reqInvokeWorking;
}

/* --------------------- [ CORBA interface ] ----------------------*/
void 
    Asm2Impl::setAverageValue (CORBA::Double nbOfValues)
throw (CORBA::SystemException)
{
    int errcode;
    unsigned long long timestamp;
    cout << "Received setAverageValue command. nbOfValues: " << nbOfValues << endl; 

    m_cmdNbOfAveragedValues_p->getDevIO()->write(nbOfValues, errcode, timestamp);
}

ACS::RWdouble_ptr
Asm2Impl::cmdNbOfAveragedValues ()
    throw (CORBA::SystemException)
{
    if (m_cmdNbOfAveragedValues_p == 0)
    {
        return ACS::RWdouble::_nil();
    }

    ACS::RWdouble_var prop = ACS::RWdouble::_narrow(m_cmdNbOfAveragedValues_p->getCORBAReference());
    return prop._retn();
}


ACS::ROdouble_ptr
Asm2Impl::actTemp ()
    throw (CORBA::SystemException)
{
    if (m_actTemp_p == 0)
	{
	return ACS::ROdouble::_nil();
	}

    ACS::ROdouble_var prop = ACS::ROdouble::_narrow(m_actTemp_p->getCORBAReference());
    return prop._retn();
}

void
Asm2Impl::setAverageValueAsync (CORBA::Double nbOfValues,
                                ACS::CBdouble_ptr callBack,
                                const ACS::CBDescIn &desc
                               )
    throw (CORBA::SystemException)
{
    ACE_DEBUG((LM_DEBUG, "(Asm2Impl::setAverageValueAsync) %f\n",nbOfValues));
    // register the action in a queue so that control is returned immediately
    double *value = new double();
    *value=nbOfValues;

    BACIValue *baciV = new BACIValue(value);
    getComponent()->registerAction(BACIValue::type_double, callBack, desc, this, 0, *baciV); // ID = 0
    
}
/* --------------- [ MACI DLL support functions ] -----------------*/
#include <maciACSComponentDefines.h>
MACI_DLL_SUPPORT_FUNCTIONS(Asm2Impl)
/* ----------------------------------------------------------------*/

/*___oOo___*/