##
## 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.
##

// This file automatically generated by:
//   $version
//   $now
// This file is automatically created and should not be edited!

\#include "$inc"
\#include "common/EtchRuntimeException.h"

using namespace $namespace;

#set($class = ($intf.name())+$suffix)

#foreach( $n in $intf.iterator() )
#if($n.isConstant() && !$hasBaseClass)
#set($initConstruct = true)
#end
#end
#if($initConstruct)
#set($sep = "")
$class::$intf.name()() :#foreach( $n in $intf.iterator() )#if($n.isConstant())#if(!$hasBaseClass)$sep $n.name()($helper.getTypeValue( $n.type(), $n.value() ) #set($sep = ","))#end#end#end{}
#end
#foreach( $n in $intf.iterator() )
#if($n.isEnumx())
#if (!$hasBaseClass)
/*
 * Init Type ID of $n.name()
 */
const EtchObjectType* $n.name()::TYPE() {
  const static EtchObjectType TYPE(${n.vname($helper)}ID, NULL);
  return &TYPE;
}

#end
#elseif ($n.isStruct() || $n.isExcept())
#if (!$hasBaseClass)
/*
 * Init Type ID of $class::$n.name()
 */
const EtchObjectType* $class::$n.name()::TYPE() {
  const static EtchObjectType TYPE(${n.vname($helper)}ID, NULL);
  return &TYPE;
}

/**
 * Constructs the $n.name().
 */
$class::$n.name()::$n.name()()
#if($n.isExcept())
  : EtchException("${n.name()}", ETCH_ERROR, EXCPTYPE_USERDEFINED)
#end
{
  addObjectType($class::$n.name()::TYPE());
}
#if ($n.hasAnyParameters())
/**
 * Constructs the $n.name().
#foreach( $i in $n.getAllParameters() )
#set( $sep = "@param " )
#foreach( $s in $i.descr() )
 * $sep$i.name() $s
#set( $sep = "" )
#end
#end
 */
$class::$n.name()::$n.name()(#set($sep = "")#foreach($i in $n.getAllParameters())$sep$helper.getEtchTypeName($i.type(), true) $i.name() #set( $sep = ", " )#end)
#if($n.hasExtends())
  : $n.getExtends().name()(#set($sep = "")#foreach($i in $n.getExtends().getAllParameters())$sep$i.name()#set( $sep = ", " )#end)
#else
#if($n.isExcept())
  : EtchException("${n.name()}", ETCH_ERROR, EXCPTYPE_USERDEFINED)
#end
#end
{
  addObjectType($class::$n.name()::TYPE());
#foreach( $i in $n.getParameters() )
  this->$i.name() = $i.name();
#end
}

#if(! $n.isExcept() )

EtchStringPtr $class::$n.name()::toString()
{
  //TODO: $helper.formatString( $n, false );
  return NULL;
}

#end

#foreach( $i in $n.iterator() )

/**
 * Gets the value.
 *
#foreach( $s in $i.descr() )
 * $s
#end
 *
 * @return the value.
 */
$helper.getEtchTypeName($i.type(), true) $class::$n.name()::$helper.getGetterName($i.name())()
{
  return $i.name();
}

/**
 * Sets the value.
 *
#foreach( $s in $i.descr() )
 * $s
#end
 *
 * @param value the value.
 */
void $class::$n.name()::$helper.getSetterName($i.name())( $helper.getEtchTypeName($i.type(), true) value )
{
  this->$i.name() = value;
}
#end
#end
#end
#end
#end

status_t $class::_sessionQuery(capu::SmartPointer<EtchObject> query, capu::SmartPointer<EtchObject> &result)
{
  return ETCH_EUNIMPL;
}
status_t $class::_sessionControl(capu::SmartPointer<EtchObject> control, capu::SmartPointer<EtchObject> value)
{
  return ETCH_EUNIMPL;
}

status_t $class::_sessionNotify(capu::SmartPointer<EtchObject> event )
{
  return ETCH_EUNIMPL;
}
