// $Id: JGDevType.cpp,v 1.3 2003/02/02 15:56:01 fukasawa Exp $

//=============================================================================
/**
 *  @file    JGDevType.cpp
 *
 *  @author  Fukasawa Mitsuo
 *
 *
 *    Copyright (C) 2001-2003 BEE Co.,Ltd. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
//=============================================================================

#define BEE_BUILD_DLL

#include "JGDevType.h"
#include "JGDevObject.h"
#include "JGDevAttribute.h"
#include "PLCDevice.h"

static ACE_Thread_Mutex _lock;

//-----------------------------------------------------------------------------
// Instance Log Object
//-----------------------------------------------------------------------------
JGDevObject * JGDevType::instance()
{
    TRACE_FUNCTION(TRL_CONSTRUCT, "JGDevType::instance");
    // Lock
    ACE_GUARD_RETURN(ACE_Thread_Mutex, ace_mon, _lock, NULL);

    JGDevObject * devobj = new JGDevObject(this, m_seq++);

    m_objs.insert(b_objectPair(devobj->getObjID(), devobj));
    ObjSpec::instance()->addObject(devobj);
    return devobj;
}

//-----------------------------------------------------------------------------
// Destroy Log Object
//-----------------------------------------------------------------------------
int JGDevType::destroy(JGDevObject * obj)
{
    TRACE_FUNCTION(TRL_CONSTRUCT, "JGDevType::destroy");
    // Lock
    ACE_GUARD_RETURN(ACE_Thread_Mutex, ace_mon, _lock, 1);

    delete obj;
    return 0;
}

//-----------------------------------------------------------------------------
// Delete Last Log Object
//-----------------------------------------------------------------------------
int JGDevType::releaseLast()
{
    TRACE_FUNCTION(TRL_CONSTRUCT, "JGDevType::releaseLast");
    // Lock
    ACE_GUARD_RETURN(ACE_Thread_Mutex, ace_mon, _lock, 1);
    if (m_last != NULL)
    {
        delete m_last;
        m_last = NULL;
    }
    return 0;
}

//-----------------------------------------------------------------------------
// Get Latch status from switch register
//-----------------------------------------------------------------------------
bool JGDevType::latchStatus()
{
    TRACE_FUNCTION(TRL_LOW, "JGDevType::latchStatus");
    bool status;

    if (! m_latch)
    {
        return false;
    }

    PLCDevice * plc = m_watchAdr.memory();
    if (plc == NULL)
    {
        TRACE_ERROR(("plc memory is null.\n"));
        return false;
    }
    USHORT cureg = plc->get(m_watchAdr.addr());
    status = (cureg) ? true : false;
    return status;
}

//-----------------------------------------------------------------------------
// Get Pause status from switch register
//-----------------------------------------------------------------------------
bool JGDevType::pauseStatus()
{
    TRACE_FUNCTION(TRL_LOW, "JGDevType::pauseStatus");
    bool status;

    if (! m_pause)
    {
        return false;
    }

    PLCDevice * plc = m_pauseAdr.memory();
    if (plc == NULL)
    {
        TRACE_ERROR(("plc memory is null.\n"));
        return false;
    }
    USHORT cureg = plc->get(m_pauseAdr.addr());
    status = (cureg) ? true : false;
    return status;
}

//-----------------------------------------------------------------------------
// Compare the last and the current object data
//-----------------------------------------------------------------------------
bool JGDevType::checkAndSet(const JGDevObject * rhs)
{
    TRACE_FUNCTION(TRL_LOW, "JGDevType::isChanged");

    JGDevObject * current = const_cast<JGDevObject *>(rhs);
    bool status;
    if (m_last == NULL)
    {
        m_last = this->instance();
        status = false;
    }
    else
    {
        status = (m_last->equal(*current)) ? false : true;
    }
    m_last->b_object::set(*rhs);
    return status;
}


//-----------------------------------------------------------------------------
// Dump
//-----------------------------------------------------------------------------
void JGDevType::dump() const
{
    this->b_objtype::dump();
}

