<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                              xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<xsl:output method="text"/>

<!-- (c) 2016, Trimble Inc. All rights reserved.                                               -->
<!-- Permission is hereby granted to use, copy, modify, or distribute this style sheet for any -->
<!-- purpose and without fee, provided that the above copyright notice appears in all copies   -->
<!-- and that both the copyright notice and the limited warranty and restricted rights notice  -->
<!-- below appear in all supporting documentation.                                             -->

<!-- TRIMBLE INC. PROVIDES THIS STYLE SHEET "AS IS" AND WITH ALL FAULTS.                       -->
<!-- TRIMBLE INC. SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY               -->
<!-- OR FITNESS FOR A PARTICULAR USE. TRIMBLE INC. DOES NOT WARRANT THAT THE                   -->
<!-- OPERATION OF THIS STYLE SHEET WILL BE UNINTERRUPTED OR ERROR FREE.                        -->

<xsl:decimal-format name="null" NaN='?'/>

<xsl:variable name="Null" select="'?'"/>
<xsl:variable name="Eol" select="'&#13;&#10;'"/>
<xsl:variable name="Space" select="' '"/>
<xsl:variable name="Percent" select="'%'"/>
<xsl:variable name="FieldSeperator" select="'&#9;'"/>
<xsl:variable name="DegreesSymbol" select="'&#xb0;'"/>
<xsl:variable name="MinutesSymbol"><xsl:text>'</xsl:text></xsl:variable>
<xsl:variable name="SecondsSymbol"><xsl:text>"</xsl:text></xsl:variable>

<xsl:variable name="HeightUnit" select="/Stakeout/DisplaySettings/HeightUnits"/>
<xsl:variable name="DistanceUnit" select="/Stakeout/DisplaySettings/DistanceUnits"/>

<xsl:variable name="DistDPs">
  <xsl:choose>
    <xsl:when test="/Stakeout/DisplaySettings/DistanceDisplayDPs = 1">0.0</xsl:when>
    <xsl:when test="/Stakeout/DisplaySettings/DistanceDisplayDPs = 2">0.00</xsl:when>
    <xsl:when test="/Stakeout/DisplaySettings/DistanceDisplayDPs = 3">0.000</xsl:when>
    <xsl:when test="/Stakeout/DisplaySettings/DistanceDisplayDPs = 4">0.0000</xsl:when>
    <xsl:otherwise>0.000</xsl:otherwise>
  </xsl:choose>
</xsl:variable>

<xsl:variable name="HorzDistAbbrev">
  <xsl:choose>
    <xsl:when test="$DistanceUnit ='Metres'"><xsl:text>m</xsl:text></xsl:when>
    <xsl:when test="$DistanceUnit ='InternationalFeet'"><xsl:text>ift</xsl:text></xsl:when>
    <xsl:when test="$DistanceUnit ='USSurveyFeet'"><xsl:text>sft</xsl:text></xsl:when>
  </xsl:choose>
</xsl:variable>

<xsl:variable name="HorzDistFactor">
  <xsl:choose>
    <xsl:when test="$DistanceUnit = 'Metres'">1.0</xsl:when>
    <xsl:when test="$DistanceUnit = 'InternationalFeet'">3.280839895</xsl:when>
    <xsl:when test="$DistanceUnit = 'USSurveyFeet'">3.2808333333357</xsl:when>
    <xsl:otherwise>1.0</xsl:otherwise>
  </xsl:choose>
</xsl:variable>

<xsl:variable name="VertDistAbbrev">
  <xsl:choose>
    <xsl:when test="$HeightUnit ='Metres'"><xsl:text>m</xsl:text></xsl:when>
    <xsl:when test="$HeightUnit ='InternationalFeet'"><xsl:text>ift</xsl:text></xsl:when>
    <xsl:when test="$HeightUnit ='USSurveyFeet'"><xsl:text>sft</xsl:text></xsl:when>
  </xsl:choose>
</xsl:variable>

<xsl:variable name="VertDistFactor">
  <xsl:choose>
    <xsl:when test="$HeightUnit = 'Metres'">1.0</xsl:when>
    <xsl:when test="$HeightUnit = 'InternationalFeet'">3.280839895</xsl:when>
    <xsl:when test="$HeightUnit = 'USSurveyFeet'">3.2808333333357</xsl:when>
    <xsl:otherwise>1.0</xsl:otherwise>
  </xsl:choose>
</xsl:variable>

<xsl:variable name="DisplayFtAndInches">
  <xsl:choose>
    <xsl:when test="(/Stakeout/DisplaySettings/FeetAndInchesDisplayPrecision = 0) or
                    ((/Stakeout/DisplaySettings/FeetAndInchesDisplayPrecision != 0) and ($DistanceUnit ='Metres'))">false</xsl:when>
    <xsl:otherwise>true</xsl:otherwise>
  </xsl:choose>
</xsl:variable>

<xsl:template name="SetZeroValuesAlwaysPositive">
  <xsl:param name="inVal"/>
  
  <xsl:choose>
    <xsl:when test="number($inVal) = 0.0">
      <xsl:value-of select="format-number(0.0, $DistDPs, 'null')"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$inVal"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template name="FormatHorizontalDistance">
  <xsl:param name="Distance"/>
  <xsl:value-of select="$FieldSeperator"/>
  <xsl:choose>
    <xsl:when test="$DisplayFtAndInches = 'false'">
      <xsl:variable name="fmtVal">
        <xsl:value-of select="format-number(number($Distance * $HorzDistFactor),$DistDPs,'null')"/>
      </xsl:variable>
      <xsl:call-template name="SetZeroValuesAlwaysPositive">
        <xsl:with-param name="inVal" select="$fmtVal"/>
      </xsl:call-template>
      <xsl:if test="not(format-number($Distance,'0.000')='NaN')">
        <xsl:value-of select="$HorzDistAbbrev"/>
      </xsl:if>
    </xsl:when>
    <xsl:otherwise>
      <xsl:call-template name="FormattedFeetAndInchesDistance">
        <xsl:with-param name="distVal" select="number($Distance * $HorzDistFactor)"/>
      </xsl:call-template>
    </xsl:otherwise>
  </xsl:choose>
  <xsl:value-of select="$Eol"/>
</xsl:template>

<xsl:template name="FormatPrefixedVerticalDistance">
  <xsl:param name="Distance"/>
  <xsl:value-of select="$FieldSeperator"/>
  <xsl:if test="not(format-number($Distance,'0.000')='NaN')">
    <xsl:variable name="Prefix">
        <xsl:if test="$Distance &lt;= '0.0'"><xsl:text>Cut</xsl:text></xsl:if>
        <xsl:if test="$Distance &gt; '0.0'"><xsl:text>Fill</xsl:text></xsl:if>
    </xsl:variable>
    <xsl:value-of select="$Prefix"/>
    <xsl:value-of select="$Space"/>
  </xsl:if>
  <xsl:variable name="Factor">
    <xsl:if test="$Distance &lt; '0.0'"><xsl:value-of select="number(-1 * $VertDistFactor)"/></xsl:if>
    <xsl:if test="$Distance &gt;= '0.0'"><xsl:value-of select="$VertDistFactor"/></xsl:if>
  </xsl:variable>
  <xsl:choose>
    <xsl:when test="$DisplayFtAndInches = 'false'">
      <xsl:value-of select="format-number(number($Distance * $Factor),$DistDPs,'null')"/>
      <xsl:if test="not(format-number($Distance,'0.000')='NaN')">
        <xsl:value-of select="$VertDistAbbrev"/>
      </xsl:if>
    </xsl:when>
    <xsl:otherwise>
      <xsl:call-template name="FormattedFeetAndInchesDistance">
        <xsl:with-param name="distVal" select="number($Distance * $Factor)"/>
      </xsl:call-template>
    </xsl:otherwise>
  </xsl:choose>

  <!-- Set up the value color based on the sign of the vertical distance -->
  <xsl:variable name="absVertDist" select="concat(substring('-',2 - ($Distance &lt; 0)), '1') * $Distance"/>
  <xsl:value-of select="$FieldSeperator"/>
  <xsl:text>ValueColor=</xsl:text>
  <xsl:choose>
    <xsl:when test="$absVertDist &lt; 0.001">Green</xsl:when>
    <xsl:when test="/Stakeout/DTMDeltas/DeltaElevation &lt; 0.0">Red</xsl:when>
    <xsl:when test="/Stakeout/DTMDeltas/DeltaElevation &gt; 0.0">Blue</xsl:when>
    <xsl:otherwise>Black</xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template name="FormatVerticalDistance">
  <xsl:param name="Distance"/>
  <xsl:value-of select="$FieldSeperator"/>
  <xsl:variable name="Factor">
    <xsl:if test="$Distance &lt; '0.0'"><xsl:value-of select="number(-1 * $VertDistFactor)"/></xsl:if>
    <xsl:if test="$Distance &gt;= '0.0'"><xsl:value-of select="$VertDistFactor"/></xsl:if>
  </xsl:variable>
  <xsl:choose>
    <xsl:when test="$DisplayFtAndInches = 'false'">
      <xsl:value-of select="format-number(number($Distance * $Factor),$DistDPs,'null')"/>
      <xsl:if test="not(format-number($Distance,'0.000')='NaN')">
        <xsl:value-of select="$VertDistAbbrev"/>
      </xsl:if>
    </xsl:when>
    <xsl:otherwise>
      <xsl:call-template name="FormattedFeetAndInchesDistance">
        <xsl:with-param name="distVal" select="number($Distance * $Factor)"/>
      </xsl:call-template>
    </xsl:otherwise>
  </xsl:choose>
  <xsl:if test="not(format-number($Distance,'0.000')='NaN')">
    <xsl:variable name="DirectionSuffix">
      <xsl:if test="$Distance &lt; '0.0'"><xsl:text>Down</xsl:text></xsl:if>
      <xsl:if test="$Distance &gt; '0.0'"><xsl:text>Up</xsl:text></xsl:if>
    </xsl:variable>
    <xsl:value-of select="$Space"/>
    <xsl:value-of select="$DirectionSuffix"/>
  </xsl:if>
</xsl:template>

<!-- **************************************************************** -->
<!-- ********** Formatted feet and inches distance value ************ -->
<!-- **************************************************************** -->
<xsl:template name="FormattedFeetAndInchesDistance">
  <xsl:param name="distVal"/>

  <xsl:variable name="sign">
    <xsl:choose>
      <xsl:when test="number($distVal) &lt; 0.0">-1</xsl:when>
      <xsl:otherwise>1</xsl:otherwise>
    </xsl:choose>
  </xsl:variable>
  <xsl:variable name="feetVal" select="$distVal * $sign"/>
  <xsl:variable name="feet" select="floor($feetVal)"/>
  <xsl:variable name="footFrac" select="$feetVal - $feet"/>
  <xsl:variable name="inch" select="floor($footFrac * 12.0)"/>
  <xsl:variable name="inchFrac" select="$footFrac * 12.0 - $inch"/>
  <xsl:variable name="numerator" select="round($inchFrac * /Stakeout/DisplaySettings/FeetAndInchesDisplayPrecision)"/>

  <xsl:variable name="simplifiedFractionVals">
    <xsl:call-template name="SimplifyFractionValues">
      <xsl:with-param name="numerator" select="$numerator"/>
      <xsl:with-param name="denominator" select="/Stakeout/DisplaySettings/FeetAndInchesDisplayPrecision"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:choose>
    <xsl:when test="string(number($distVal)) = 'NaN'">  <!-- Null value so handle via format command -->
      <xsl:value-of select="format-number($distVal,$DistDPs,'null')"/>
    </xsl:when>
    <xsl:when test="msxsl:node-set($simplifiedFractionVals)/numerator = msxsl:node-set($simplifiedFractionVals)/denominator">
      <!-- We have a whole inch in the fraction part so add 1 to the inch variable and deal with it reaching 12 inches -->
      <xsl:variable name="adjVals">
        <xsl:choose>
          <xsl:when test="$inch + 1 = 12">
            <xsl:element name="inch">0</xsl:element>
            <xsl:element name="feet">
              <xsl:value-of select="$feet + 1"/>
            </xsl:element>
          </xsl:when>
          <xsl:otherwise>
            <xsl:element name="inch">
              <xsl:value-of select="$inch + 1"/>
            </xsl:element>
            <xsl:element name="feet">
              <xsl:value-of select="$feet"/>
            </xsl:element>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:variable>
      <xsl:if test="$sign = -1">-</xsl:if>
      <xsl:if test="msxsl:node-set($adjVals)/feet &gt; 0">
        <xsl:value-of select="msxsl:node-set($adjVals)/feet"/>
        <xsl:text>' </xsl:text>
      </xsl:if>
      <xsl:value-of select="msxsl:node-set($adjVals)/inch"/>
      <xsl:text>"</xsl:text>
    </xsl:when>

    <xsl:otherwise>  <!-- Value with fractions of an inch -->
      <xsl:if test="$sign = -1">-</xsl:if>
      <xsl:if test="$feet &gt; 0">
        <xsl:value-of select="$feet"/>
        <xsl:text>' </xsl:text>
      </xsl:if>
      <xsl:choose>
        <xsl:when test="$inch &gt; 0">
          <xsl:value-of select="$inch"/>
          <xsl:value-of select="' '"/>
        </xsl:when>
        <xsl:otherwise>   <!-- We have 0 inches - if there are no decimals of an inch we should output 0 to give 0" -->
          <xsl:if test="msxsl:node-set($simplifiedFractionVals)/numerator = 0">0</xsl:if>
        </xsl:otherwise>
      </xsl:choose>
      <xsl:if test="msxsl:node-set($simplifiedFractionVals)/numerator &gt; 0">
        <xsl:value-of select="msxsl:node-set($simplifiedFractionVals)/numerator"/>
        <xsl:text>/</xsl:text>
        <xsl:value-of select="msxsl:node-set($simplifiedFractionVals)/denominator"/>
      </xsl:if>
      <xsl:text>"</xsl:text>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<!-- **************************************************************** -->
<!-- ********** Simplifies the values defining a fraction *********** -->
<!-- **************************************************************** -->
<xsl:template name="SimplifyFractionValues">
  <xsl:param name="numerator"/>
  <xsl:param name="denominator"/>

  <xsl:choose>
    <xsl:when test="($numerator &gt; 0) and (($numerator div 2) - floor($numerator div 2) = 0.0)">
      <xsl:call-template name="SimplifyFractionValues">
        <xsl:with-param name="numerator" select="floor($numerator div 2)"/>
        <xsl:with-param name="denominator" select="floor($denominator div 2)"/>
      </xsl:call-template>
    </xsl:when>

    <xsl:otherwise>
      <xsl:element name="numerator">
        <xsl:value-of select="$numerator"/>
      </xsl:element>

      <xsl:element name="denominator">
        <xsl:value-of select="$denominator"/>
      </xsl:element>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template name="FormatElevation">
  <xsl:param name="Elevation"/>
  <xsl:value-of select="$FieldSeperator"/>
  <xsl:value-of select="format-number(number($Elevation * $VertDistFactor),$DistDPs,'null')"/>
  <xsl:if test="not(format-number($Elevation,'0.000')='NaN')">
    <xsl:value-of select="$VertDistAbbrev"/>
  </xsl:if>
  <xsl:value-of select="$Eol"/>
</xsl:template>

<xsl:template match="/Stakeout/Name">
  <xsl:text>LivePointName</xsl:text>
  <xsl:value-of select="$Eol"/>
</xsl:template>

<xsl:template match="/Stakeout/Code">
  <xsl:text>LivePointCode</xsl:text>
  <xsl:value-of select="$Eol"/>
</xsl:template>

<xsl:template match="/Stakeout/Description1">
  <xsl:text>LiveDescription1</xsl:text>
  <xsl:value-of select="$Eol"/>
</xsl:template>

<xsl:template match="/Stakeout/Description2">
  <xsl:text>LiveDescription2</xsl:text>
  <xsl:value-of select="$Eol"/>
</xsl:template>

<xsl:template match="/Stakeout/ComputedGrid">
  <xsl:text>As-staked elevation</xsl:text>
  <xsl:call-template name="FormatElevation">
    <xsl:with-param name="Elevation" select="Elevation"/>
  </xsl:call-template>  
</xsl:template>

<xsl:template match="/Stakeout/DTMDeltas/DeltaElevation">
  <xsl:text>V.Dist surface</xsl:text>
  <xsl:call-template name="FormatPrefixedVerticalDistance">
    <xsl:with-param name="Distance" select="."/>
  </xsl:call-template>
</xsl:template>

<xsl:template match="/Stakeout/DTMDesign/Name">
  <xsl:text>DTM</xsl:text>
  <xsl:value-of select="$FieldSeperator"/>
  <xsl:copy-of select="."/>
  <xsl:value-of select="$Eol"/>
</xsl:template>

<xsl:template match="/Stakeout/DTMDesign/VerticalOffset">
  <xsl:text>V.Offset</xsl:text>
  <xsl:if test="/Stakeout/DTMDesign/OffsetPerpendicularToDTM = 'true'">
    <xsl:text> (</xsl:text>
    <xsl:text>Perpendicular</xsl:text>
    <xsl:text>)</xsl:text>
  </xsl:if>
  <xsl:call-template name="FormatVerticalDistance">
    <xsl:with-param name="Distance" select="."/>
  </xsl:call-template>
</xsl:template>

<!-- Key words that can be used to control the presentation

     Screen display:
     Including the key word WideScreen at the start of the output will instruct
     the Survey Controller to use the full screen width for the output details
     
     Font sizes:
     Font sizes can be defined for the Prompts (PromptSize) and Values (ValueSize)
     There are 3 font sizes available for Prompts: Small, Medium and Large
     There are 4 font sizes available for Values:  Small, Medium, Large and ExtraLarge
     Default Prompt and Value sizes can be set at the start of the output using
     the following commands:
     DefaultPromptSize=Size where Size = Small, Medium or Large
     DefaultValueSize=Size  where Size = Small, Medium, Large or ExtraLarge
     Individual Prompt and Value sizes can be assigned to specific Prompt/Value pairs
     by following the Prompt/Value pair with a second tab separator then space separated
     PromptSize=Size and ValueSize=Size commands where the Size options are as defined 
     above:
     Prompt \t Value \t PromptSize=Size ValueSize=Size\r\n
     
     Font Colors:
     The default color for Prompts and Values is Black but colors can be assigned to
     Prompts and Values on an individual basis by following the Prompt/Value pair with
     a second tab separator then space separated PromptColor=Color and ValueColor=Color
     commands:
     Prompt \t Value \t PromptColor=Color ValueColor=Color\r\n
     The available colors are listed below:
     Red, Mud, Blue, Cyan, Gray, Lime, Navy, Rose, Teal, Black, Brick, Cream, Green, 
     Lemon, Olive, Peach, White, Orange, Purple, Silver, Yellow, Magenta, DarkGray, 
     MediumGray, BlueBlack, LightBlue, RoyalBlue, Turquoise, TrimbleBlue and 
     TrimblePaleBlue
     
     Note: These PromptColor and ValueColor commands can be combined with the PromptSize 
     and ValueSize commands.
-->
  
<xsl:template name="StakeDeltas">
  <xsl:text>GroupboxStart</xsl:text>
  <xsl:value-of select="$FieldSeperator"/>
  <xsl:text>Stake deltas</xsl:text>
  <xsl:value-of select="$Eol"/>  

  <xsl:apply-templates select="/Stakeout/DTMDeltas/DeltaElevation"/>
  <!-- Now set up the prompt and value sizes - color has already been set -->
  <xsl:text> PromptSize=Medium ValueSize=ExtraLarge</xsl:text>
  <xsl:value-of select="$Eol"/>

  <xsl:text>GroupboxEnd</xsl:text>
  <xsl:value-of select="$Eol"/>
</xsl:template>

<xsl:template name="DTM">
  <xsl:if test="(/Stakeout/DTMDesign/VerticalOffset != '') and (/Stakeout/DTMDesign/VerticalOffset != 0)">
    <xsl:text>GroupboxStart</xsl:text>
    <xsl:value-of select="$FieldSeperator"/>
    <xsl:text>Surface</xsl:text>
    <xsl:value-of select="$Eol"/>

    <xsl:apply-templates select="/Stakeout/DTMDesign/VerticalOffset"/>
    <!-- Now set up the prompt and value sizes and set the color to Purple to highlight it -->
    <xsl:value-of select="$FieldSeperator"/>
    <xsl:text>PromptSize=Medium ValueSize=ExtraLarge ValueColor=Purple</xsl:text>
    <xsl:value-of select="$Eol"/>

    <xsl:text>GroupboxEnd</xsl:text>
    <xsl:value-of select="$Eol"/>
  </xsl:if>
</xsl:template>

<xsl:template match="/Stakeout">
  <xsl:text>WideScreen</xsl:text>
  <xsl:value-of select="$Eol"/>  
  <xsl:call-template name="StakeDeltas"/>
  <xsl:call-template name="DTM"/>
</xsl:template>

</xsl:stylesheet>