/**************************************************************
 *
 * 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 <s2_luidl/pe_selem.hxx>

// NOT FULLY DECLARED SERVICES
#include <ary/idl/i_gate.hxx>
#include <ary/idl/i_struct.hxx>
#include <ary/idl/i_structelem.hxx>
#include <ary/idl/ip_ce.hxx>
#include <ary/doc/d_oldidldocu.hxx>
#include <s2_luidl/pe_type2.hxx>
#include <s2_luidl/tk_ident.hxx>
#include <s2_luidl/tk_punct.hxx>


namespace csi
{
namespace uidl
{

namespace
{
    const String  C_sNone;
}

PE_StructElement::PE_StructElement( RStructElement &	o_rResult,
									const RStruct &		i_rCurStruct,
							        const String &      i_rCurStructTemplateParam )
	:	eState(e_none),
		pResult(&o_rResult),
		pCurStruct(&i_rCurStruct),
		bIsExceptionElement(false),
		pPE_Type(0),
		nType(0),
		sName(),
		pCurStructTemplateParam(&i_rCurStructTemplateParam)
{
	pPE_Type = new PE_Type(nType);
}

PE_StructElement::PE_StructElement( RStructElement &	o_rResult,
							        const RStruct &		i_rCurExc )
	:	eState(e_none),
		pResult(&o_rResult),
		pCurStruct(&i_rCurExc),
		bIsExceptionElement(true),
		pPE_Type(0),
		nType(0),
		sName(),
		pCurStructTemplateParam(&C_sNone)
{
	pPE_Type = new PE_Type(nType);
}

void
PE_StructElement::EstablishContacts( UnoIDL_PE *				io_pParentPE,
									 ary::Repository &		io_rRepository,
							         TokenProcessing_Result & 	o_rResult )
{
	UnoIDL_PE::EstablishContacts(io_pParentPE,io_rRepository,o_rResult);
	pPE_Type->EstablishContacts(this,io_rRepository,o_rResult);
}

PE_StructElement::~PE_StructElement()
{
}

void
PE_StructElement::ProcessToken( const Token & i_rToken )
{
	i_rToken.Trigger(*this);
}

void
PE_StructElement::Process_Default()
{
	if (eState == expect_type)
	{
		SetResult( not_done, push_sure, pPE_Type.Ptr() );
		eState = expect_name;
	}
	else {
		csv_assert(false);
    }
}

void
PE_StructElement::Process_Identifier( const TokIdentifier & i_rToken )
{
    csv_assert(*i_rToken.Text() != 0);

	if (eState == expect_type)
	{
	    if ( *pCurStructTemplateParam == i_rToken.Text() )
	    {
            nType = lhf_FindTemplateParamType();
       		SetResult( done, stay );
        	eState = expect_name;
	    }
	    else    // No template parameter type existing, or not matching:
	    {
       		SetResult( not_done, push_sure, pPE_Type.Ptr() );
        	eState = expect_name;
	    }
	}
	else if (eState == expect_name)
	{
		sName = i_rToken.Text();
		SetResult( done, stay );
        eState = expect_finish;
	}
	else {
		csv_assert(false);
    }
}

void
PE_StructElement::Process_Punctuation( const TokPunctuation &)
{
    csv_assert(eState == expect_finish);

	SetResult( done, pop_success );
}

void
PE_StructElement::InitData()
{
	eState = expect_type;

	nType = 0;
	sName = "";
}

void
PE_StructElement::TransferData()
{
	csv_assert(pResult != 0 AND pCurStruct != 0);

    ary::idl::StructElement *
        pCe = 0;
    if (bIsExceptionElement)
    {
        pCe = & Gate().Ces().Store_ExceptionMember(
                                            *pCurStruct,
                                            sName,
                                            nType );
    }
    else
    {
        pCe = & Gate().Ces().Store_StructMember(
                                            *pCurStruct,
                                            sName,
                                            nType );
    }
	*pResult = pCe->CeId();
	PassDocuAt(*pCe);

	eState = e_none;
}

UnoIDL_PE &
PE_StructElement::MyPE()
{
	return *this;
}

ary::idl::Type_id
PE_StructElement::lhf_FindTemplateParamType() const
{
    const ary::idl::CodeEntity &
        rCe = Gate().Ces().Find_Ce(*pCurStruct);
    const ary::idl::Struct &
        rStruct = static_cast< const ary::idl::Struct& >(rCe);
    return rStruct.TemplateParameterType();
}


}   // namespace uidl
}   // namespace csi
