<?xml version="1.0" encoding="UTF-8"?>
<!--***********************************************************
 * 
 * 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.
 * 
 ***********************************************************-->


<!--
	For further documentation and updates visit http://xml.openoffice.org/odf2xhtml
-->
<xsl:stylesheet version="1.0"
		xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
		xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0"
		xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0"
		xmlns:dc="http://purl.org/dc/elements/1.1/"
		xmlns:dom="http://www.w3.org/2001/xml-events"
		xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0"
		xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"
		xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"
		xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0"
		xmlns:math="http://www.w3.org/1998/Math/MathML"
		xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0"
		xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"
		xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
		xmlns:ooo="http://openoffice.org/2004/office"
		xmlns:oooc="http://openoffice.org/2004/calc"
		xmlns:ooow="http://openoffice.org/2004/writer"
		xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0"
		xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0"
		xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"
		xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"
		xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"
		xmlns:xforms="http://www.w3.org/2002/xforms"
		xmlns:xlink="http://www.w3.org/1999/xlink"
		xmlns:xsd="http://www.w3.org/2001/XMLSchema"
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xmlns:xt="http://www.jclark.com/xt"
		xmlns:common="http://exslt.org/common"
		xmlns:xalan="http://xml.apache.org/xalan"
		exclude-result-prefixes="chart config dc dom dr3d draw fo form math meta number office ooo oooc ooow script style svg table text xforms xlink xsd xsi xt common xalan">



	<!-- ***************************************** -->
	<!-- *** Gathering office style properties *** -->
	<!-- ***************************************** -->

	<!-- REASON FOR STYLESHEET:
			In the OpenOffice documents styles are represented by a hierarchy.
			(e.g. most styles are inherited from a default style).
			Many other languages (as XHTML/CSS) do not support inherited styles.
			The style inheritance have to be made flat/absolute for each style.

			A further reason was, that the earlier style collection mechanism
			had problems with CSS inline, which do not inherit from XML office defaults
			nor font:family defaults as the style header does
			(cp. stylesheet 'style_collector.xsl' and the 'write-default-styles' template)

		 RESULT OF STYLESHEET:
			All styles will be returned in a variable containing styles with their inherited *:

				<all-styles>
					<style style:family="foo" style:name="x1">
						<* fo:padding-left="0cm" fo:margin-right="0cm" />
					</style>
					<style style:family="muh" style:name="x2" >
						<* fo:padding-left="3cm" ...                  />
					</style>
					...

				</all-styles>
	-->


	<xsl:template name="collect-global-odf-properties">
		<!-- to access the variable as a node-set by XPATH expressions, it is necessary to convert it
			 from a result-tree-fragment (RTF) to a node set by a in a XSLT 1.0 non standarized function -->
		<xsl:variable name="globalDataRTF">
			<xsl:call-template name="collect-document-links-RTF" />
		</xsl:variable>

		<xsl:choose>
			<xsl:when test="function-available('common:node-set')">
				<xsl:call-template name="collect-style-properties">
					<xsl:with-param name="globalData" select="common:node-set($globalDataRTF)" />
				</xsl:call-template>
			</xsl:when>
			<xsl:when test="function-available('xalan:nodeset')">
				<xsl:call-template name="collect-style-properties">
					<xsl:with-param name="globalData" select="xalan:nodeset($globalDataRTF)" />
				</xsl:call-template>
			</xsl:when>
			<xsl:when test="function-available('xt:node-set')">
				<xsl:call-template name="collect-style-properties">
					<xsl:with-param name="globalData" select="xt:node-set($globalDataRTF)" />
				</xsl:call-template>
			</xsl:when>
			<xsl:otherwise>
				<xsl:message terminate="yes">The required node-set function was not found!</xsl:message>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>



	<xsl:template name="collect-style-properties">
		<xsl:param name="globalData" />

		<!-- Add the input file references to the new collected style properties -->
		<xsl:variable name="globalDataRTF">
			<xsl:copy-of select="$globalData" />
			<xsl:call-template name="collect-style-properties-RTF">
				<xsl:with-param name="globalData" select="$globalData" />
			</xsl:call-template>
		</xsl:variable>

		<xsl:choose>
			<xsl:when test="function-available('common:node-set')">
				<xsl:call-template name="map-odf-style-properties">
					<xsl:with-param name="globalData" select="common:node-set($globalDataRTF)" />
				</xsl:call-template>
			</xsl:when>
			<xsl:when test="function-available('xalan:nodeset')">
				<xsl:call-template name="map-odf-style-properties">
					<xsl:with-param name="globalData" select="xalan:nodeset($globalDataRTF)" />
				</xsl:call-template>
			</xsl:when>
			<xsl:when test="function-available('xt:node-set')">
				<xsl:call-template name="map-odf-style-properties">
					<xsl:with-param name="globalData" select="xt:node-set($globalDataRTF)" />
				</xsl:call-template>
			</xsl:when>
			<xsl:otherwise>
				<xsl:message terminate="yes">The required node-set function was not found!</xsl:message>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>


	<xsl:template name="collect-document-links-RTF">
		<!-- works for zipped office files, unzipped office files as for flat filter single office file format as well -->
		<xsl:variable name="documentLinksRTF">
			<xsl:choose>
				<xsl:when test="office:document-content">
					<xsl:element name="styles-file" namespace="">
						<xsl:copy-of select="document(concat($sourceBaseURL, 'styles.xml'), .)" />
					</xsl:element>
					<xsl:element name="meta-file" namespace="">
						<xsl:copy-of select="document(concat($sourceBaseURL, 'meta.xml'), .)" />
					</xsl:element>
				</xsl:when>
				<xsl:otherwise>
					<xsl:element name="styles-file" namespace="">
						<xsl:copy-of select="/" />
					</xsl:element>
					<xsl:element name="meta-file" namespace="">
						<xsl:copy-of select="/" />
					</xsl:element>
				</xsl:otherwise>
			</xsl:choose>
		</xsl:variable>

		<xsl:choose>
			<xsl:when test="function-available('common:node-set')">
				<xsl:call-template name="collect-document-links">
					<xsl:with-param name="documentLinks" select="common:node-set($documentLinksRTF)" />
				</xsl:call-template>
			</xsl:when>
			<xsl:when test="function-available('xalan:nodeset')">
				<xsl:call-template name="collect-document-links">
					<xsl:with-param name="documentLinks" select="xalan:nodeset($documentLinksRTF)" />
				</xsl:call-template>
			</xsl:when>
			<xsl:when test="function-available('xt:node-set')">
				<xsl:call-template name="collect-document-links">
					<xsl:with-param name="documentLinks" select="xt:node-set($documentLinksRTF)" />
				</xsl:call-template>
			</xsl:when>
			<xsl:otherwise>
				<xsl:message terminate="yes">The required node-set function was not found!</xsl:message>
			</xsl:otherwise>
		</xsl:choose>

	</xsl:template>


	<xsl:template name="collect-document-links">
		<xsl:param name="documentLinks" />

		<xsl:element name="styles-file" namespace="">
			<xsl:copy-of select="$documentLinks/styles-file/*" />
		</xsl:element>

		<xsl:element name="meta-file" namespace="">
			<xsl:copy-of select="$documentLinks/meta-file/*" />
		</xsl:element>

		<xsl:copy-of select="$documentLinks/styles-file/*/office:styles" />
		<xsl:copy-of select="$documentLinks/styles-file/*/office:font-face-decls" />

		<!-- office:automatic-styles may be containted in two files (i.e. content.xml and styles.xml).
			 Wild card necessary as top level element differs from flat office files ("SampleName.fsxw") -->
		<xsl:copy-of select="/*/office:automatic-styles" />

	</xsl:template>


	<xsl:template name="collect-style-properties-RTF">
		<xsl:param name="globalData" />

	   <!--** DEFAULT STYLES: First adding some office defaults unwritten in XML -->
		<xsl:variable name="defaultOfficeStyle-RTF">
			<xsl:element name="style" namespace="">
				<xsl:element name="style:properties" />
			</xsl:element>
		</xsl:variable>

		<xsl:choose>
			<xsl:when test="function-available('common:node-set')">
				<xsl:call-template name="collect-properties-defaults">
					<xsl:with-param name="globalData" select="$globalData" />
					<xsl:with-param name="defaultOfficeStyle" select="common:node-set($defaultOfficeStyle-RTF)" />
				</xsl:call-template>
			</xsl:when>
			<xsl:when test="function-available('xalan:nodeset')">
				<xsl:call-template name="collect-properties-defaults">
					<xsl:with-param name="globalData" select="$globalData" />
					<xsl:with-param name="defaultOfficeStyle" select="xalan:nodeset($defaultOfficeStyle-RTF)" />
				</xsl:call-template>
			</xsl:when>
			<xsl:when test="function-available('xt:node-set')">
				<xsl:call-template name="collect-properties-defaults">
					<xsl:with-param name="globalData" select="$globalData" />
					<xsl:with-param name="defaultOfficeStyle" select="xt:node-set($defaultOfficeStyle-RTF)" />
				</xsl:call-template>
			</xsl:when>
			<xsl:otherwise>
				<xsl:message terminate="yes">ERROR: Function not found: 'Nodeset'</xsl:message>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>


	<xsl:template name="collect-properties-defaults">
		<xsl:param name="globalData" />
		<xsl:param name="defaultOfficeStyle" />

		<!--** DEFAULT STYLES: Adding the default styles of a style:family, by adding each office:styles/style:default-style element **-->
		<xsl:variable name="defaultFamilyStyles-RTF">
			<xsl:for-each select="$globalData/office:styles/style:default-style">
				<xsl:element name="style" namespace="">
					<xsl:copy-of select="@style:family" />
					<xsl:call-template name="create-inherited-style-properties">
						<xsl:with-param name="inheritedStyleProperties" select="$defaultOfficeStyle/style/*" />
					</xsl:call-template>
				</xsl:element>
			</xsl:for-each>
		</xsl:variable>

		<xsl:choose>
			<xsl:when test="function-available('common:node-set')">
				<xsl:call-template name="collect-properties">
					<xsl:with-param name="globalData" select="$globalData" />
					<xsl:with-param name="defaultOfficeStyle" select="$defaultOfficeStyle" />
					<xsl:with-param name="defaultFamilyStyles" select="common:node-set($defaultFamilyStyles-RTF)" />
				</xsl:call-template>
			</xsl:when>
			<xsl:when test="function-available('xalan:nodeset')">
				<xsl:call-template name="collect-properties">
					<xsl:with-param name="globalData" select="$globalData" />
					<xsl:with-param name="defaultOfficeStyle" select="$defaultOfficeStyle" />
					<xsl:with-param name="defaultFamilyStyles" select="xalan:nodeset($defaultFamilyStyles-RTF)" />
				</xsl:call-template>
			</xsl:when>
			<xsl:when test="function-available('xt:node-set')">
				<xsl:call-template name="collect-properties">
					<xsl:with-param name="globalData" select="$globalData" />
					<xsl:with-param name="defaultOfficeStyle" select="$defaultOfficeStyle" />
					<xsl:with-param name="defaultFamilyStyles" select="xt:node-set($defaultFamilyStyles-RTF)" />
				</xsl:call-template>
			</xsl:when>
			<xsl:otherwise>
				<xsl:message terminate="yes">ERROR: Function not found: nodeset</xsl:message>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>


	<xsl:template name="collect-properties">
		<xsl:param name="globalData" />
		<xsl:param name="defaultOfficeStyle" />
		<xsl:param name="defaultFamilyStyles" />

	   <!--** traversee all style trees - branch after branch - collecting style properties **-->
		<xsl:element name="all-doc-styles" namespace="">

	   <!-- Background Information:

		   There are two different types of styles in the Office:
			   1) The office:styles from the user pre-defined style templates
			   2) The automatic:styles, which are created whenever a user uses explicit style formatting.

		   The office:styles only have parent styles in the office:styles,
		   but automatic:styles may inherit from both office:styles and themself.
		-->

		   <!--** traversee all office:styles trees beginning with the top-level styles **-->
			<xsl:for-each select="$globalData/office:styles/style:style[not(@style:parent-style-name)]">
			   <!-- Looking for parents from style:family
			   <xsl:for-each select="$globalData/office:styles/style:style[@style:family=current()/@style:family][not(@style:parent-style-name)]"> -->
				<xsl:choose>
					<xsl:when test="$defaultFamilyStyles/style[@style:family=current()/@style:family]">
						<xsl:call-template name="inherit-style-for-self-and-children">
							<xsl:with-param name="globalData" select="$globalData" />
							<xsl:with-param name="inheritedStyleProperties" select="$defaultFamilyStyles/style[@style:family=current()/@style:family]/*" />
							<xsl:with-param name="searchOnlyInAutomaticStyles" select="false()" />
						</xsl:call-template>
					</xsl:when>
					<xsl:otherwise>
						<xsl:call-template name="inherit-style-for-self-and-children">
							<xsl:with-param name="globalData" select="$globalData" />
							<xsl:with-param name="inheritedStyleProperties" select="$defaultOfficeStyle/style/*" />
							<xsl:with-param name="searchOnlyInAutomaticStyles" select="false()" />
						</xsl:call-template>
					</xsl:otherwise>
				</xsl:choose>
			   <!--** creates a style element with style:name and style:family attribute and
					   an element representing the absolute style properties style:property  ** -->
			</xsl:for-each>

	   <!--** traversee all office:automatic-styles trees beginning with the top-level styles **-->
			<xsl:for-each select="$globalData/office:automatic-styles/style:style[not(@style:parent-style-name)]">
			   <!--** creates a style element with style:name and style:family attribute and
					   an element representing the absolute style properties style:property  ** -->
				<xsl:choose>
					<xsl:when test="$defaultFamilyStyles/style[@style:family=current()/@style:family]">
						<xsl:call-template name="inherit-style-for-self-and-children">
							<xsl:with-param name="globalData" select="$globalData" />
							<xsl:with-param name="inheritedStyleProperties" select="$defaultFamilyStyles/style[@style:family=current()/@style:family]/*" />
							<xsl:with-param name="searchOnlyInAutomaticStyles" select="true()" />
						</xsl:call-template>
					</xsl:when>
					<xsl:otherwise>
						<xsl:call-template name="inherit-style-for-self-and-children">
							<xsl:with-param name="globalData" select="$globalData" />
							<xsl:with-param name="inheritedStyleProperties" select="$defaultOfficeStyle/style/*" />
							<xsl:with-param name="searchOnlyInAutomaticStyles" select="true()" />
						</xsl:call-template>
					</xsl:otherwise>
				</xsl:choose>

			</xsl:for-each>

		</xsl:element>
	   <!-- debug output in case only styles should be given out (regression test)  -->
		<xsl:if test="$onlyStyleOutputEnabled">
			<xsl:element name="defaultOfficeStyle" namespace="">
				<xsl:copy-of select="$defaultOfficeStyle" />
			</xsl:element>
			<xsl:element name="defaultFamilyStyles" namespace="">
				<xsl:copy-of select="$defaultFamilyStyles" />
			</xsl:element>
		</xsl:if>

	</xsl:template>


	<xsl:template name="inherit-style-for-self-and-children">
		<xsl:param name="globalData" />
		<xsl:param name="inheritedStyleProperties" />
		<xsl:param name="searchOnlyInAutomaticStyles" />

		   <!--** create an absolute style by inherting properties from the given parent properties **-->
		<xsl:variable name="newStyleProperties-RTF">
			<xsl:call-template name="create-inherited-style-properties">
				<xsl:with-param name="inheritedStyleProperties" select="$inheritedStyleProperties" />
			</xsl:call-template>
		</xsl:variable>
		<xsl:choose>
			<xsl:when test="function-available('common:node-set')">
				<xsl:variable name="newStyleProperties" select="common:node-set($newStyleProperties-RTF)" />

				<xsl:element name="style" namespace="">
					<xsl:copy-of select="@style:family" />
					<xsl:copy-of select="@style:name" />
					<xsl:copy-of select="$newStyleProperties" />
				</xsl:element>

				<xsl:choose>
					<xsl:when test="$searchOnlyInAutomaticStyles">
						<xsl:call-template name="get-children">
							<xsl:with-param name="globalData" select="$globalData" />
							<xsl:with-param name="searchOnlyInAutomaticStyles" select="true()" />
							<xsl:with-param name="inheritedStyleProperties" select="$newStyleProperties/*" />
						</xsl:call-template>
					</xsl:when>
					<xsl:otherwise>
						   <!--** for all automatic-children of the current office:styles  **-->
						<xsl:call-template name="get-children">
							<xsl:with-param name="globalData" select="$globalData" />
							<xsl:with-param name="searchOnlyInAutomaticStyles" select="false()" />
							<xsl:with-param name="inheritedStyleProperties" select="$newStyleProperties/*" />
						</xsl:call-template>
					</xsl:otherwise>
				</xsl:choose>
			</xsl:when>
			<xsl:when test="function-available('xalan:nodeset')">
				<xsl:variable name="newStyleProperties" select="xalan:nodeset($newStyleProperties-RTF)" />

				<xsl:element name="style" namespace="">
					<xsl:copy-of select="@style:family" />
					<xsl:copy-of select="@style:name" />
					<xsl:copy-of select="$newStyleProperties" />
				</xsl:element>

				<xsl:choose>
					<xsl:when test="$searchOnlyInAutomaticStyles">
						<xsl:call-template name="get-children">
							<xsl:with-param name="globalData" select="$globalData" />
							<xsl:with-param name="searchOnlyInAutomaticStyles" select="true()" />
							<xsl:with-param name="inheritedStyleProperties" select="$newStyleProperties/*" />
						</xsl:call-template>
					</xsl:when>
					<xsl:otherwise>
						   <!--** for all automatic-children of the current office:styles  **-->
						<xsl:call-template name="get-children">
							<xsl:with-param name="globalData" select="$globalData" />
							<xsl:with-param name="searchOnlyInAutomaticStyles" select="false()" />
							<xsl:with-param name="inheritedStyleProperties" select="$newStyleProperties/*" />
						</xsl:call-template>
					</xsl:otherwise>
				</xsl:choose>
			</xsl:when>
			<xsl:when test="function-available('xt:node-set')">
				<xsl:variable name="newStyleProperties" select="xt:node-set($newStyleProperties-RTF)" />

				<xsl:element name="style" namespace="">
					<xsl:copy-of select="@style:family" />
					<xsl:copy-of select="@style:name" />
					<xsl:copy-of select="$newStyleProperties" />
				</xsl:element>

				<xsl:choose>
					<xsl:when test="$searchOnlyInAutomaticStyles">
						<xsl:call-template name="get-children">
							<xsl:with-param name="globalData" select="$globalData" />
							<xsl:with-param name="searchOnlyInAutomaticStyles" select="true()" />
							<xsl:with-param name="inheritedStyleProperties" select="$newStyleProperties/*" />
						</xsl:call-template>
					</xsl:when>
					<xsl:otherwise>
						   <!--** for all automatic-children of the current office:styles  **-->
						<xsl:call-template name="get-children">
							<xsl:with-param name="globalData" select="$globalData" />
							<xsl:with-param name="searchOnlyInAutomaticStyles" select="false()" />
							<xsl:with-param name="inheritedStyleProperties" select="$newStyleProperties/*" />
						</xsl:call-template>
					</xsl:otherwise>
				</xsl:choose>
			</xsl:when>
			<xsl:otherwise>
				<xsl:message terminate="yes">ERROR: Function not found: nodeset</xsl:message>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>


	<xsl:template name="get-children">
		<xsl:param name="globalData" />
		<xsl:param name="searchOnlyInAutomaticStyles" />
		<xsl:param name="inheritedStyleProperties" select="*" />

<!-- QUESTION: Parent style is only unique by name and family, but what about cross family inheritance? -->
	   <!-- For each child style (that is every style which has the given parentStyleName as style:parent-style-name and the same style:family -->
		<xsl:variable name="parentStyleFamily" select="@style:family" />
		<xsl:variable name="parentStyleName" select="@style:name" />
		<xsl:if test="not($searchOnlyInAutomaticStyles)">
			<xsl:for-each select="$globalData/office:styles/style:style[@style:family=$parentStyleFamily and @style:parent-style-name=$parentStyleName]">
				<xsl:call-template name="inherit-style-for-self-and-children">
					<xsl:with-param name="globalData" select="$globalData" />
					<xsl:with-param name="inheritedStyleProperties" select="$inheritedStyleProperties" />
					<xsl:with-param name="searchOnlyInAutomaticStyles" select="$searchOnlyInAutomaticStyles" />
				</xsl:call-template>
			</xsl:for-each>
		</xsl:if>
		<xsl:for-each select="$globalData/office:automatic-styles/style:style[@style:family=$parentStyleFamily and @style:parent-style-name=$parentStyleName]">
			<xsl:call-template name="inherit-style-for-self-and-children">
				<xsl:with-param name="globalData" select="$globalData" />
				<xsl:with-param name="inheritedStyleProperties" select="$inheritedStyleProperties" />
				<xsl:with-param name="searchOnlyInAutomaticStyles" select="$searchOnlyInAutomaticStyles" />
			</xsl:call-template>
		</xsl:for-each>
	</xsl:template>


	<xsl:template name="create-inherited-style-properties">
		<xsl:param name="inheritedStyleProperties" />

		<xsl:element name="style:properties">
		   <!-- Writing all inherited style properties -->
			<xsl:for-each select="$inheritedStyleProperties/@*">
				<xsl:sort select="name()" />
				<xsl:copy-of select="." />
			</xsl:for-each>

		   <!--All current attributes will override already inserted attributes of the same name
			   XSLT Spec: "Adding an attribute to an element replaces any existing attribute of that element with the same expanded-name." -->
			<xsl:for-each select="*/@*[name() != 'style:font-size-rel']">
				<xsl:copy-of select="." />
			</xsl:for-each>

			<xsl:if test="*/@style:font-size-rel">
<!--
	The intheritedStyleProperties should include a absolute Font Size, but
	<style:properties
		xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0"
		xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"
		style:font-name="Courier New"
		fo:language="en"
		fo:country="US"
		style:font-name-asian=Courier New"
		style:font-name-complex="Courier New"/>
-->
				<xsl:variable name="fontSizeAbsolute">
					<xsl:call-template name="convert2pt">
						<xsl:with-param name="value" select="$inheritedStyleProperties/@fo:font-size" />
					</xsl:call-template>
				</xsl:variable>

				<xsl:variable name="fontSizeRelative">
					<xsl:call-template name="convert2pt">
						<xsl:with-param name="value" select="*/@style:font-size-rel" />
					</xsl:call-template>
				</xsl:variable>

				<xsl:attribute name="fo:font-size">
					<xsl:value-of select="$fontSizeAbsolute + $fontSizeRelative"/>
					<xsl:text>pt</xsl:text>
				</xsl:attribute>
			</xsl:if>

			<!-- providing tabulator indentation -->
			<xsl:copy-of select="$inheritedStyleProperties/style:tab-stops"/>
			<xsl:copy-of select="*/style:tab-stops"/>
		</xsl:element>
	</xsl:template>

   <!-- debugging & testing purpose -->
	<xsl:template name="write-collected-styles">
		<xsl:param name="globalData" />

		<xsl:message>&lt;all-doc-styles&gt;</xsl:message>
		<xsl:for-each select="$globalData/all-doc-styles/style">
			<xsl:message>&lt;style</xsl:message>
			<xsl:message>style:family="<xsl:value-of select="current()/@style:family" />"&gt;</xsl:message>
			<xsl:message>style:name="<xsl:value-of select="current()/@style:name" />" </xsl:message>
			<xsl:message>   &lt;*</xsl:message>
			<xsl:for-each select="*/@*">
				<xsl:message>
					<xsl:text></xsl:text>
					<xsl:value-of select="name()" />="<xsl:value-of select="." />"</xsl:message>
			</xsl:for-each>
			<xsl:message>/&gt;</xsl:message>
			<xsl:message>&lt;/style&gt;</xsl:message>
		</xsl:for-each>
		<xsl:message>&lt;/all-doc-styles&gt;</xsl:message>
	</xsl:template>

	<xsl:template name="map-odf-style-properties">
		<xsl:param name="globalData" />

		<xsl:choose>
		   <!--+++++ DEBUG STYLE OUTPUT FOR REGRESSION TEST +++++-->
		   <!-- create styles file from the style variable (testing switch) -->
			<xsl:when test="$onlyStyleOutputEnabled">

				<xsl:element name="debug-output" namespace="">
					<xsl:copy-of select="$globalData" />
					<xsl:call-template name="map-odf-properties">
						<xsl:with-param name="globalData" select="$globalData" />
					</xsl:call-template>
				</xsl:element>
			</xsl:when>

		   <!-- create XHTML file -->
			<xsl:otherwise>
			   <!-- to access the variable like a node-set it is necessary to convert it
					from a result-tree-fragment (RTF) to a node set using the James Clark extension -->
				<xsl:variable name="globalDataRTF">
				   <!-- raw properties still needed for table width attribute creation -->
					<xsl:copy-of select="$globalData" />
					<xsl:call-template name="map-odf-properties">
						<xsl:with-param name="globalData" select="$globalData" />
					</xsl:call-template>
				</xsl:variable>

				<xsl:choose>
					<xsl:when test="function-available('common:node-set')">
						<xsl:call-template name="start-main">
							<xsl:with-param name="globalData" select="common:node-set($globalDataRTF)" />
						</xsl:call-template>
					</xsl:when>
					<xsl:when test="function-available('xalan:nodeset')">
						<xsl:call-template name="start-main">
							<xsl:with-param name="globalData" select="xalan:nodeset($globalDataRTF)" />
						</xsl:call-template>
					</xsl:when>
					<xsl:when test="function-available('xt:node-set')">
						<xsl:call-template name="start-main">
							<xsl:with-param name="globalData" select="xt:node-set($globalDataRTF)" />
						</xsl:call-template>
					</xsl:when>
					<xsl:otherwise>
						<xsl:message terminate="yes">ERROR: Function not found: nodeset</xsl:message>
					</xsl:otherwise>
				</xsl:choose>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>

	<!-- REASON FOR TEMPLATE:
	   The OpenOffice style properities gathered in the variable 'globalData' have to be mapped to the CSS style format
	-->
	<xsl:template name="map-odf-properties">
		<xsl:param name="globalData" />
		<xsl:element name="all-styles" namespace="">
			<xsl:for-each select="$globalData/all-doc-styles/style">
				<xsl:sort select="@style:family" />
				<xsl:sort select="@style:name" />

				<xsl:call-template name="writeUsedStyles">
					<xsl:with-param name="globalData" select="$globalData" />
					<xsl:with-param name="style" select="."/>
				</xsl:call-template>
			</xsl:for-each>
		</xsl:element>
	</xsl:template>

	<xsl:key name="elementUsingStyle" match="*" use="@text:style-name | @draw:style-name | @draw:text-style-name | @table:style-name | @table:default-cell-style-name"/>
	<xsl:key name="listLabelStyleInStyles" match="/*/office:styles/text:list-style/*  |
									  /*/office:styles/style:graphic-properties/text:list-style/*" use="@text:style-name"/>

    <xsl:key name="listLabelStyleInContent" match="/*/office:automatic-styles/text:list-style/* | /*/office:automatic-styles/style:graphic-properties/text:list-style/*" use="@text:style-name"/>


	<xsl:variable name="documentRoot" select="/" />
    <xsl:template name="writeUsedStyles">
        <xsl:param name="globalData" />
        <xsl:param name="style"/>
    
            <!-- for-each changes the key environment from the previously globalData back to the document root  -->
        <xsl:for-each select="$documentRoot">
                <!-- only styles, which are used in the content are written as CSS styles -->
            <xsl:choose>
                <xsl:when test="key('elementUsingStyle', $style/@style:name)/@* or key('listLabelStyleInContent', $style/@style:name)/@*">
                    <xsl:call-template name="writeUsedStyles2">
                        <xsl:with-param name="globalData" select="$globalData" />
                        <xsl:with-param name="style" select="$style" />
                    </xsl:call-template>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:choose>
                        <xsl:when test="not(office:document-content)">
                            <xsl:if test="key('listLabelStyleInStyles', $style/@style:name)/@* or /*/office:styles/text:notes-configuration[@text:citation-style-name = $style/@style:name or /*/office:styles/@text:citation-body-style-name=$style/@style:name]">
                                <!-- if there are consecutive paragraphs with borders (OR background AND margin ), only the first and the last have the top/bottom border
                                unless style:join-border="false" -->
                                <xsl:call-template name="writeUsedStyles2">
                                    <xsl:with-param name="globalData" select="$globalData" />
                                    <xsl:with-param name="style" select="$style" />
                                </xsl:call-template>
                            </xsl:if>    
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:for-each select="document($stylesFileURL)">
                                <xsl:if test="key('listLabelStyleInStyles', $style/@style:name)/@* or /*/office:styles/text:notes-configuration[@text:citation-style-name = $style/@style:name or /*/office:styles/@text:citation-body-style-name=$style/@style:name]">
                                    <!-- if there are consecutive paragraphs with borders (OR background AND margin ), only the first and the last have the top/bottom border
                                    unless style:join-border="false" -->
                                    <xsl:call-template name="writeUsedStyles2">
                                        <xsl:with-param name="globalData" select="$globalData" />
                                        <xsl:with-param name="style" select="$style" />
                                    </xsl:call-template>
                                </xsl:if>
                            </xsl:for-each>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:for-each>
    </xsl:template>     
    
	<xsl:template name="writeUsedStyles2">
		<xsl:param name="globalData" />
		<xsl:param name="style"/>
        <xsl:choose>
            <xsl:when test="
                $style/@style:family='paragraph'
            and((
                  ( 
                        $style/*/@fo:border-top
                     or $style/*/@fo:border-bottom
                     or $style/*/@fo:border
                  )
                   and
                  (
                     not($style/*/@style:join-border)
                     or  $style/*/@style:join-border = 'true'
                  )
                )
               or
                (
                  ( 
                        $style/*/@fo:margin-top
                     or $style/*/@fo:margin-bottom
                     or $style/*/@fo:margin
                  )
                    and
                  (     $style/*/@fo:background-color
                    and 
                        not($style/*/fo:background-color='transparent')
                  )
                )
               )">
                <xsl:element name="style" namespace="">
                    <xsl:copy-of select="$style/@style:family" />
                    <xsl:attribute name="style:name"><xsl:value-of select="concat($style/@style:name, '_borderStart')" /></xsl:attribute>
                    <xsl:element name="final-properties" namespace="">
                        <xsl:apply-templates select="$style/*/@*[not(name() = 'fo:border-bottom')][not(name() = 'fo:padding-bottom')][not(name() = 'fo:margin-bottom')][not(name() = 'fo:margin')]">
                            <xsl:with-param name="globalData" select="$globalData" />
                        </xsl:apply-templates>
                        <xsl:apply-templates mode="paragraphMerge" select="$style/*/@*[name() = 'fo:margin-bottom' or name() = 'fo:margin']">
                            <xsl:with-param name="globalData" select="$globalData" />
                        </xsl:apply-templates>                                
                        <xsl:text> border-bottom-style:none; </xsl:text>
                    </xsl:element>
                </xsl:element>
                <xsl:element name="style" namespace="">
                    <xsl:copy-of select="$style/@style:family" />
                    <xsl:copy-of select="$style/@style:name" />
                    <xsl:attribute name="mergedBorders"><xsl:value-of select="true()" /></xsl:attribute>
                    <xsl:element name="final-properties" namespace="">
                        <xsl:apply-templates select="$style/*/@*[not(name() = 'fo:border-top') and not(name() = 'fo:border-bottom')][not(name() = 'fo:padding-top') and not(name() = 'fo:padding-bottom')][not(name() = 'fo:margin-top') and not(name() = 'fo:margin-bottom')][not(name() = 'fo:margin')]">
                            <xsl:with-param name="globalData" select="$globalData" />
                        </xsl:apply-templates>
                        <xsl:apply-templates mode="paragraphMerge" select="$style/*/@*[name() = 'fo:margin-top' or name() = 'fo:margin-bottom' or name() = 'fo:margin']">
                            <xsl:with-param name="globalData" select="$globalData" />
                        </xsl:apply-templates>                                
                        <xsl:text> border-top-style:none; border-bottom-style:none; </xsl:text>
                    </xsl:element>
                </xsl:element>
                <xsl:element name="style" namespace="">
                    <xsl:copy-of select="$style/@style:family" />
                    <xsl:attribute name="style:name"><xsl:value-of select="concat($style/@style:name, '_borderEnd')" /></xsl:attribute>
                    <xsl:element name="final-properties" namespace="">
                        <xsl:apply-templates select="$style/*/@*[not(name() = 'fo:border-top')][not(name() = 'fo:padding-top')][not(name() = 'fo:margin-top')][not(name() = 'fo:margin')]">
                            <xsl:with-param name="globalData" select="$globalData" />
                        </xsl:apply-templates>
                        <xsl:apply-templates mode="paragraphMerge" select="$style/*/@*[name() = 'fo:margin-top' or name() = 'fo:margin']">
                            <xsl:with-param name="globalData" select="$globalData" />
                        </xsl:apply-templates>                                
                        <xsl:text> border-top-style:none;</xsl:text>
                    </xsl:element>
                </xsl:element>
            </xsl:when>
            <xsl:otherwise>
                <xsl:choose>
                    <xsl:when test="not(key('listLabelStyleInStyles', $style/@style:name)/@*)">
                        <xsl:element name="style" namespace="">
                            <xsl:copy-of select="$style/@style:family" />
                            <xsl:copy-of select="$style/@style:name" />
                            <xsl:element name="final-properties" namespace="">
                                <xsl:apply-templates select="$style/*/@*">
                                    <xsl:with-param name="globalData" select="$globalData" />
                                </xsl:apply-templates>
                            </xsl:element>
                        </xsl:element>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:element name="style" namespace="">
                            <xsl:attribute name="style:family">none</xsl:attribute>
                            <xsl:attribute name="style:name"><xsl:value-of select="$style/@style:name"/></xsl:attribute>
                            <xsl:element name="final-properties" namespace="">
                                <xsl:apply-templates select="$style/*/@*">
                                    <xsl:with-param name="globalData" select="$globalData" />
                                </xsl:apply-templates>
                            </xsl:element>
                        </xsl:element>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:otherwise>
        </xsl:choose>
	</xsl:template>
    
	<xsl:template mode="paragraphMerge" match="@fo:margin | @fo:margin-top | @fo:margin-bottom | @fo:margin-left | @fo:margin-right">
		<xsl:text>padding</xsl:text>
        <xsl:value-of select="substring-after(name(), 'fo:margin')"/>
		<xsl:text>:</xsl:text>
		<!-- Map once erroneusly used inch shortage 'inch' to CSS shortage 'in' -->
		<xsl:choose>
			<xsl:when test="contains(., 'inch')">
				<xsl:value-of select="substring-before(.,'ch')"/>
			</xsl:when>
			<xsl:otherwise>
				<xsl:value-of select="."/>
			</xsl:otherwise>
		</xsl:choose>
		<xsl:text>; </xsl:text>
	</xsl:template>    
</xsl:stylesheet>
