<?xml version="1.0" encoding="Shift_JIS" ?>
<!-- Copyright (c) 2000 Yasuko Yokota -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<!-- ルート要素 -->
<xsl:template match="/">
  <html>
    <head>
      <title>
        <xsl:apply-templates mode="title"/>
      </title>
    </head>
    <body>
      <h2><xsl:apply-templates mode="title"/></h2>
      <xsl:apply-templates mode="list"/>
      <xsl:apply-templates select="//accounts"/>

    </body>
  </html>
</xsl:template>

<!-- 家計簿タイトル -->
<xsl:template match="monthly" mode="title">
  <xsl:value-of select="@year"/>年<xsl:value-of select="@month"/>月の家計簿
</xsl:template>

<!-- 入力データ一覧表 -->
<xsl:template match="monthly" mode="list">
  <h2>
    <apply-templates select="." mode="title"/>
  </h2>
  <table border="2">
    <tr>
      <th>日付</th>
      <th nowrap="">種類</th>
      <th width="100">金額</th>
      <th>口座</th>
      <th>費目</th>
      <th>摘要</th>
    </tr>
    <xsl:apply-templates select="line" mode="list"/>
  </table>
</xsl:template>

<!-- 表の一行 -->
<xsl:template match="line" mode="list">
  <tr>
    <!-- 日付 -->
    <td align="right" nowrap=""><xsl:value-of select="@day"/></td>

    <!-- 種類 -->
    <td>
      <xsl:choose>
        <xsl:when test="@type='income'">収入</xsl:when>
        <xsl:when test="@type='outgo'">支出</xsl:when>
        <xsl:when test="@type='move'">移動</xsl:when>
        <xsl:when test="@type='check'">残高</xsl:when>
      </xsl:choose>
    </td>

    <!-- 金額 -->
    <td align="right">
      <xsl:choose>

        <!-- 口座間移動は括弧で囲む -->
        <xsl:when test="@type='move'">
          (<xsl:value-of select="format-number( @amount, '###,##0' )"/>)
        </xsl:when>

        <!-- 残高入力は斜体 -->
        <xsl:when test="@type='check'">
          <i><xsl:value-of select="format-number( @amount, '###,##0' )"/></i>
        </xsl:when>

        <!-- 収入・支出は通常の数字 -->
        <xsl:otherwise>
          <xsl:value-of select="format-number( @amount, '###,##0' )"/>
        </xsl:otherwise>
      </xsl:choose>
    </td>

    <!-- 口座（出金口座→入金口座）-->
    <td>
      <xsl:value-of select="@from"/>
      <xsl:if test="@type='move'">
        <xsl:text> → </xsl:text>
      </xsl:if>
      <xsl:value-of select="@to"/>
      <xsl:value-of select="@account"/>
    </td>

    <!-- 分類 -->
    <td>
      <xsl:choose>
        <xsl:when test="@group=''"><hr/></xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="@group"/>
        </xsl:otherwise>
      </xsl:choose>
    </td>

    <!-- 摘要 -->
    <td>
      <xsl:choose>
        <xsl:when test=".=''"><xsl:text>　</xsl:text></xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="."/>
        </xsl:otherwise>
      </xsl:choose>
    </td>
  </tr>
</xsl:template>

<!-- 残高計算 -->
<!-- カレントノード : 最後の残高入力line -->
<xsl:template match="line" mode="sumAccount">
  <xsl:variable name="account" select="@account"/>
  <!-- 支出合計 -->
  <xsl:variable name="outgoSum">
    <xsl:choose>
      <xsl:when test="sum( following-sibling::line[@from=$account]/@amount )">
        <xsl:value-of select="sum( following-sibling::line[@from=$account]/@amount )"/>
      </xsl:when>
      <xsl:otherwise>0</xsl:otherwise>
    </xsl:choose>
  </xsl:variable>
  <!-- 収入合計 -->
  <xsl:variable name="incomeSum">
    <xsl:choose>
      <xsl:when test="sum( following-sibling::line[@to=$account]/@amount )">
        <xsl:value-of select="sum( following-sibling::line[@to=$account]/@amount )"/>
      </xsl:when>
      <xsl:otherwise>0</xsl:otherwise>
    </xsl:choose>
  </xsl:variable>
  <xsl:value-of select="@amount + $incomeSum - $outgoSum"/>
</xsl:template>

<!-- 各口座ごとの収入・支出・不明金・収支・残高と合計 -->
<xsl:template match="accounts">

  <table border="2">
    <tr><th colspan="8">【口座情報】</th></tr>
    <!-- 項目欄 -->
    <tr>
      <th>　</th>
      <th>収入</th>
      <th>支出</th>
      <th>不明金</th>
      <th>収支</th>
      <th>移入</th>
      <th>移出</th>
      <th>残高</th>
    </tr>

    <!-- 口座ごとに -->
    <xsl:for-each select="account">
      <xsl:variable name="account" select="@name"/>
      <tr>
        <!-- 口座名 -->
        <th><xsl:value-of select="$account"/></th>
        <!-- 収入計算 -->
        <xsl:variable name="incomeSum">
          <xsl:apply-templates mode="sumIncome" select="//monthly">
            <xsl:with-param name="targetAccount" select="$account"/>
          </xsl:apply-templates>
        </xsl:variable>
        <xsl:variable name="outgoSum">
          <xsl:apply-templates mode="sumOutgo" select="//monthly">
            <xsl:with-param name="targetAccount" select="$account"/>
          </xsl:apply-templates>
        </xsl:variable>

        <!-- 収入表示 -->
        <td align="right">
          <xsl:value-of select="format-number( $incomeSum, '###,##0' )"/>
        </td>
        <!-- 支出表示 -->
        <td align="right">
          <xsl:value-of select="format-number( $outgoSum, '###,##0' )"/>
        </td>

        <!-- 現実の残高を計算 -->
        <xsl:variable name="realBalance">
          <xsl:apply-templates mode="sumAccount" select="//line[@account=$account and @type='check'][position()=last()]"/>
        </xsl:variable>
　　　　<!-- 仮想的な残高を計算 -->
        <xsl:variable name="virtualBalance">
          <xsl:apply-templates mode="sumAccount" select="//line[@account=$account and @type='check'][position()=1]"/>
        </xsl:variable>

        <!-- 不明金表示 -->
        <td align="right">
          <xsl:value-of select="format-number( $realBalance - $virtualBalance, '###,##0' )"/>
        </td>
        <!-- 収支表示 -->
        <td align="right">
          <xsl:value-of select="format-number( $incomeSum - $outgoSum + $realBalance - $virtualBalance, '###,##0' )"/>
        </td>

        <!-- 移入計算 -->
        <xsl:variable name="moveInSum">
          <xsl:apply-templates mode="sumMoveIn" select="//monthly">
            <xsl:with-param name="targetAccount" select="$account"/>
          </xsl:apply-templates>
        </xsl:variable>
        <!-- 移出計算 -->
        <xsl:variable name="moveOutSum">
          <xsl:apply-templates mode="sumMoveOut" select="//monthly">
            <xsl:with-param name="targetAccount" select="$account"/>
          </xsl:apply-templates>
        </xsl:variable>

        <!-- 移入表示 -->
        <td align="right">
          <xsl:value-of select="format-number( $moveInSum, '###,##0' )"/>
        </td>
        <!-- 移出表示 -->
        <td align="right">
          <xsl:value-of select="format-number( $moveOutSum, '###,##0' )"/>
        </td>
        <!-- 残高表示 -->
        <td align="right">
          <xsl:value-of select="format-number( $realBalance, '###,##0' )"/>
        </td>
      </tr>
    </xsl:for-each>

    <!-- 各口座合計を求めるための再帰計算をして結果を表示 -->
    <tr>
      <th>合計</th>
      <!-- 収入合計計算 -->
      <xsl:variable name="incomeSum">
        <xsl:apply-templates select="account[position()=1]">
          <xsl:with-param name="type">income</xsl:with-param>
        </xsl:apply-templates>
      </xsl:variable>
      <!-- 支出合計計算 -->
      <xsl:variable name="outgoSum">
        <xsl:apply-templates select="account[position()=1]">
          <xsl:with-param name="type">outgo</xsl:with-param>
        </xsl:apply-templates>
      </xsl:variable>

      <!-- 収入合計表示 -->
      <td align="right">
        <xsl:value-of select="format-number($incomeSum, '###,##0')"/>
      </td>
      <!-- 支出合計表示 -->
      <td align="right">
        <xsl:value-of select="format-number($outgoSum, '###,##0')"/>
      </td>

      <!-- 現実の残高合計を計算 -->
      <xsl:variable name="realBalance">
        <xsl:apply-templates select="account[position()=1]">
          <xsl:with-param name="type">realBalance</xsl:with-param>
        </xsl:apply-templates>
      </xsl:variable>
      <!-- 仮想的な残高合計を計算 -->
      <xsl:variable name="virtualBalance">
        <xsl:apply-templates select="account[position()=1]">
          <xsl:with-param name="type">virtualBalance</xsl:with-param>
        </xsl:apply-templates>
      </xsl:variable>

      <!-- 不明金合計表示 -->
      <td align="right">
        <xsl:value-of select="format-number($realBalance - $virtualBalance, '###,##0')"/>
      </td>
      <!-- 収支合計表示 -->
      <td align="right">
        <xsl:value-of select="format-number($incomeSum - $outgoSum + $realBalance - $virtualBalance, '###,##0')"/>
      </td>

      <!-- 移入・移出合計はスキップ-->
      <td colspan="2"><hr/></td>

      <!-- 残高合計表示 -->
      <td align="right">
        <xsl:value-of select="format-number($realBalance, '###,##0')"/>
      </td>
    </tr>
  </table>

</xsl:template>

<!-- 特定の口座の収入を合計 -->
<xsl:template match="monthly" mode="sumIncome">
  <xsl:param name="targetAccount"/>
  <xsl:choose>
    <!-- 該当入力データがあれば合計値、なければ0-->
    <xsl:when test="line/@amount[../@type='income' and ../@to=$targetAccount]">
      <xsl:value-of select="sum(line/@amount[../@type='income' and ../@to=$targetAccount])"/>
    </xsl:when>
    <xsl:otherwise>0</xsl:otherwise>
  </xsl:choose>
</xsl:template>

<!-- 特定の口座の支出を合計 -->
<xsl:template match="monthly" mode="sumOutgo">
  <xsl:param name="targetAccount"/>
  <xsl:choose>
    <!-- 該当入力データがあれば合計値、なければ0-->
    <xsl:when test="line/@amount[../@type='outgo' and ../@from=$targetAccount]">
      <xsl:value-of select="sum(line/@amount[../@type='outgo' and ../@from=$targetAccount])"/>
    </xsl:when>
    <xsl:otherwise>0</xsl:otherwise>
  </xsl:choose>
</xsl:template>

<!-- 特定の口座の移入を合計 -->
<xsl:template match="monthly" mode="sumMoveIn">
  <xsl:param name="targetAccount"/>
  <xsl:choose>
    <!-- 該当入力データがあれば合計値、なければ0-->
    <xsl:when test="line/@amount[../@type='move' and ../@to=$targetAccount]">
      <xsl:value-of select="sum(line/@amount[../@type='move' and ../@to=$targetAccount])"/>
    </xsl:when>
    <xsl:otherwise>0</xsl:otherwise>
  </xsl:choose>
</xsl:template>

<!-- 特定の口座の移出を合計 -->
<xsl:template match="monthly" mode="sumMoveOut">
  <xsl:param name="targetAccount"/>
  <xsl:choose>
    <!-- 該当入力データがあれば合計値、なければ0-->
    <xsl:when test="line/@amount[../@type='move' and ../@from=$targetAccount]">
      <xsl:value-of select="sum(line/@amount[../@type='move' and ../@from=$targetAccount])"/>
    </xsl:when>
    <xsl:otherwise>0</xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- 各口座の各データを順次加算するための再帰テンプレート -->
<!-- 入力；何個めかのaccount -->
<xsl:template match="account">
  <xsl:param name="type"/>

  <xsl:variable name="account" select="@name"/>
  <!-- 値の計算 -->
  <xsl:variable name="this">
    <xsl:choose>
      <!-- 収入 -->
      <xsl:when test="$type='income'">
        <xsl:apply-templates mode="sumIncome" select="//monthly">
          <xsl:with-param name="targetAccount" select="$account"/>
        </xsl:apply-templates>
      </xsl:when>
      <!-- 支出 -->
      <xsl:when test="$type='outgo'">
        <xsl:apply-templates mode="sumOutgo" select="//monthly">
          <xsl:with-param name="targetAccount" select="$account"/>
        </xsl:apply-templates>
      </xsl:when>
      <!-- 現実の残高 -->
      <xsl:when test="$type='realBalance'">
        <xsl:apply-templates mode="sumAccount" select="//line[@account=$account and @type='check'][position()=last()]"/>
      </xsl:when>
      <!-- 仮想的な残高 -->
      <xsl:when test="$type='virtualBalance'">
        <xsl:apply-templates mode="sumAccount" select="//line[@account=$account and @type='check'][position()=1]"/>
      </xsl:when>
      <xsl:otherwise>0</xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <!-- 次のノードがあれば再帰して、返値を足す -->
  <xsl:variable name="others">
    <xsl:choose>
      <xsl:when test="following-sibling::account">
        <xsl:apply-templates select="following-sibling::account">
          <xsl:with-param name="type" select="$type"/>
        </xsl:apply-templates>
      </xsl:when>
      <xsl:otherwise>0</xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:value-of select="$this + $others"/>
</xsl:template>

</xsl:stylesheet>

