<?xml version="1.0" encoding="UTF-8"?>

<!--================================================================-->
<!-- Copyright 2004 P&P Software GmbH                                                                                  -->
<!--================================================================-->

<!--===================================================================
This is the code generator for the body file of the application component factory for the 
OBS Framework.

This XSL program process the XML-based application model.
===================================================================-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.1"  xmlns:lxslt="http://xml.apache.org/xslt">

<xsl:strip-space elements="*"/>
<xsl:output omit-xml-declaration="yes" method="text"/>
<!--
    Global Variables                                                                                                                      
-->
<xsl:variable name="codeDir" select="'../'"/>
<xsl:variable name="className" select="'CC_ComponentFactory'"/>
<xsl:variable name="numberOfComponents" select="count(//*[(@kind='component') and (@name)])"/>
<!--
       Include general utility rules
-->
<xsl:include href="WriteCommentBody.xsl"/>
<xsl:include href="ClassNameFromPath.xsl"/>
<xsl:include href="TruncatedClassNameFromPath.xsl"/>
<xsl:include href="TypeNameFromPath.xsl"/>
<xsl:include href="ConfigureObsClock.xsl"/>
<xsl:include href="ConfigureEventRepository.xsl"/>
<xsl:include href="ConfigureFSM.xsl"/>
<xsl:include href="ConfigureControlBlock.xsl"/>
<xsl:include href="ConfigureControlAction.xsl"/>
<xsl:include href="ConfigureDataPool.xsl"/>
<xsl:include href="ConfigureParameterDatabase.xsl"/>
<xsl:include href="ConfigureRootObject.xsl"/>
<xsl:include href="ConfigureFunctionalityManagers.xsl"/>
<!--
    Top-Level Rule                                                 
-->
<xsl:template match="/ObsApplication">
//
// Copyright 2004 P&amp;P Software GmbH - All Rights Reserved
//
// <xsl:value-of select="$className"/>.cpp
//
// This file was automatically generated by an XSL program

#include "<xsl:value-of select="$codeDir"/>GeneralInclude/ForwardDeclarations.h"
#include "<xsl:value-of select="$codeDir"/>GeneralInclude/CompilerSwitches.h"
#include "<xsl:value-of select="$codeDir"/>GeneralInclude/DebugSupport.h"
#include "<xsl:value-of select="$codeDir"/>GeneralInclude/BasicTypes.h"
#include "<xsl:value-of select="$codeDir"/>GeneralInclude/Constants.h"
#include "<xsl:value-of select="$className"/>_inc.h"
#include "<xsl:value-of select="$className"/>.h"
#include "<xsl:value-of select="$codeDir"/>Base/CC_RootObject.h"   
<xsl:variable name="temp">
<xsl:for-each select="//*[(@kind='component') and (@name)]">  
   <xsl:element name="type"><xsl:value-of select="@type"/></xsl:element>
</xsl:for-each>
</xsl:variable>

<xsl:variable name="sortedTemp">
<xsl:for-each select="$temp/type">
    <xsl:sort/>
   <xsl:element name="type"><xsl:value-of select="."/></xsl:element>
</xsl:for-each>
</xsl:variable>

<xsl:for-each select="$sortedTemp/type">
      <xsl:variable name="value" select="."/>
      <xsl:variable name="count" select="position()"/>
      <xsl:variable name="previousValue" select="../type[position()=number($count)-1]"/>
      <xsl:if test="not($value=$previousValue)">
#include "<xsl:value-of select="$codeDir"/><xsl:value-of select="$value"/>.h"        <xsl:text/>
      </xsl:if>
</xsl:for-each>

// Disable type mismatch warning that arise when calling
// the configuration methods on monitoring profiles
#pragma warning( disable : 4305 )

<xsl:variable name="ParDatabaseSize">
<xsl:choose>
      <xsl:when test="//BasicDatabase">
            <xsl:value-of select="//DatabaseSize/@value"/>
      </xsl:when>
      <xsl:when test="//IndexedDatabase">
            <xsl:value-of select="//IndexedDatabase/Size/@value"/>
      </xsl:when>
      <xsl:otherwise>
            -- ERROR: no size information for the parameter database
      </xsl:otherwise>
</xsl:choose>
</xsl:variable>

// Create the parameter database storage areas. In an operational
// context the two pointers should be made to point to the database
// operational and default tables. The names of the pointers must 
// match the names in the parameter database application models.
char* PARDATABASE_OP_TABLE_START = new char[<xsl:value-of select="$ParDatabaseSize"/>];
char* PARDATABASE_DEF_TABLE_START = new char[<xsl:value-of select="$ParDatabaseSize"/>];

// Create the telecommand storage area. In an operational setting,
// this should be linked to the area where TCs are written. The name
// used here must match the name used in the telecommand loader model and
// the size of the allocated memory should be consistent with the configuration
// parameters of the telecommand loader.
unsigned char* TC_LOADER_AREA_START = new unsigned char[1000];

// Create the telemetry storage area. In an operational setting,
// this should be linked to the area from where TMs are read. The name
// used here must match the name used in the telemetry stream model and
// the size of the allocated memory should be consistent with the configuration
// parameters of the telemetry stream.
unsigned char* TM_STREAM_START = new unsigned char[5000];

<xsl:value-of select="$className"/>* <xsl:value-of select="$className"/>::pInstance = pNULL;

<xsl:value-of select="$className"/>::<xsl:value-of select="$className"/>(void) {

   <!-- configure the system list size (this must be done before any application components are instantiated) -->
   <xsl:variable name="numberOfObjects" select="count(//*[@kind='component'][@name])"/>
   // Initialize the system list size. The size is computed as the number of components
   // defined in the application model plus a (heuritically defined) margin of ten to
   // account for components that are created internally to other components
   CC_RootObject::setSystemListSize(<xsl:value-of select="$numberOfObjects"/>+10);

<xsl:for-each select="//*[(@kind='component') and (@name)]">  
      <xsl:variable name="ClassName">
            <xsl:call-template name="ClassNameFromPath">
                  <xsl:with-param name="path" select="@type"/>
            </xsl:call-template>
      </xsl:variable>    
      <xsl:variable name="TypeName">
            <xsl:call-template name="TypeNameFromPath">
                  <xsl:with-param name="path" select="@type"/>
            </xsl:call-template>
      </xsl:variable>    
      <xsl:text>   </xsl:text><xsl:value-of select="@name"/> = new <xsl:value-of select="$ClassName"/>();
   list[<xsl:value-of  select="position()"/>] = <xsl:value-of select="@name"/>;
   type[<xsl:value-of  select="position()"/>] =  <xsl:value-of select="$TypeName"/>;
</xsl:for-each>
}

<xsl:value-of select="$className"/>* <xsl:value-of select="$className"/>::getInstance(void) {
   if (pInstance==pNULL)
      pInstance = new <xsl:value-of select="$className"/>();
   return pInstance;
}

void <xsl:value-of select="$className"/>::configureApplication(void) {
   configureRootObject();
   <xsl:if test="EventRepository">configureEventRepository();</xsl:if><xsl:text>
   </xsl:text>   <xsl:if test="ObsClock">configureObsClock();</xsl:if><xsl:text>
   </xsl:text>   <xsl:if test="DataPool">configureDataPool();</xsl:if><xsl:text>
   </xsl:text>   <xsl:if test="ParameterDatabase">configureParameterDatabase();</xsl:if><xsl:text>
   </xsl:text>   <xsl:if test="FSM">configureFSM();</xsl:if><xsl:text>
   </xsl:text>   <xsl:if test="FSM">configureFunctionalityManagers();</xsl:if><xsl:text>
   </xsl:text>   <xsl:if test="ControllerManagement">configureControllers();</xsl:if>
}

void <xsl:value-of select="$className"/>::configureRootObject(void) {
   <xsl:call-template name="configureRootObject"/>
}

<xsl:if test="ObsClock">
void <xsl:value-of select="$className"/>::configureObsClock(void) {
   <xsl:apply-templates select="ObsClock"/>
}
</xsl:if>

<xsl:if test="EventRepository">
void <xsl:value-of select="$className"/>::configureEventRepository(void) {
   <xsl:apply-templates select="EventRepository"/>
}
</xsl:if>

<xsl:if test="FSM">
void <xsl:value-of select="$className"/>::configureFSM(void) {
   <xsl:apply-templates select="FSM"/>
   <!-- Reset all FSMs (this must be done only after all FSMs and FsmStates have been configured -->
<xsl:text>
   </xsl:text>// ---- Reset all the FSM  ----
<xsl:text/>
   <xsl:for-each select="//FSM">
            <xsl:variable name="fsm" select="@name"/>
            <xsl:text>   </xsl:text><xsl:value-of select="$fsm"/>->reset();
<xsl:text/>
   </xsl:for-each>
}
</xsl:if>

<xsl:if test="ControllerManagement">
void <xsl:value-of select="$className"/>::configureControllers(void) {
      <xsl:apply-templates select="ControllerManagement/ControlAction/ControlBlock"/>           
      <xsl:apply-templates select="ControllerManagement/ControlAction"/>           
}     
</xsl:if>

 <xsl:if test="DataPool">
void <xsl:value-of select="$className"/>::configureDataPool(void) {
   <xsl:apply-templates select="DataPool"/>
}
</xsl:if>

 <xsl:if test="ParameterDatabase">
void <xsl:value-of select="$className"/>::configureParameterDatabase(void) {
   <xsl:apply-templates select="ParameterDatabase"/>
}
</xsl:if>

void <xsl:value-of select="$className"/>::configureFunctionalityManagers(void) {
   <xsl:apply-templates select="ManoeuvreManagement/ManoeuvreManager"/>
   <xsl:apply-templates select="TelecommandManagement/TelecommandManager"/>
   <xsl:apply-templates select="TelemetryManagement/TelemetryManager"/>
}

</xsl:template>

<!-- =================================================================== -->
<!-- Residual rule to catch elements that do not need to be processed -->

<xsl:template match="*|@*|text()">
</xsl:template>



</xsl:stylesheet>

