/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/

#include <precomp.h>
#include <ary/doc/d_oldcppdocu.hxx>


// NOT FULLY DEFINED SERVICES
#include <ary/info/all_tags.hxx>
#include <ary/info/docstore.hxx>
#include <ary/info/infodisp.hxx>
#include <docu_node_ids.hxx>




namespace ary
{
namespace doc
{

using namespace info;




unsigned char  C_ucNO_INDEX = 255;
typedef DYN StdTag * (F_CREATE)();


OldCppDocu::OldCppDocu()
	:	Node(docnt::nt_OldCppDocu),
	    bIsObsolete(false),
		bIsInternal(false),
		bIsInterface(false)
{
	memset( nTags, C_ucNO_INDEX, size_t(C_eAtTag_NrOfClasses) );
}

OldCppDocu::~OldCppDocu()
{
}

void
OldCppDocu::Store2( info::DocuStore & o_rDocuStore )
{
	o_rDocuStore.Store2ConnectedDeclaration(*this);
}

AtTag *
OldCppDocu::Create_StdTag( E_AtTagId i_eId )
{
	UINT8 nIndex = static_cast<UINT8>(i_eId);
	if ( nTags[nIndex] == C_ucNO_INDEX )
	{
		AtTag * ret = new StdTag(i_eId);
		NewTag(nIndex) = ret;
		return ret;
	}
	else
	{
		return GetTag(nIndex).GetFollower();
	}
}

AtTag *
OldCppDocu::CheckIn_BaseTag()
{
	UINT8 nIndex = atc_base;
	if ( nTags[nIndex] == C_ucNO_INDEX )
	{
		AtTag * ret = new BaseTag();
		NewTag(nIndex) = ret;
		return ret;
	}
	else
	{
		return GetTag(nIndex).GetFollower();
	}
}

AtTag *
OldCppDocu::CheckIn_ExceptionTag()
{
	UINT8 nIndex = atc_exception;
	if ( nTags[nIndex] == C_ucNO_INDEX )
	{
		AtTag * ret = new ExceptionTag();
		NewTag(nIndex) = ret;
		return ret;
	}
	else
	{
		return GetTag(nIndex).GetFollower();
	}
}

AtTag *
OldCppDocu::Create_ImplementsTag()
{
	UINT8 nIndex = atc_implements;
	if ( nTags[nIndex] == C_ucNO_INDEX )
	{
		AtTag * ret = new ImplementsTag();
		NewTag(nIndex) = ret;
		return ret;
	}
	else
	{
		return GetTag(nIndex).GetFollower();
	}
}

AtTag *
OldCppDocu::Create_KeywordTag()
{
	UINT8 nIndex = atc_keyword;
	if ( nTags[nIndex] == C_ucNO_INDEX )
	{
		AtTag * ret = new KeywordTag();
		NewTag(nIndex) = ret;
		return ret;
	}
	else
	{
		return GetTag(nIndex).GetFollower();
	}
}

AtTag *
OldCppDocu::CheckIn_ParameterTag()
{
	UINT8 nIndex = atc_parameter;
	if ( nTags[nIndex] == C_ucNO_INDEX )
	{
		AtTag * ret = new ParameterTag();
		NewTag(nIndex) = ret;
		return ret;
	}
	else
	{
		return GetTag(nIndex).GetFollower();
	}
}

AtTag *
OldCppDocu::CheckIn_SeeTag()
{
	UINT8 nIndex = atc_see;
	if ( nTags[nIndex] == C_ucNO_INDEX )
	{
		AtTag * ret = new SeeTag();
		NewTag(nIndex) = ret;
		return ret;
	}
	else
	{
		return GetTag(nIndex).GetFollower();
	}
}

AtTag *
OldCppDocu::CheckIn_TemplateTag()
{
	UINT8 nIndex = atc_template;
	if ( nTags[nIndex] == C_ucNO_INDEX )
	{
		AtTag * ret = new TemplateTag();
		NewTag(nIndex) = ret;
		return ret;
	}
	else
	{
		return GetTag(nIndex).GetFollower();
	}
}

AtTag *
OldCppDocu::Create_LabelTag()
{
	UINT8 nIndex = atc_label;
	if ( nTags[nIndex] == C_ucNO_INDEX )
	{
		AtTag * ret = new LabelTag();
		NewTag(nIndex) = ret;
		return ret;
	}
	else
	{
		return GetTag(nIndex).GetFollower();
	}
}

AtTag *
OldCppDocu::Create_DefaultTag()
{
	UINT8 nIndex = atid_descr;
	if ( nTags[nIndex] == C_ucNO_INDEX )
	{
		AtTag * ret = new StdTag(atid_descr);
		NewTag(nIndex) = ret;
		return ret;
	}
	else
	{
		return GetTag(nIndex).GetFollower();
	}
}

AtTag *
OldCppDocu::Create_SinceTag()
{
	UINT8 nIndex = atc_since;
	if ( nTags[nIndex] == C_ucNO_INDEX )
	{
		AtTag * ret = new SinceTag();
		NewTag(nIndex) = ret;
		return ret;
	}
	else
	{
		return GetTag(nIndex).GetFollower();
	}
}


void
OldCppDocu::Replace_AtShort_By_AtDescr()
{
    unsigned char nPosInTags = nTags[atid_short];
    if ( nPosInTags == C_ucNO_INDEX )
        return;

	AtTag * pTag = aTags[ nPosInTags ];
	if ( pTag == 0 )    // Should be csv_assert().
        return;

    csv_assert( dynamic_cast< StdTag* >(pTag) != 0 );
	StdTag * pStdTag = static_cast< StdTag* >(pTag);

    pStdTag->ChangeId2(atid_descr);
    nTags[atid_short] = C_ucNO_INDEX;
    nTags[atid_descr] = nPosInTags;
}

void
OldCppDocu::Set_Obsolete()
{
	bIsObsolete = true;
}

void
OldCppDocu::Set_Internal()
{
	bIsInternal = true;
}

const AtTag &
OldCppDocu::Short() const
{
    static const StdTag aNull_(atid_short);

    unsigned char nPosInTags = nTags[atid_short];
    if ( nPosInTags != C_ucNO_INDEX )
    {
		AtTag * pTag = aTags[ nPosInTags ];
		if ( pTag != 0 )    // Should be csv_assert().
		{
            return *pTag;
		}
	}

    return aNull_;
}

AtTag * &
OldCppDocu::NewTag(UINT8 i_nIndex)
{
	nTags[i_nIndex] = static_cast<UINT8>(aTags.size());
	aTags.push_back(0);
	return aTags.back();
}

AtTag &
OldCppDocu::GetTag( UINT8	i_nIndex )
{
    csv_assert( i_nIndex < C_eAtTag_NrOfClasses );
    csv_assert( nTags[i_nIndex] != C_ucNO_INDEX );
    csv_assert( aTags[nTags[i_nIndex]] != 0 );
	return * aTags[nTags[i_nIndex]];
}

bool
OldCppDocu::IsInternal() const
{
    return bIsInternal;
}

bool
OldCppDocu::IsInterface() const
{
    return bIsInterface;
}

void
OldCppDocu::do_Accept(csv::ProcessorIfc & io_processor) const
{
    csv::CheckedCall(io_processor, *this);
}

}   // namespace doc
}   // namespace ary
