<?xml version="1.0" encoding="UTF-8"?>
<!--
    Copyright 2004 P&P Software GmbH                                                                                 
-->
<!--
This is the code generator for the header and body files of a custom FsmState class.
This XSL program process the XML-based application model.
The XSL program searches the application model for all "FsmState" elements
which have a "Custom" subelement that indicates that a custom FsmState
class must be created. For each such element a class header file and a class
body files are created.
The base class of the generated class is assumed to be the class in the
"type" attribute of the FsmState element.

NB: This program writes its outputs (the header and body files) to documents that are 
opened using the "xsl:document" instruction. The directory where these files
are written must apparently be specified through an absolute path names (this
seems to be in contrast with the documentation of xsl:document and may be a
bug in the XSLT provessor). This directory is hardcoded in variable
$TargetFile.

@todo: 
      - add treatment of default attributes
      - add setting of class identifier in the constructor body
-->
<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="'../'"/>
<!--
       Include general utility rules
-->
<xsl:include href="WriteCommentBody.xsl"/>
<xsl:include href="ClassNameFromPath.xsl"/>
<!--
    Top-Level Rule (iterates over all FsmState elements with a Custom subelement)
-->
<xsl:template match="/ObsApplication">
      <!-- write warning about the location of the output file -->
       WARNING: this XSL program hardcodes the directory where output files are written in variable $TargetFile
            
      <xsl:for-each select="//FsmState[Custom]">
            <xsl:variable name="SuperClassName">
                  <xsl:call-template name="ClassNameFromPath">
                        <xsl:with-param name="path" select="@type"/>
                  </xsl:call-template>
            </xsl:variable>
            <xsl:variable name="ClassName">
                  <xsl:call-template name="ClassNameFromPath">
                        <xsl:with-param name="path" select="Custom/@type"/>
                  </xsl:call-template>
            </xsl:variable>
            <xsl:variable name="TargetFile" select="concat('/Projects/ObsFramework/src/cpp/',Custom/@type)"/>     
            Generating code for class <xsl:value-of select="$ClassName"/> in files <xsl:value-of select="$TargetFile"/>.h/.cpp

            <!-- Check whether writing to an output file is possible -->
            <xsl:if test="not(element-available('xsl:document'))">
                  FATAL ERROR: the xsl:document element is not supported. Header files cannot be written! This element
                  is normally supported only in version 1.1 of XSL.
            </xsl:if>
            
            <!-- ===================================================================================
                   Create the header file  
                   ===================================================================================-->
             <xsl:document href="{$TargetFile}.h" omit-xml-declaration="yes" method="text">  
//
// Copyright 2004 P&amp;P Software GmbH - All Rights Reserved
//
// <xsl:value-of select="$ClassName"/>.h
//
// This file was automatically generated by an XSL program

#ifndef <xsl:value-of select="$ClassName"/>H
#define <xsl:value-of select="$ClassName"/>H

#include "<xsl:value-of select="$codeDir"/>GeneralInclude/ForwardDeclarations.h"
#include "<xsl:value-of select="$codeDir"/>GeneralInclude/BasicTypes.h"
#include "<xsl:value-of select="$codeDir"/><xsl:value-of select="@type"/>.h"

/**
<xsl:call-template name="WriteCommentBody">
         <xsl:with-param name="text" select="normalize-space(Custom/Description)"/>
         <xsl:with-param name="indent" select="' '"/>
</xsl:call-template>
 * &lt;p&gt;
 * This is a stub class. It provides dummy implementations for some of the virtual
 * methods of its superclass. 
 * This class was automatically generated by an XSL program that processes the
 * XML-based &lt;i&gt;target application model&lt;/i&gt;. The XSL program  
 * searches the application model for all "FsmState" elements
 * which have a "Custom" subelement that indicates that a custom FsmState
 * class must be created. For each such element a class header file is created.
 * The base class of the generated class is assumed to be the class in the
 * "type" attribute of the FsmState element. 
 * The information in the application model is used to decide which virtual methods
 * should be overridden.
 * @todo Modify the generator meta-component generateRecoveryAction to generate the code
 * that sets the class identifier and to treat the default attributes in the custom recovery action description.
 * @author Automatically Generated Class
 * @version 1.0
 */
class <xsl:value-of select="$ClassName"/> : public <xsl:value-of select="$SuperClassName"/> {

  public: 
  
    /**
     * Stub constructor that returns without taking any action.
     */
    <xsl:value-of select="$ClassName"/>(void);
    
    <xsl:if test="Custom/InitAction">
    /**
<xsl:call-template name="WriteCommentBody">
         <xsl:with-param name="text" select="normalize-space(Custom/InitAction/Description)"/>
         <xsl:with-param name="indent" select="'     '"/>
</xsl:call-template>
     * &lt;p&gt;
     * This is a stub method that must be completed by the application developer.
     * This stub provides a default implementation that calls the &lt;code&gt;doInit&lt;/code&gt; 
     * method of the superclass.
     */
    virtual void doInit(void);
    </xsl:if>
 
    <!-- NB: Treatment of the continuation action is different because method doContinue in class FsmState is pure virtual -->
    <xsl:choose>
          <xsl:when test="Custom/ContinuationAction">
    /**
<xsl:call-template name="WriteCommentBody">
         <xsl:with-param name="text" select="normalize-space(Custom/ContinuationAction/Description)"/>
         <xsl:with-param name="indent" select="'     '"/>
</xsl:call-template>
     * &lt;p&gt;
     * This is a stub method that must be completed by the application developer.
     * This stub provides a default implementation that returns without taking any action.
     */
    virtual void doContinue(void);
          </xsl:when>
          <xsl:otherwise>
    /**
     * Dummy implementation that returns without taking any action. There is no continuation
     * action associated to this class.
     */
    virtual void doContinue(void);
          </xsl:otherwise>
    </xsl:choose>
    
    <xsl:if test="Custom/ExitAction">
    /**
<xsl:call-template name="WriteCommentBody">
         <xsl:with-param name="text" select="normalize-space(Custom/ExitAction/Description)"/>
         <xsl:with-param name="indent" select="'     '"/>
</xsl:call-template>
     * &lt;p&gt;
     * This is a stub method that must be completed by the application developer.
     * This stub provides a default implementation that calls the &lt;code&gt;doExit&lt;/code&gt; 
     * method of the superclass.
     */
    virtual void doExit(void);
    </xsl:if>
             
    <xsl:if test="Custom/EntryCheck">
    /**
<xsl:call-template name="WriteCommentBody">
         <xsl:with-param name="text" select="normalize-space(Custom/EntryCheck/Description)"/>
         <xsl:with-param name="indent" select="'     '"/>
</xsl:call-template>
     * &lt;p&gt;
     * This is a stub method that must be completed by the application developer.
     * This stub provides a default implementation that calls the &lt;code&gt;canEnter&lt;/code&gt; 
     * method of the superclass.
     * @return true if the state can be entered, false otherwise
     */
    virtual bool canEnter(void);
    </xsl:if>
                          
    <xsl:if test="Custom/ExitCheck">
    /**
<xsl:call-template name="WriteCommentBody">
         <xsl:with-param name="text" select="normalize-space(Custom/ExitCheck/Description)"/>
         <xsl:with-param name="indent" select="'     '"/>
</xsl:call-template>
     * &lt;p&gt;
     * This is a stub method that must be completed by the application developer.
     * This stub provides a default implementation that calls the &lt;code&gt;canExit&lt;/code&gt; 
     * method of the superclass.
     * @return true if the state can be exited, false otherwise
     */
    virtual bool canExit(void);
    </xsl:if>
             
    <xsl:if test="Custom/TerminationCheck">
    /**
<xsl:call-template name="WriteCommentBody">
         <xsl:with-param name="text" select="normalize-space(Custom/TerminationCheck/Description)"/>
         <xsl:with-param name="indent" select="'     '"/>
</xsl:call-template>
     * &lt;p&gt;
     * This is a stub method that must be completed by the application developer.
     * This stub provides a default implementation that calls the &lt;code&gt;isFinished&lt;/code&gt; 
     * method of the superclass.
     * @return true if the continuation action of this state has terminated, false otherwise
     */
    virtual bool isFinished(void);
    </xsl:if>
};
            
#endif
             </xsl:document>
             
            <!-- ===================================================================================
                   Create the body file  
                   ===================================================================================-->
             <xsl:document href="{$TargetFile}.cpp" omit-xml-declaration="yes" method="text">  
//
// 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/CompilerSwitches.h"
#include "<xsl:value-of select="$codeDir"/>GeneralInclude/Constants.h"
#include "<xsl:value-of select="$codeDir"/><xsl:value-of select="@type"/>.h"
#include "<xsl:value-of select="$codeDir"/><xsl:value-of select="Custom/@type"/>.h"

<xsl:value-of select="$ClassName"/>::<xsl:value-of select="$ClassName"/>(void) {
      // insert application-specific code here
}
    
    <xsl:if test="Custom/InitAction">
void <xsl:value-of select="$ClassName"/>::doInit(void) {
      <xsl:value-of select="$SuperClassName"/>::doInit();
      // remove previous statement and insert application-specific code here
}
    </xsl:if>
    
    <xsl:choose>
          <xsl:when test="Custom/ContinuationAction">
void <xsl:value-of select="$ClassName"/>::doContinue(void) {
      return;
      // remove previous statement and insert application-specific code here
}
          </xsl:when>
          <xsl:otherwise>
void <xsl:value-of select="$ClassName"/>::doContinue(void) {
      return;
}
          </xsl:otherwise>
    </xsl:choose>
    
    <xsl:if test="Custom/ExitAction">
void <xsl:value-of select="$ClassName"/>::doExit(void) {
      <xsl:value-of select="$SuperClassName"/>::doExit();
      // remove previous statement and insert application-specific code here
}
    </xsl:if>
             
    <xsl:if test="Custom/EntryCheck">
bool <xsl:value-of select="$ClassName"/>::canEnter(void) {
      return <xsl:value-of select="$SuperClassName"/>::canEnter();
      // remove previous statement and insert application-specific code here
}
    </xsl:if>
                          
    <xsl:if test="Custom/ExitCheck">
bool <xsl:value-of select="$ClassName"/>::canExit(void) {
      return <xsl:value-of select="$SuperClassName"/>::canExit();
      // remove previous statement and insert application-specific code here
}
    </xsl:if>
             
    <xsl:if test="Custom/TerminationCheck">
bool <xsl:value-of select="$ClassName"/>::isFinished(void) {
      return <xsl:value-of select="$SuperClassName"/>::isFinished();
      // remove previous statement and insert application-specific code here
}
    </xsl:if>
            </xsl:document>
      </xsl:for-each>
</xsl:template>




</xsl:stylesheet>

