<#--
  Library of macros
-->


<#import "NormalClassDeclaration.java" as NCDecl />
<#import "EnumDeclaration.java" as EnDecl />
<#import "InterfaceDeclaration.java" as InDecl />


<#-- constants -->
<#assign JAVA_IDENT="    " />
<#assign BETWEEN_FIELDS_LINE_SPACING="\n" />
<#assign BETWEEN_METHODS_LINE_SPACING="\n" />
<#assign BETWEEN_TYPES_LINE_SPACING="\n" />


<#macro PackageDeclaration classInfo>
<#if classInfo.getPackage()?? && (classInfo.getPackage()?length > 0) >  
package ${classInfo.getPackage()};

</#if>
</#macro>


<#macro ImportDeclarations classInfo>
<#if classInfo.getImportedTypes()?? >
<#list classInfo.getImportedTypes() as type>
<@ImportDeclaration type />
</#list>
</#if>
</#macro>


<#macro ImportDeclaration type>
import ${type}; 
</#macro>


<#macro TypeDeclaration classInfo nestingLevel > 
<#if classInfo.isInterface()> 
<@InDecl.InterfaceDeclaration classInfo nestingLevel />
<#elseif classInfo.isEnumeration()> 
<@EnDecl.EnumDeclaration classInfo nestingLevel />
<#else>
<@NCDecl.NormalClassDeclaration classInfo nestingLevel />
</#if>
</#macro>


<#macro TypeDeclarationComment classInfo nestingLevel >
<@MemberDeclarationComment classInfo nestingLevel />
</#macro>


<#macro MemberDeclarationComment memberInfo nestingLevel >
<@CommonDeclarationComment memberInfo nestingLevel />
<@idMarker memberInfo nestingLevel />
</#macro>


<#macro MethodDeclarationComment methodInfo nestingLevel >
<@CommonDeclarationComment methodInfo nestingLevel />
<#if methodInfo.getMemberName()?? >
<@idMarkerBody methodInfo "yes" nestingLevel />
<#else>
<@idMarker methodInfo nestingLevel />
</#if>
</#macro>


<#macro CommonDeclarationComment memberInfo nestingLevel >
<#if memberInfo.getComment()?? >
<#assign comment=memberInfo.getComment() />
<@ident nestingLevel />/**
<#list comment?split("\n") as line >
<@ident nestingLevel /> *  ${line}
</#list>
<@ident nestingLevel /> */
</#if>
</#macro>


<#macro TypeDeclarationModifiers classInfo >
${classInfo.getModifierText(classInfo.getModifiers())}
</#macro>


<#macro TypeDeclarationTypeParameters classInfo >
<#if classInfo.getClassElement()?? >
<#assign classifier=classInfo.getClassElement() />
<#if classifier.getTemplateParameters()?? && (classifier.getTemplateParameters()?size > 0) >
<#assign templatesList >
<@commaSpaceSeparatedList classifier.getTemplateParameters() />
</#assign> 	
<#-- -->
<#if ((templatesList?trim)?length > 0 ) >
< ${templatesList} >
</#if>
</#if> 	
</#if> 
</#macro>


<#macro NormalClassExtends classInfo >
<@singleline>
<#if  classInfo.getSuperClassInfo()?? > 
extends ${classInfo.getSuperClassInfo().getCodeGenType(false, classInfo)} 
</#if>
</@singleline>
</#macro>

<#macro ClassImplements classInfo >
<@singleline>
<#if  classInfo.getSuperInterfaceInfos()?? && (classInfo.getSuperInterfaceInfos()?size > 0) >
implements 
<#list classInfo.getSuperInterfaceInfos() as interfaceInfo > 
 ${interfaceInfo.getCodeGenType(false, classInfo)}
<#if interfaceInfo_has_next>
,
</#if>
</#list>
</#if>
</@singleline>
</#macro>


<#macro InterfaceExtends classInfo >
<@singleline>
<#if  classInfo.getSuperInterfaceInfos()?? && (classInfo.getSuperInterfaceInfos()?size > 0) >
extends 
<#list classInfo.getSuperInterfaceInfos() as interfaceInfo > 
 ${interfaceInfo.getCodeGenType(false, classInfo)}
<#if interfaceInfo_has_next>
,
</#if>
</#list>
</#if>
</@singleline>
</#macro>


<#macro ClassBodyDeclaration classInfo nestingLevel >
<@noSpaceIfEmpty >

<@FieldDeclarations classInfo nestingLevel/>
</@noSpaceIfEmpty ><@noSpaceIfEmpty >

<@ConstructorDeclarations classInfo nestingLevel />
</@noSpaceIfEmpty ><@noSpaceIfEmpty >

<@MethodDeclarations classInfo nestingLevel />
</@noSpaceIfEmpty ><@noSpaceIfEmpty >

<@MemberTypeDeclarations classInfo nestingLevel />
</@noSpaceIfEmpty >
</#macro>


<#macro FieldDeclarations classInfo nestingLevel >
<#if classInfo.getFieldsCodeGenSorted()?? >
<#list classInfo.getFieldsCodeGenSorted() as fieldInfo > 
<@FieldDeclaration fieldInfo nestingLevel />
<#if fieldInfo_has_next>${BETWEEN_FIELDS_LINE_SPACING}</#if>
</#list>
</#if>
</#macro>


<#macro FieldDeclaration fieldInfo nestingLevel >
<@MemberDeclarationComment fieldInfo nestingLevel />
<@ident nestingLevel /><@compress single_line=true>
${classInfo.getModifierText(fieldInfo.getModifiers())} ${fieldInfo.getCodeGenType()!} ${fieldInfo.getName()!}
<#if fieldInfo.getInitializer()??> 
= ${fieldInfo.getInitializer()}
</#if></@compress>;<#return />
</#macro>


<#macro ConstructorDeclarations classInfo nestingLevel >
<#if classInfo.getConstructorsCodeGenSorted()?? >
<#list classInfo.getConstructorsCodeGenSorted() as methodInfo > 
<@ConstructorDeclaration methodInfo nestingLevel />
<#if methodInfo_has_next>${BETWEEN_METHODS_LINE_SPACING}</#if>
</#list>
</#if> 
</#macro>


<#macro ConstructorDeclaration methodInfo nestingLevel >
<@MemberDeclarationComment methodInfo nestingLevel />
<@ident nestingLevel /><@compress single_line=true>
${classInfo.getModifierText(methodInfo.getModifiers())} ${methodInfo.getName()!} <@MethodDeclarationFormalParameters methodInfo /> <@MethodDeclarationThrows methodInfo /> 
</@compress> 
<@ConstructorDeclarationBody methodInfo nestingLevel />
</#macro>


<#macro ConstructorDeclarationBody methodInfo nestingLevel >
 {
<@singleline>
<@ident nestingLevel />}
</@singleline>
</#macro>


<#macro MethodDeclarations classInfo nestingLevel >
<#if classInfo.getMethodsCodeGenSorted()?? >
<#list classInfo.getMethodsCodeGenSorted() as methodInfo > 
<@MethodDeclaration methodInfo nestingLevel />
<#if methodInfo_has_next>${BETWEEN_METHODS_LINE_SPACING}</#if>
</#list>
</#if>
</#macro>


<#macro MethodDeclaration methodInfo nestingLevel >
<@MethodDeclarationComment methodInfo nestingLevel />
<@ident nestingLevel /><@compress single_line=true><@compress single_line=true>
${classInfo.getModifierText(methodInfo.getModifiers())} ${methodInfo.getCodeGenReturnType()!} ${methodInfo.getName()!} <@MethodDeclarationFormalParameters methodInfo /> <@MethodDeclarationThrows methodInfo /> 
</@compress><#if (methodInfo.isAbstract() || methodInfo.isNative() ) >;</#if>
</@compress> 
<#if ! ( methodInfo.isAbstract() || methodInfo.isNative() ) >
<@MethodDeclarationBody methodInfo nestingLevel />
</#if>
</#macro>


<#macro MethodDeclarationBody methodInfo nestingLevel >
 {
<#if methodInfo.getMemberName()?? >
<@MethodBodyGetterSetter methodInfo nestingLevel+1 />
<#else>
<@MethodBodyDefaultReturn methodInfo nestingLevel+1 />
</#if>
<@singleline>
<@ident nestingLevel />}
</@singleline>
</#macro>


<#macro MethodBodyGetterSetter methodInfo nestingLevel >
<#if methodInfo.getMemberName()?? >
<@singleline>
<#if methodInfo.isAccessor() >
<@ident nestingLevel />return ${methodInfo.getMemberName()};
<#else>
<#if methodInfo.getParameterInfos()?? && (methodInfo.getParameterInfos()?size > 0) >
<#assign params=methodInfo.getParameterInfos() />
<@ident nestingLevel />this.${methodInfo.getMemberName()!} = ${params[0].getName()!};
</#if>
</#if>
</@singleline>

</#if>
</#macro>


<#macro MethodBodyDefaultReturn methodInfo nestingLevel >
<#if methodInfo.getDefaultReturnValue()?? >
<@singleline>
<@ident nestingLevel />return ${methodInfo.getDefaultReturnValue()};
</@singleline>

<#else><@singleline></@singleline>
</#if>
</#macro>


<#macro MethodDeclarationThrows methodInfo >
<@singleline>
<#if methodInfo.getExceptions()?? && (methodInfo.getExceptions()?size > 0) >
<#assign exceptionsList >
<@commaSpaceSeparatedList methodInfo.getExceptions() />
</#assign> 	
<#if ((exceptionsList?trim)?length > 0 ) >
throws ${exceptionsList}
</#if>
</#if>
</@singleline>
</#macro>


<#macro MethodDeclarationFormalParameters methodInfo >
(<@singleline>
<#if methodInfo.getParameterInfos()?? && (methodInfo.getParameterInfos()?size > 0) >
<#list methodInfo.getParameterInfos() as parameterInfo> 
${(parameterInfo.getCodeGenType())!} ${(parameterInfo.getName())!}<#if parameterInfo_has_next>, </#if>
</#list>
</#if>
</@singleline>)
</#macro>


<#macro MemberTypeDeclarations classInfo nestingLevel >
<#if classInfo.getMemberTypes()?? >
<#list classInfo.getMemberTypes() as memberType >
<@TypeDeclaration memberType nestingLevel />
<#if memberType_has_next>${BETWEEN_TYPES_LINE_SPACING}<#else></#if>
</#list>
</#if>
</#macro>


<#macro EnumBodyDeclaration classInfo nestingLevel >
<@noSpaceIfEmpty >

<@EnumLiterals  classInfo nestingLevel />

</@noSpaceIfEmpty >
<@ClassBodyDeclaration classInfo nestingLevel />
</#macro>


<#macro EnumLiterals classInfo nestingLevel >
<#if classInfo.getLiterals()?? && (classInfo.getLiterals()?size > 0) >
<#list classInfo.getLiterals() as literal >
<#if literal.getName()?? >
<@MemberDeclarationComment literal nestingLevel />
<@ident nestingLevel />${literal.getName()}<@literalArguments literal /><#if literal_has_next>,${BETWEEN_FIELDS_LINE_SPACING}<#else>;</#if>
</#if>
</#list>
<#else>
<@ident nestingLevel />;
</#if>
</#macro>


<#macro literalArguments literal >
<@singleline>
<#if literal.getLiteral().getTaggedValueByName("JavaEnumLiteralArguments")?? >
<#if literal.getLiteral().getTaggedValueByName("JavaEnumLiteralArguments").getDataValue()?? >
(${literal.getLiteral().getTaggedValueByName("JavaEnumLiteralArguments").getDataValue()})
</#if>
</#if>
</@singleline>
</#macro>


<#macro idMarker elementInfo nestingLevel>
<#if codegenOptions["GENERATE_MARKER_ID"]?? && codegenOptions["GENERATE_MARKER_ID"] >
<@ident nestingLevel />// <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
<@ident nestingLevel />// #[regen=yes,id=${elementInfo.getMarkerID()}]
<@ident nestingLevel />// </editor-fold> 
</#if>
</#macro>


<#macro idMarkerBody elementInfo regenBody nestingLevel>
<#if codegenOptions["GENERATE_MARKER_ID"]?? && codegenOptions["GENERATE_MARKER_ID"] >
<@ident nestingLevel />// <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
<@ident nestingLevel />// #[regen=yes,regenBody=${regenBody},id=${elementInfo.getMarkerID()}]
<@ident nestingLevel />// </editor-fold> 
</#if>
</#macro>


<#--
 #  common utilities
 -->


<#macro commaSpaceSeparatedList list >
<@compress single_line=true>
<@singleline>
<#if list?? && (list?size > 0) >
<#assign comma=false />
<#list list as item >
<@compress single_line=true>
<@singleline>
<#assign listItem=item?trim /> 
<#if (listItem?length > 0)  >
<#if comma >
,
</#if>
 ${listItem}
<#assign comma=true />
</#if>		<#-- listItem?length > 0 -->
</@singleline>
</@compress>
</#list>	<#-- list as item -->
</#if>		<#-- list?? && (list?size > 0) -->
</@singleline>	
</@compress>
</#macro>


<#-- 
 #  some formatting utilities 
 #-->


<#macro ident nestingLevel > 
<@singleline >
<#if (nestingLevel > 0) >
${JAVA_IDENT}
<@ident (nestingLevel - 1) />
</#if>
</@singleline>
</#macro>


<#macro singleline >
<#assign input >
<#nested />
</#assign>
<#assign output >
${input?replace("\r\n","")}</#assign >
${output?replace("\n","")}<#return />
</#macro> 


<#-- standard compress somehow didn't make it into integrated version -->
<#macro compress single_line >
<#assign input >
<#nested />
</#assign>
<#assign words =input?word_list >
<@singleline >
<#list words as word>${word}
<#if word_has_next> </#if>
</#list>
</@singleline >
</#macro> 


<#macro noSpaceIfEmpty >
<#assign input >
<@compress true><#nested /></@compress>
</#assign>
<#assign isEmpty=input?matches("\\w*") />
<#if isEmpty><#else><#nested /></#if><#return />
</#macro> 


 






