// $Id: JGAttribute.cpp,v 1.8 2003/03/16 14:51:00 fukasawa Exp $

//=============================================================================
/**
 *  @file    JGAttribute.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 "JGAttribute.h"
#include "JGClass.h"
#include "JGObject.h"
#include "JGAttrData.h"

//-----------------------------------------------------------------------------
// Constructor/Destructor
//-----------------------------------------------------------------------------
JGAttribute::JGAttribute(JGClass& clazz, const BCHAR * name, int type,
                         size_t size)
        : b_attribute(clazz, name, type, size) {
    TRACE_FUNCTION(TRL_CONSTRUCT, "JGAttribute::JGAttribute");
}

//-----------------------------------------------------------------------------
// Create instance data of attribute
//-----------------------------------------------------------------------------
b_attrdata * JGAttribute::instance(const b_object * obj) const
{
    TRACE_FUNCTION(TRL_LOW, "JGAttribute::factory");

    JGAttrData * val = new JGAttrData((JGObject *)obj,
                                      (JGAttribute *)this);
    val->set(const_cast<b_value&>(m_init));
    return val;
}

//-----------------------------------------------------------------------------
// Dump
//-----------------------------------------------------------------------------
void JGAttribute::dump() const
{
    ACE_DEBUG((LM_DEBUG, ACE_TEXT("  name = %s(%s), "), m_name.c_str(),
                                                        m_userName.c_str()));
    ACE_DEBUG((LM_DEBUG, ACE_TEXT("type = 0x%x, "), m_type));
    ACE_DEBUG((LM_DEBUG, ACE_TEXT("size = %d, "), m_size));
    ACE_DEBUG((LM_DEBUG, ACE_TEXT("position = %d, "), m_position));
    string value;
    m_init.get(value);
    ACE_DEBUG((LM_DEBUG, ACE_TEXT("initval = %s\n"), value.c_str()));
}


//
// <<< Vector >>>
//
//-----------------------------------------------------------------------------
// Constructor/Destructor
//-----------------------------------------------------------------------------
JGVector::JGVector(const BCHAR * name, JGAttribute * attr, size_t q, int mode)
        : JGAttribute(name, ATOM_VECTOR, q, mode)
{
    if (attr != NULL)
    {
        m_attrs.push_back(attr);
        b_valvect vv;
        for (size_t i = 0; i < q; i++)
        {  // tricky
            vv.push_back(const_cast<b_value *>(&(attr->getInitVal())));
        }
        m_init = vv;
    }
}

//-----------------------------------------------------------------------------
JGVector::JGVector(JGClass& cls, const BCHAR * name, JGAttribute * attr,
                   size_t q, int mode)
        : JGAttribute(name, ATOM_VECTOR, q, mode)
{
    if (attr != NULL)
    {
        m_attrs.push_back(attr);
        b_valvect vv;
        for (size_t i = 0; i < q; i++)
        {  // tricky
            vv.push_back(const_cast<b_value *>(&(attr->getInitVal())));
        }
        m_init = vv;
    }
    cls.add(this);
}

//-----------------------------------------------------------------------------
JGVector::JGVector(JGStruct& stt, const BCHAR * name, JGAttribute * attr,
                   size_t q, int mode)
        : JGAttribute(name, ATOM_VECTOR, q, mode)
{
    if (attr != NULL)
    {
        m_attrs.push_back(attr);
        b_valvect vv;
        for (size_t i = 0; i < q; i++)
        {  // tricky
            vv.push_back(const_cast<b_value *>(&(attr->getInitVal())));
        }
        m_init = vv;
    }
    stt.add(this);
}

//-----------------------------------------------------------------------------
// Create instance data of attribute
//-----------------------------------------------------------------------------
b_attrdata * JGVector::instance(const b_object * obj) const
{
    TRACE_FUNCTION(TRL_LOW, "JGVector::factory");

    JGAttrData * val = new JGAttrData((JGObject *)obj,
                                      (JGAttribute *)this);
    val->set(const_cast<b_value&>(m_init));

    return val;
}

//-----------------------------------------------------------------------------
// Dump
//-----------------------------------------------------------------------------
void JGVector::dump() const
{
    ACE_DEBUG((LM_DEBUG, ACE_TEXT("<vector>\n")));
    m_attrs[0]->dump();
    ACE_DEBUG((LM_DEBUG, ACE_TEXT("</vector>\n")));
}


//
// <<< Struct >>>
//
//-----------------------------------------------------------------------------
// Constructor/Destructor
//-----------------------------------------------------------------------------
JGStruct::JGStruct(JGClass& cls, const BCHAR * name, int mode)
        : JGAttribute(name, ATOM_STRUCT, 0, mode)
{
    TRACE_FUNCTION(TRL_LOW, "JGStruct::JGStruct");

    cls.add(this);
}

//-----------------------------------------------------------------------------
JGStruct::JGStruct(JGStruct& stt, const BCHAR * name, int mode)
        : JGAttribute(name, ATOM_STRUCT, 0, mode)
{
    TRACE_FUNCTION(TRL_LOW, "JGStruct::JGStruct");

    stt.add(this);
}

//-----------------------------------------------------------------------------
// Create instance data of attribute
//-----------------------------------------------------------------------------
b_attrdata * JGStruct::instance(const b_object * obj) const
{
    TRACE_FUNCTION(TRL_LOW, "JGStruct::factory");

    JGAttrData * val = new JGAttrData((JGObject *)obj,
                                      (JGAttribute *)this);
    for (size_t i = 0; i < m_attrs.size(); i++)
    {
        b_valvect * members = m_init.m._vec;
        b_value * initval = (*members)[i];
        JGAttrData * mbrData = reinterpret_cast<JGAttrData *>(m_attrs[i]->instance(obj));
        mbrData->set(*initval);
        val->m._vec->push_back(mbrData);
    }

    return val;
}

//-----------------------------------------------------------------------------
// Add member attributes
//-----------------------------------------------------------------------------
void JGStruct::add(JGAttribute * attr)
{
    TRACE_FUNCTION(TRL_LOW, "JGStruct::add");

    BEEAssert(attr != NULL);
    m_attrs.push_back(attr);
    attr->position(m_attrs.size() - 1);     // Set position of struct
    b_value * v = new b_value(attr->getInitVal());
    m_init.m._vec->push_back(v);

    return ;
}

//-----------------------------------------------------------------------------
void JGStruct::add(JGAttribute * attrs[])
{
    TRACE_FUNCTION(TRL_LOW, "JGStruct::add");

    BEEAssert(attrs != NULL);
    int i = 0;
    while (attrs[i] != NULL)
    {
        JGAttribute * attr = attrs[i++];
        m_attrs.push_back(attr);
        attr->position(m_attrs.size() - 1);     // Set position of struct
        b_value * v = new b_value(attr->getInitVal());
        m_init.m._vec->push_back(v);
    }

    return ;
}

//-----------------------------------------------------------------------------
// Dump
//-----------------------------------------------------------------------------
void JGStruct::dump() const
{
    ACE_DEBUG((LM_DEBUG, ACE_TEXT("<struct>\n")));
    for (size_t i = 0; i < m_attrs.size(); i++)
    {
        m_attrs[i]->dump();
    }
    ACE_DEBUG((LM_DEBUG, ACE_TEXT("</struct>\n")));
}



