<?xml version="1.0" encoding="iso-8859-1"?>
<!--
  ** Author: Marco Ladermann (<marco.ladermann@gmx.de>)
  ** Date:   Sat Feb 01 18:26:59 CET 2003 @768 /Internet Time/
  **
  ** This software is free software. It is released under the terms of the
  ** GNU Lesser General Public Licence (LGPL)
  ** see http://www.gnu.org/copyleft/lesser.html
  **
  ** These stylesheets are distributed in the hope that they will be useful,
  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  -->
<xsl:stylesheet 
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:exsl="http://exslt.org/common"
    xmlns:set="http://exslt.org/sets"
    extension-element-prefixes="exsl set"
>
    <xsl:import href="classes.xsl"/>
    <xsl:import href="properties.xsl"/>
    
    <xsl:output encoding="utf-8" indent="no" method="text"/>

    <!--
    <xsl:variable name="QtClasses" select="document('QtClasses.xml')"/>
    -->

    <!--
      ** Matching the root node call named templates to do all the work
      ** @param data opaque data for user purpose
      -->
    <xsl:template match="/" mode="main">
        <xsl:param name="data"/>
        <xsl:message>Java package    : "<xsl:value-of select="$package"/>"</xsl:message>
        <xsl:message>Abstract slots  : "<xsl:value-of select="$abstract"/>"</xsl:message>
        <xsl:message>Method main     : "<xsl:value-of select="$main"/>"</xsl:message>
        <xsl:message>Image directory : "<xsl:value-of select="$images"/>"</xsl:message>
        <xsl:message>Output directory: "<xsl:value-of select="$outdir"/>"</xsl:message>
        <xsl:message>OS type         : "<xsl:value-of select="$os"/>"</xsl:message>
        <xsl:message></xsl:message>
        <xsl:if test="$abstract and $main">
            <xsl:message>Class will be abstract without main method</xsl:message>
        </xsl:if>
        <xsl:call-template name="createFileHeader">
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
        <xsl:call-template name="createClassPreamble">
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
        <xsl:call-template name="createClassHeader">
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
        <xsl:call-template name="createInstanceVariables">
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
        <xsl:call-template name="createConstructors">
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
        <xsl:call-template name="createSlots">
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
        <xsl:call-template name="createMethods">
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
        <xsl:call-template name="createMain">
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
        <xsl:call-template name="createClassFooter">
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
    </xsl:template>

    <!-- 
      ** Create the file header 
      ** @param data opaque data for user purpose
      -->
    <xsl:template name="createFileHeader">
        <xsl:param name="data"/>
        <xsl:call-template name="putFileHeader">
            <xsl:with-param name="comment" select="/UI/comment"/>
            <xsl:with-param name="author" select="/UI/author"/>
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
    </xsl:template>

    <!--
      ** Finds all Qt classes to import and forwards a set of them to the
      ** template "putClassPreamble". The set of classes is given as a set
      ** of class-tagged names.
      ** @param data opaque data for user purpose
      -->
    <xsl:template name="createClassPreamble">
        <xsl:param name="data"/>
        <xsl:variable name="classes.tf">
            <xsl:if test="not($abstract) and $main">
                <xsl:choose>
                    <xsl:when test="$kde">
                        <class>KApplication</class>
                        <class>KCmdLineArgs</class>
                    </xsl:when>
                    <xsl:otherwise>
                        <class>QApplication</class>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:if>
            <class>QWidget</class>
            <xsl:apply-templates mode="classes"/>
        </xsl:variable>
        <xsl:variable name="classes.ns" select="exsl:node-set($classes.tf)"/>
        <xsl:variable name="classes" select="set:distinct($classes.ns/class)"/>
        
        <xsl:variable name="sortedClasses">
            <xsl:for-each select="exsl:node-set($classes)">
                <xsl:sort/>
                <class><xsl:value-of select="."/></class>
            </xsl:for-each>
        </xsl:variable>
        
        <xsl:call-template name="putClassPreamble">
            <xsl:with-param name="classes" select="exsl:node-set($sortedClasses)"/>
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
    </xsl:template>
    
    <!--
      ** Create the class header
      ** @param data opaque data for user purpose
      -->
    <xsl:template name="createClassHeader">
        <xsl:param name="data"/>
        <xsl:call-template name="putClassHeader">
            <xsl:with-param name="extends" select="/UI/widget/@class"/>
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
    </xsl:template>

    <!--
      ** Create the instance variables
      ** @param data opaque data for user purpose
      -->
    <xsl:template name="createInstanceVariables">
        <xsl:param name="data"/>
        <xsl:call-template name="putVariables">
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
        <xsl:apply-templates mode="declareInstances" select="/UI">
            <xsl:with-param name="data" select="$data"/>
        </xsl:apply-templates>
    </xsl:template>

    <!--
      ** Create the constructors
      ** @param data opaque data for user purpose
      -->
    <xsl:template name="createConstructors">
        <xsl:param name="data"/>
        <xsl:call-template name="putConstructors">
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
    </xsl:template>

    <!--
      ** Create the slots
      ** @param data opaque data for user purpose
      -->
    <xsl:template name="createSlots">
        <xsl:param name="data"/>
        <xsl:for-each select="/UI/slots/slot | /UI/connections/slot">
            <xsl:call-template name="putSlot">
                <xsl:with-param name="data" select="$data"/>
            </xsl:call-template>
        </xsl:for-each>
    </xsl:template>

    <!--
      ** Create the signals
      ** @param data opaque data for user purpose
      -->
    <xsl:template name="createSignals">
        <xsl:param name="data"/>
        <xsl:for-each select="/UI/signals/signal">
            <xsl:call-template name="putSignal">
                <xsl:with-param name="data" select="$data"/>
            </xsl:call-template>
        </xsl:for-each>
    </xsl:template>

    <!--
      ** Create the methods
      ** @param data opaque data for user purpose
      -->
    <xsl:template name="createMethods">
        <xsl:param name="data"/>
        <xsl:call-template name="putMethods">
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
    </xsl:template>

    <!--
      ** Create the main class
      ** @param data opaque data for user purpose
      -->
    <xsl:template name="createMain">
        <xsl:param name="data"/>
        <xsl:call-template name="putMain">
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
    </xsl:template>

    <!--
      ** Create the class header, i.e. the class declaration and
      ** the declaration of the instance variables
      ** @param data opaque data for user purpose
      -->
    <xsl:template name="createClassFooter">
        <xsl:param name="data"/>
        <xsl:call-template name="putClassFooter">
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
    </xsl:template>

    <!--
      ** Create the instance definitions
      ** @param data opaque data for user purpose
      -->
    <xsl:template name="createInstanceDefinitions">
        <xsl:param name="data"/>
        <xsl:apply-templates mode="defineInstances" select="/UI/widget">
            <xsl:with-param name="data" select="$data"/>
        </xsl:apply-templates>
    </xsl:template>

    <!--
      ** Create the database definitions
      ** @param data opaque data for user purpose
      -->
    <xsl:template name="createDatabaseDefinitions">
        <xsl:param name="data"/>
        <xsl:for-each select="//widget[@class = 'QDataBrowser']">
            <xsl:call-template name="putDatabaseDefinition">
                <xsl:with-param name="data" select="$data"/>
            </xsl:call-template>
        </xsl:for-each>
    </xsl:template>

    <!--
      ** Create the action definitions
      ** @param data opaque data for user purpose
      -->
    <xsl:template name="createActionDefinitions">
        <xsl:param name="data"/>
        <xsl:apply-templates mode="defineActions" select="/UI/actions/*">
            <xsl:with-param name="data" select="$data"/>
        </xsl:apply-templates>
    </xsl:template>

    <!--
      ** Create the toolbar definitions
      ** @param data opaque data for user purpose
      -->
    <xsl:template name="createToolbarDefinitions">
        <xsl:param name="data"/>
        <xsl:apply-templates mode="toolbar" select="/UI/toolbars/toolbar">
            <xsl:with-param name="data" select="$data"/>
        </xsl:apply-templates>
    </xsl:template>

    <!--
      ** Create the menubar definitions
      ** @param data opaque data for user purpose
      -->
    <xsl:template name="createMenubarDefinitions">
        <xsl:param name="data"/>
        <xsl:apply-templates mode="menubar" select="/UI/menubar">
            <xsl:with-param name="data" select="$data"/>
        </xsl:apply-templates>
    </xsl:template>

    <!--
      ** Create the connection definitions
      ** @param data opaque data for user purpose
      -->
    <xsl:template name="createConnectionDefinitions">
        <xsl:param name="data"/>
        <xsl:for-each select="/UI/connections/connection">
            <xsl:call-template name="putConnectionDefinition">
                <xsl:with-param name="data" select="$data"/>
            </xsl:call-template>
        </xsl:for-each>
    </xsl:template>

    <!--
      ** Create the tabstops definitions
      ** @param data opaque data for user purpose
      -->
    <xsl:template name="createTabstopsDefinitions">
        <xsl:param name="data"/>
        <xsl:if test="/UI/tabstops">
            <xsl:call-template name="putTabstops">
                <xsl:with-param name="data" select="$data"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>


    <!--
      ** Declare instance variables for all children objects of the
      ** main widget, actions, menubars etc.
      ** @param data opaque data for user purpose
      -->
      
    <!-- Declare instances of all objects that are not QLayoutWidgets -->
    <xsl:template match="property[(@name = 'name') and not(../@class = 'QLayoutWidget')]" mode="declareInstances" priority="1">
        <xsl:param name="data"/>
        <xsl:call-template name="putInstanceVariable"><!-- call user hook -->
            <xsl:with-param name="class">
                <xsl:apply-templates mode="toClass" select=".."/>
            </xsl:with-param>
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
    </xsl:template>
    
    <!-- Declare instances of all objects that are QLayoutWidgets not included in a hbox, vbox or grid -->
    <xsl:template match="property[(@name = 'name') and (../@class = 'QLayoutWidget') and (count(ancestor::hbox|ancestor::vbox|ancestor::grid)=0)]" mode="declareInstances">
        <xsl:param name="data"/>
        <xsl:message>Declare a QLayoutWidget</xsl:message>
        <xsl:call-template name="putInstanceVariable"><!-- call user hook -->
            <xsl:with-param name="class">
                <xsl:apply-templates mode="toClass" select=".."/>
            </xsl:with-param>
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
    </xsl:template>
    
    <xsl:template match="menubar/item" mode="declareInstances">
        <xsl:param name="data"/>
        <xsl:call-template name="putInstanceVariable"><!-- call user hook -->
            <xsl:with-param name="class">
                <class>QPopupMenu</class>
            </xsl:with-param>
            <xsl:with-param name="name" select="@name"/>
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
    </xsl:template>

    <!-- leave out the main widget -->
    <xsl:template match="/UI/widget" mode="declareInstances" priority="1">
        <xsl:param name="data"/>
        <xsl:apply-templates mode="declareInstances" select="widget|grid|hbox|vbox">
            <xsl:with-param name="data" select="$data"/>
        </xsl:apply-templates>
    </xsl:template>
    <!-- descent -->
    <xsl:template match="widget|grid|hbox|vbox" mode="declareInstances">
        <xsl:param name="data"/>
        <xsl:apply-templates mode="declareInstances" select="*">
            <xsl:with-param name="data" select="$data"/>
        </xsl:apply-templates>
    </xsl:template>
    <xsl:template match="text()|@*" mode="declareInstances"/>

    <!--
      ** 
      **    The following templates generate the definitions of the instance variables.
      **    They are called/applied in the "putConstructor" template 
      **
      -->

    <!-- Match the toplevel widget -->  
    <xsl:template match="/UI/widget" mode="defineInstances" priority="1">
        <xsl:param name="data"/>
        <xsl:call-template name="putTopLevelWindowDefinition">
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
        <xsl:apply-templates mode="defineInstances">
            <xsl:with-param name="data" select="$data"/>
        </xsl:apply-templates>
    </xsl:template>

    <!-- Match subsequent widgets -->
    <xsl:template match="widget[@class = 'QLayoutWidget']" mode="defineInstances" priority="1">
        <xsl:param name="data"/>
        <xsl:if test="count(ancestor::hbox|ancestor::vbox|ancestor::grid)=0">
            <xsl:call-template name="putWidgetDefinition">
                <xsl:with-param name="data" select="$data"/>
            </xsl:call-template>
        </xsl:if>
        <xsl:apply-templates mode="defineInstances">
            <xsl:with-param name="data" select="$data"/>
        </xsl:apply-templates>
    </xsl:template>
    <!-- Match subsequent widgets -->
    <xsl:template match="widget[not(@class = 'QLayoutWidget')]" mode="defineInstances">
        <xsl:param name="data"/>
        <xsl:call-template name="putWidgetDefinition">
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
        <xsl:apply-templates mode="defineInstances">
            <xsl:with-param name="data" select="$data"/>
        </xsl:apply-templates>
    </xsl:template>

    <!-- Match layout tags -->
    <xsl:template match="grid|hbox|vbox" mode="defineInstances">
        <xsl:param name="data"/>
        <xsl:variable name="class">
            <xsl:apply-templates mode="toClass" select="."/>
        </xsl:variable>
        <xsl:call-template name="putLayoutDefinition">
            <xsl:with-param name="class" select="$class"/>
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
        <xsl:apply-templates mode="defineInstances">
            <xsl:with-param name="data" select="$data"/>
        </xsl:apply-templates>
        <xsl:for-each select="widget|spacer">
            <xsl:call-template name="putLayoutContentDefinition">
            <xsl:with-param name="data" select="$data"/>
            </xsl:call-template>
        </xsl:for-each>
    </xsl:template>

    <!-- Match column tags -->
    <xsl:template match="column" mode="defineInstances">
        <xsl:param name="data"/>
        <xsl:call-template name="putColumnDefinition">
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
    </xsl:template>

    <!-- Match row tags -->
    <xsl:template match="row" mode="defineInstances">
        <xsl:param name="data"/>
        <xsl:call-template name="putRowDefinition">
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
    </xsl:template>

    <!-- Match item tags -->
    <xsl:template match="item" mode="defineInstances">
        <xsl:param name="data"/>
        <xsl:variable name="containerClass">
            <xsl:apply-templates mode="toClass" select=".."/>
        </xsl:variable>
        <xsl:call-template name="putItemDefinition">
            <xsl:with-param name="class" select="$containerClass"/>
            <xsl:with-param name="number" select="count(preceding-sibling::item)"/>
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
    </xsl:template>

    <!-- Match spacer tags -->
    <xsl:template match="spacer" mode="defineInstances">
        <xsl:param name="data"/>
        <xsl:call-template name="putSpacerDefinition">
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
        <!-- <xsl:apply-templates mode="defineInstances">
                <xsl:with-param name="data" select="$data"/>
             </xsl:apply-templates>
        -->
    </xsl:template>

    <xsl:template match="property[not(@name = 'name')]" mode="defineInstances">
        <xsl:param name="data"/>
        <xsl:apply-templates mode="property">
            <xsl:with-param name="name" select="@name"/>
            <xsl:with-param name="data" select="$data"/>
        </xsl:apply-templates>
    </xsl:template>

    <!-- Ignore everything else -->
    <xsl:template match="text()|@*" mode="defineInstances"/>

    <!-- ACTIONS -->
    <xsl:template match="action" mode="defineActions">
        <xsl:param name="data"/>
        <xsl:call-template name="putActionDefinition">
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
        <xsl:apply-templates select="*" mode="defineInstances">
            <xsl:with-param name="data" select="$data"/>
        </xsl:apply-templates>
    </xsl:template>
    <xsl:template match="actiongroup" mode="defineActions">
        <xsl:param name="data"/>
        <xsl:call-template name="putActionGroupDefinition">
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
        <xsl:apply-templates select="*" mode="defineActions">
            <xsl:with-param name="data" select="$data"/>
        </xsl:apply-templates>
    </xsl:template>
    <!-- Ignore everything else -->
    <xsl:template match="*|text()|@*" mode="defineActions"/>

    <!-- 
      ** Match menubar 
      -->
    <xsl:template match="menubar" mode="menubar">
        <xsl:param name="data"/>
        <xsl:call-template name="putMenubarDefinition">
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
        <xsl:apply-templates mode="menubar">
            <xsl:with-param name="data" select="$data"/>
        </xsl:apply-templates>
    </xsl:template>
    
    <xsl:template match="item" mode="menubar">
        <xsl:param name="data"/>
        <xsl:call-template name="putMenubarItemDefinition">
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
        <xsl:apply-templates mode="menubar">
            <xsl:with-param name="data" select="$data"/>
        </xsl:apply-templates>
    </xsl:template>

    <xsl:template match="action" mode="menubar">
        <xsl:param name="data"/>
        <xsl:call-template name="putMenubarActionDefinition">
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
    </xsl:template>

    <xsl:template match="separator" mode="menubar">
        <xsl:param name="data"/>
        <xsl:call-template name="putMenubarSeperatorDefinition">
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
    </xsl:template>

    <xsl:template match="*|text()|@*" mode="menubar"/>
    
    <!-- 
      ** Match Toolbar 
      -->
    <xsl:template match="toolbar" mode="toolbar">
        <xsl:param name="data"/>
        <xsl:call-template name="putToolbarDefinition">
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
        <xsl:apply-templates mode="toolbar">
            <xsl:with-param name="data" select="$data"/>
        </xsl:apply-templates>
    </xsl:template>
    
    <xsl:template match="action" mode="toolbar">
        <xsl:param name="data"/>
        <xsl:call-template name="putToolbarActionDefinition">
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
    </xsl:template>

    <xsl:template match="separator" mode="toolbar">
        <xsl:param name="data"/>
        <xsl:call-template name="putToolbarSeperatorDefinition">
            <xsl:with-param name="data" select="$data"/>
        </xsl:call-template>
    </xsl:template>

    <xsl:template match="*|text()|@*" mode="toolbar"/>

</xsl:stylesheet>

