/*  Copyright (C) 2003-2008 Free Electron Organization
    Any use of this software requires a license.  If a valid license
    was not distributed with this file, visit freeelectron.org. */

#include "data.pmh"

namespace fe
{

RecordAV RecordAV::clone(void)
{
	RecordAV r_clone;
	if(!isValid()) { return r_clone; }

	sp<Scope> spScope = m_spLayout->scope();

	feX("RecordAV::clone", "the following line needs to be activated");
	//r_clone = spScope->produceRecord(m_spLayout->name());

	UWORD cnt = spScope->getAttributeCount();
	for(UWORD i = 0; i < cnt; i++)
	{
		if(m_spLayout->checkAttribute(i))
		{
			sp<Attribute> spAttribute=spScope->attribute(i);
			if(spAttribute->isCloneable())
			{
				sp<BaseType> spBT = spAttribute->type();
				spBT->assign(
					r_clone.rawAttribute(i),
					rawAttribute(i));
			}
		}
	}

	return r_clone;
}

bool RecordAV::extractInstance(Instance &instance, const String &attrName)
{
    UWORD attrIndex;
    FEASSERT(m_spLayout.isValid());
    const sp<Attribute>& rspAttribute =
        m_spLayout->scope()->findAttribute(attrName, attrIndex);
    if(!rspAttribute.isValid())
    {
        return false;
    }

    if(!m_spLayout->checkAttribute(attrIndex))
    {
        return false;
    }

    const sp<BaseType>& rspBT = rspAttribute->type();

    void *pV = rawAttribute(attrIndex);

    int *pRefCnt = NULL;

	UWORD refCountIndex = m_spLayout->scope()->refCount().index();
	if(m_spLayout->checkAttribute(refCountIndex))
	{
		pRefCnt = &(accessAttribute<int>(refCountIndex));
	}

    instance.set(pV, rspBT, pRefCnt);

    return true;
}

String RecordAVInfo::print(void *instance)
{
	if(!instance)
		return String("<error>");

	const RecordSB* pR = (RecordSB*)instance;
	if(!pR->isValid())
		return String("<invalid>");

	String string;
	string.sPrintf("%u %s",pR->idr(),pR->layout().isValid()?
			pR->layout()->name().c_str(): "<invalid layout>");
	return string;
}

IWORD RecordAVInfo::output(std::ostream &ostrm, void *instance, t_serialMode mode)
{
	feX(e_unsupported,
		"RecordInfo::output",
		"record output should be done via fe::Stream");
	return 0;
}

void RecordAVInfo::input(std::istream &istrm, void *instance, t_serialMode mode)
{
	feX(e_unsupported,
		"RecordInfo::input",
		"record input should be done via fe::Stream");
}

IWORD RecordAVInfo::iosize(void)
{
	return c_implicit;
}

bool RecordAVInfo::getConstruct(void)
{
	return true;
}

void RecordAVInfo::construct(void *instance)
{
	new(instance)RecordAV;
}

void RecordAVInfo::destruct(void *instance)
{
	((RecordAV *)instance)->~RecordAV();
}



} /* namespace */


