// $Id: JGPLCDevice.h,v 1.4 2003/03/16 14:51:00 fukasawa Exp $

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

#ifndef JGPLCDEVICE_H
#define JGPLCDEVICE_H

#include "ecm.h"
#include "JGNameInfo.h"
#include "PLCDevice.h"

//
// Define PLC device
//
class BEE_Export JGPLCDevice : public JGNameInfo
{
    friend class JGPLCManager;

public:
    enum { SENSOR = 0, ACTUATOR = 1, CONTROL = 2 };   // dev type
    enum { DISCRETE = 0, SCALAR = 1, VECTOR = 2 };    // data type
    // io type
    enum { WORD = 0, BIT = 1, BITSET = 2, STRING = 3, WORDSET = 4 };

public:
    JGPLCDevice(): JGNameInfo(),
                   m_sysid(0), m_devtype(SENSOR), m_datatype(SCALAR),
                   m_iotype(WORD), m_format(ATOM_LIST), m_dimension(0),
                   m_plc(), m_maxval(0), m_minval(0), m_value(0),
                   m_lastAccess(0) {}
    JGPLCDevice(JGid& devid, string& name, PLCAccess& plc, int devtype,
                int datatype, int iotype, int format, int dimension,
                JGvalue& maxval, JGvalue& minval, JGvalue& initval,
                JGid& sysid)
            : JGNameInfo(name, devid),
              m_sysid(sysid), m_devtype(devtype), m_datatype(datatype),
              m_iotype(iotype), m_format(format), m_dimension(dimension),
              m_plc(plc), m_maxval(maxval), m_minval(minval),
              m_value(initval), m_lastAccess(0) {}
    JGPLCDevice(const JGPLCDevice& rhs) : JGNameInfo(rhs) { copy(rhs); }
    virtual ~JGPLCDevice() {}

    JGPLCDevice& operator=(const JGPLCDevice& rhs) {
            if (this == &rhs)
                return *this;
            copy(rhs);
            return *this;
        }

    void  devid(JGid& id)     { m_id = id; }
    void  sysid(JGid& id)     { m_sysid = id; }
    const JGid& devid() const { return m_id; }
    const JGid& sysid() const { return m_sysid; }
    void  devtype(int t)      { m_devtype = t; }
    int   devtype() const     { return m_devtype; }
    int   datatype() const    { return m_datatype; }
    int   iotype() const      { return m_iotype; }
    void  format(int f)       { m_format = f; }
    int   format() const      { return m_format; }
    void  viewFormat(int f)   { m_viewFormat = f; }
    int   viewFormat() const  { return m_viewFormat; }
    int   dim() const         { return m_dimension; }
    int   dataq() const       { return m_dataq; }
    PLCDevice * plc()         { return m_plc.memory(); }
    JGvalue& initval()        { return m_initval; }
    JGvalue& maxval()         { return m_maxval; }
    JGvalue& minval()         { return m_minval; }
    void  unit(string& s)     { m_unit = s; }
    const string& unit() const { return m_unit; }
    const PLCAccess& access()  { return m_plc; }
    const ACE_Time_Value& lastAccess() const  { return m_lastAccess; }
    const PLCAddress&     address() const { return m_plc; }

    JGvalue& get();                                // Get data from plc
    int      put(JGvalue& val, bool sync = true);  // Put data to plc
    virtual  int init() { return BEE_SUCCESS; }
    virtual  int sense();

protected:
    void copy(const JGPLCDevice& rhs);
    void setPLC(PLCAccess& plc) { m_plc = plc; }

protected:
    JGid   m_sysid;
    int    m_devtype;    // SENSOR, ACTUATOR
    int    m_datatype;   // VECTOR, SCALAR
    int    m_iotype;     // WORD, BIT
    int    m_format;     // JGPLCDevice::XXXX -> ATOM_XXXX
    int    m_viewFormat; // ATOM_XXXX
    int    m_dimension;
    int    m_dataq;      // word/bit quantity
    //
    PLCAccess m_plc;
    JGvalue m_maxval;
    JGvalue m_minval;
    JGvalue m_initval;
    string  m_unit;

    JGvalue        m_value;
    ACE_Time_Value m_lastAccess;
};

typedef map<JGid, JGPLCDevice *, id_less, allocator<JGPLCDevice *> >
        JGPLCDeviceTable;
typedef map<string, JGPLCDevice *, str_less, allocator<JGPLCDevice *> >
        JGPLCDeviceMap;
typedef JGPLCDeviceTable::value_type  JGPLCDevicePair;
typedef JGPLCDeviceMap::value_type    JGPLCNamePair;
typedef vector<JGPLCDevice *>         JGPLCDevices;
typedef list<JGPLCDevice *>           JGPLCDeviceList;

#endif
