// $Id: var_func.cpp,v 1.10 2003/03/16 14:51:01 fukasawa Exp $

//=============================================================================
/**
 *  @file    var_func.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

//
// Functions of variable are used for getting value.
//

#include "JGInfoManager.h"
#include "JGAlarmManager.h"
#include "JGEventManager.h"
#include "JGProcProgManager.h"
#include "JGSubSystem.h"
#include "sac/JGIODevManager.h"
#include "JGVariable.h"
#include "JGLimit.h"
#include "JGTimeModule.h"
#include "BS2DeclAtoms.h"

// #define USE_PLCTIME   1

static BS2Atom * fg_systime(JGVariable * var, void * arg);
static BS2Atom * fg_getsvid(JGVariable * var, void * arg);
static BS2Atom * fg_getecid(JGVariable * var, void * arg);
static BS2Atom * fg_getecv(JGVariable * var, void * arg);
static BS2Atom * fg_get_varname(JGVariable * var, void * arg);
static BS2Atom * fg_alarm_set(JGVariable * var, void * arg);
static BS2Atom * fg_alarm_enabled(JGVariable * var, void * arg);
static BS2Atom * fg_event_enabled(JGVariable * var, void * arg);
static BS2Atom * fg_limit_report(JGVariable * var, void * arg);
static BS2Atom * fg_get_locid(JGVariable * var, void * arg);
static BS2Atom * fg_get_locstatus(JGVariable * var, void * arg);
static BS2Atom * fg_pp_changed_set(JGVariable * var, void * arg);

int setSystemFunction(JGVariable * var)
{
    if (var->name() == VAR_CLOCK)
    {
        var->funcptr(fg_systime);
    }
    else if (var->name() == VAR_CHANGED_ECV)
    {
        var->funcptr(fg_getecv);
    }
    return 0;
}

int setLibFunction(JGVariable * var)
{
    if (var->name() == VAR_ALARM_ENABLED)
    {
        var->funcptr(fg_alarm_enabled);
    }
    else if (var->name() == VAR_ALARMS_SET)
    {
        var->funcptr(fg_alarm_set);
    }
    else if (var->name() == VAR_EVENTS_ENABLED)
    {
        var->funcptr(fg_event_enabled);
    }
    else if (var->name() == VAR_EVENT_LIMIT ||
             var->name() == VAR_LIMIT_VARIABLE ||
             var->name() == VAR_TRANSITION_TYPE)
    {
        var->funcptr(fg_limit_report);
    }
    else if (var->name() == VAR_CHANGED_ECV)
    {
        var->funcptr(fg_getecv);
    }
    else if (var->name() == VAR_CHANGED_ECID)
    {
        var->funcptr(fg_getecid);
    }
    else if (var->name() == VAR_CHANGED_ECNAME)
    {
        var->funcptr(fg_get_varname);
    }
    else if (var->name() == VAR_LOCATION_ID)
    {
        var->funcptr(fg_get_locid);
    }
    else if (var->name() == VAR_LOCATION_STATUS)
    {
        var->funcptr(fg_get_locstatus);
    }
    else if ((var->name() == VAR_PP_CHANGE_NAME) ||
             (var->name() == VAR_PP_CHANGE_LIST))
    {
        var->funcptr(fg_pp_changed_set);
    }
    return 0;
}

//-----------------------------------------------------------------------------
BS2Atom * fg_systime(JGVariable * var, void * arg)
{
    ACE_UNUSED_ARG(var);
    ACE_UNUSED_ARG(arg);

    BS2Atom * result = NULL;            // Not set value to the result
    string now;
    JGTimeModule::instance()->getFormattedDateAndTime(now);
    result = new BS2Ascii(now);
    return result;
}

//-----------------------------------------------------------------------------
BS2Atom * fg_get_varname(JGVariable * var, void * arg)
{
    ACE_UNUSED_ARG(var);

    BS2Atom * atom = NULL;
    if (arg != NULL)
    {
        JGVariable * var = (JGVariable *)arg;
        atom = new BS2Ascii(var->name());
    }
    return atom;
}

//-----------------------------------------------------------------------------
BS2Atom * fg_getsvid(JGVariable * var, void * arg)
{
    BS2Atom * atom = NULL;
    if (arg != NULL)
    {
        JGVariable * sv = (JGVariable *)arg;
        atom = BS2Atom::factory(sv->svid());
    }
    return atom;
}

//-----------------------------------------------------------------------------
BS2Atom * fg_getecid(JGVariable * var, void * arg)
{
    ACE_UNUSED_ARG(var);

    BS2Atom * atom = NULL;
    if (arg != NULL)
    {
        JGVariable * ecv = (JGVariable *)arg;
        atom = BS2Atom::factory(ecv->ecid());
    }
    else
    {
        atom = new BS2Ascii();
    }
    return atom;
}

//-----------------------------------------------------------------------------
BS2Atom * fg_getecv(JGVariable * var, void * arg)
{
    BS2Atom * atom = NULL;
    if (arg != NULL)
    {
        JGVariable * ecv = (JGVariable *)arg;
        BS2value val(ecv->curval());
        atom = val.getAtom(ecv->format());
    }
    else
    {
        BS2value val(var->curval());
        atom = val.getAtom(var->format());
    }
    return atom;
}

//-----------------------------------------------------------------------------
BS2Atom * fg_alarm_set(JGVariable * var, void * arg)
{
    ACE_UNUSED_ARG(var);
    ACE_UNUSED_ARG(arg);

    BS2Atom * result;
    BS2List * listatom = new BS2List;
    JGAlarms * alset = JGAlarmManager::instance()->alarms();
    JGAlarms::iterator iter = alset->begin();
    for ( ; iter != alset->end(); iter++)
    {
        JGAlarm * alarm = *iter;
        BS2Atom * atom = BS2Atom::factory(alarm->alid());
        listatom->add(atom);
    }
    result = (BS2Atom *)listatom;
    return result;
}

//-----------------------------------------------------------------------------
BS2Atom * fg_pp_changed_set(JGVariable * var, void * arg)
{
    BS2Atom * result;
    if (arg == NULL)
    {
        BS2value val(var->curval());
        result = val.getAtom(var->format());
    }
    else
    {
        BS2List * listatom = new BS2List;
        vector<JGid>& ppset = JGProcProgManager::instance()->ppids();
        for (size_t i = 0; i < ppset.size(); i++)
        {
            BS2Atom * atom = BS2Atom::factory(ppset[i]);
            listatom->add(atom);
        }
        result = (BS2Atom *)listatom;
    }
    return result;
}


//-----------------------------------------------------------------------------
BS2Atom * fg_alarm_enabled(JGVariable * var, void * arg)
{
    ACE_UNUSED_ARG(var);
    ACE_UNUSED_ARG(arg);

    BS2Atom * result;
    BS2List * listatom = new BS2List;
    JGAlarmTable * alarms = JGAlarmManager::instance()->alarmTable();
    JGAlarmTable::iterator iter = alarms->begin();
    for ( ; iter != alarms->end(); iter++)
    {
        JGAlarm * alarm = &((*iter).second);
        if (alarm->enabled())
        {
            listatom->add(BS2Atom::factory(alarm->alid()));
        }
    }
    result = (BS2Atom *)listatom;
    return result;
}

//-----------------------------------------------------------------------------
BS2Atom * fg_event_enabled(JGVariable * var, void * arg)
{
    ACE_UNUSED_ARG(var);
    ACE_UNUSED_ARG(arg);

    BS2List * listatom = new BS2List;
    JGEventTable * evtable = JGEventManager::instance()->eventTable();
    JGEventTable::iterator iter = evtable->begin();
    for ( ; iter != evtable->end(); iter++)
    {
        JGEvent * event = &((*iter).second);
        if (event->enabled())
        {
            BS2Atom * atom = new BS2Ascii(event->ceid().toString());
            listatom->add(atom);
        }
    }
    return listatom;
}

//-----------------------------------------------------------------------------
BS2Atom * fg_limit_report(JGVariable * var, void * arg)
{
    BS2Atom * result = NULL;
    if (arg != NULL)
    {
        JGVariable * target = (JGVariable *)arg;
        JGLimit * limit = target->limit();
        result = limit->getAtom(var->vid().toString());
        if (result == NULL)
        {
            ACE_ERROR((LM_ERROR,
                  ACE_TEXT("fg_limit_report : Illegal VID(%s).\n"),
                  var->vid().toString().c_str()));
        }
    }
    return result;
}

//-----------------------------------------------------------------------------
BS2Atom * fg_get_locid(JGVariable * var, void * arg)
{
    ACE_UNUSED_ARG(var);

    BS2Atom * atom = NULL;
    if (arg != NULL)
    {
        JGVariable * location = (JGVariable *)arg;
        JGIODevice * sac = location->sac();
        if (sac->format() == JGIODevice::BITSET)
        {   // As device is bitset, vid mean iodev_id.
            sac = JGIODevManager::instance()->find(location->vid());
            if (sac == NULL)
            {
                ACE_ERROR((LM_ERROR,
                    ACE_TEXT("fg_get_locid : Not found I/O Device(%s).\n"),
                    location->vid().toString().c_str()));
                return NULL;
            }
        }
        JGSubSystem * subsys = sac->subsystem();
        // As LOC format is BINARY, convert code.
        BYTE buf[8];
        buf[0] = (BYTE)(subsys->locid().getUInt() & 0xFF);
        atom = new BS2Binary(buf, 1);
    }
    return atom;
}

//-----------------------------------------------------------------------------
BS2Atom * fg_get_locstatus(JGVariable * var, void * arg)
{
    BS2Atom * atom = NULL;
    if (arg != NULL)
    {
        JGVariable * location = (JGVariable *)arg;
        BS2value val(location->curval());
        atom = val.getAtom(var->format());
    }
    return atom;
}

