// $Id: PLCAddress.h,v 1.3 2003/03/19 16:49:24 fukasawa Exp $

//=============================================================================
/**
 *  @file    PLCAddress.h
 *
 *  @author  Fukasawa Mitsuo
 *
 *
 *    Copyright (C) 2001-2002 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 PLCADDRESS_H
#define PLCADDRESS_H

#include "ace/streams.h"
#include "ace/OS.h"
#include "BEE_Export.h"
#ifdef __GNUC__
#include <stdexcept>
#define UINT   unsigned int
#define ULONG  unsigned long
#endif
const long ACTION_END = 0x7FFFFFFF;

class PLCDevice;

//
// PLC Address
//
struct BEE_Export PLCAddress
{
    PLCAddress() : m_type(0), m_addr(0) {}
    PLCAddress(int type, long addr)
            : m_type(type), m_addr(addr) {}
    PLCAddress(const PLCAddress& rhs)
            : m_type(rhs.m_type), m_addr(rhs.m_addr) {}
    PLCAddress(long addr)
            : m_type((addr >> 16) & 0xFFFF), m_addr(addr & 0xFFFF) {}
    PLCAddress& operator=(const PLCAddress& rhs) {
            if (this == &rhs)
                return *this;
            m_type = rhs.m_type;
            m_addr = rhs.m_addr;
            return *this;
        }
    void set(int type, long addr) { m_type = type;  m_addr = addr; }
    int  type() const { return m_type; }
    long addr() const { return m_addr; }

    PLCAddress& operator+=(const PLCAddress& rhs) {
            if (m_addr == ACTION_END)
                return *this;            // ignore
            m_addr += rhs.m_addr;
            return *this;
        }
    PLCAddress& operator+=(long delta) {
            if (m_addr == ACTION_END)
                return *this;             // ignore
            m_addr += delta;
            return *this;
        }
//
    int  m_type;                          // device type
    long m_addr;
};


//
// PLC Access Address
//
struct BEE_Export PLCAccess : public PLCAddress
{
    PLCAccess() : m_memory(NULL) {}
    PLCAccess(int type, long addr, PLCDevice * plc = NULL)
            : PLCAddress(type, addr), m_memory(plc) {}
    PLCAccess(const PLCAccess& rhs) : PLCAddress(rhs) { m_memory = rhs.m_memory; }
    ~PLCAccess() {}
    PLCAccess& operator=(const PLCAccess& rhs) {
            if (this == &rhs)
                return *this;
            this->PLCAddress::operator=(rhs);
            m_memory = rhs.m_memory;
            return *this;
        }

    PLCDevice * memory() { return m_memory; }
    void set(int type, long addr, PLCDevice * plc) {
            m_type = type;  m_addr = addr;  m_memory = plc;
        }

// variable
    PLCDevice * m_memory;
};

#endif
