<?xml version="1.0" encoding="utf-8"?>
<!--

Copyright (c) 2002,2003 The Regenstrief Institute.  All rights reserved.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

Written by Gunther Schadow.

$Id: crl-reportdump.xsl,v 1.3 2005/02/18 04:16:31 gschadow Exp $

-->
<xsl:transform version="1.0"
   xmlns:saxon="http://saxon.sf.net/"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:ex="http://xwsf.sf.net/net.sf.xwsf.saxon.ExceptionElementFactory"
   xmlns:exd="http://xwsf.sf.net/exception"
   xmlns:rs="java:java.sql.ResultSet"
   xmlns:sys="java:java.lang.System"
   xmlns:gut="http://aurora.regenstrief.org/XML/GenericUpTranslator"
   extension-element-prefixes="saxon ex sys"
   exclude-result-prefixes="saxon ex rs exd sys gut">
<!-- reportdump

  Dump text reports from the data base.

  Input:

  <report-batch>
    <report id="..."/>
    <report id="..."/>
    <report id="..."/>
    ...
  </report-batch>

  Output:

  <report-batch>
    <report>...</report>
    <report>...</report>
    <report>...</report>
    ...
  </report-batch>

  The <report-batch/> element is optional, if the request contains it,
  the result will contain it if not, it won't (which may lead to an
  XML fragment with more than one toplevel node.) 

  If no id attribute is specified at the <report/>, then all reports
  are returned!

CODE   NAME                        TARGET_CODE COUNT

19559  SURGICAL PATHOLOGY RPT           19589  321131
...
29554  Pathology Report Miscellaneous   19589  111279
17869  Tissue Exam                      6226   88108
...
19566  DERMATOLOGY REPORT               19589  2479
...
19560  PED SURG PATH REPORT             19589  1120
...
6278   BIOPSY: B MAR                    19589  748
19562  NEURO PATHOLOGY REPORT           19589  667    ***
...

                                         TOTAL 525532 

-->

  <xsl:import href="exception.xsl"/>
  <xsl:import href="db-common.xsl"/>
 
  <xsl:output method="xml" 
	      indent="no" 
	      encoding="UTF-8"
	      media-type="text/xml"/>
  <xsl:strip-space elements="*"/>

  <xsl:param name="debug" select="0"/>
  <xsl:param name="use-clob" select="/*/@use-clob"/>
  <xsl:param name="immediate" select="/.."/>

  <xsl:param name="reportSQL">
     SELECT /*+FIRST_ROWS*/
            C.INSTITUTION_ID,
            M.MULTIMEDIA_CONTENT_ID,
	    C.PATIENT_ID,
            O.SERVICE_CODE,
            O.SERVICE_SYS_ID,
            O.PHYSIOLOGIC_TIME,
            M.MIME_TYPE_CODE,
            M.MULTIMEDIA_TEXT_CONTENT,
	    C.ITEM_400 AS ICDO_SITE,
	    C.ITEM_410 AS ICDO_LATERALITY,
	    NVL(C.ITEM_420,C.ITEM_522) AS ICDO_MORPHOLOGY,
	    NVL(C.ITEM_430,C.ITEM_523) AS ICDO_BEHAVIOR
       FROM CRL_REPORT_GOLD C
         INNER JOIN RMRS.MEDICAL_ORDER O
	   USING(MEDICAL_ORDER_ID)
         INNER JOIN RMRS.MULTIMEDIA_CONTENT M 
           USING(MEDICAL_ORDER_ID)
  </xsl:param>

  <xsl:param name="namesSQL">
    SELECT NAME_FIRST,
            NAME_LAST
       FROM RMRS.PATIENT_ALIAS_NAME
       WHERE (INSTITUTION_ID = ? AND PATIENT_ID = ?)
   UNION ALL
     SELECT NAME_FIRST,
            NAME_LAST
       FROM RMRS.PATIENT
       WHERE (INSTITUTION_ID = ? AND PATIENT_ID = ?)
  </xsl:param>
  <xsl:param name="namesStmt"
       xmlns:cn="java:java.sql.Connection"
       select="cn:prepareStatement($connection, $namesSQL)"/>

  <xsl:template match="/">
    <ex:try atomic="no">
      <xsl:choose>
        <xsl:when test="$immediate">
	  <xsl:message><IMMEDIATE id="{$immediate}"/></xsl:message>
	  <xsl:variable name="fake"><report/></xsl:variable>
          <xsl:apply-templates mode="sqlselect" select="$fake">
            <xsl:with-param name="whereClause"
              select="concat(' WHERE MULTIMEDIA_CONTENT_ID = ',$immediate)"/>
          </xsl:apply-templates>
        </xsl:when>
        <xsl:otherwise>
          <xsl:apply-templates select="node()"/>
        </xsl:otherwise>
      </xsl:choose>

      <ex:catch exception="java.lang.Throwable">
        <xsl:message terminate="yes">
	  <xsl:call-template name="exd:dump">
	    <xsl:with-param name="name" select="'ERROR'"/>
	  </xsl:call-template>
        </xsl:message>
      </ex:catch>
      <ex:finally>
        <xsl:sequence xmlns:c="java:java.sql.Connection"
                      select="c:close($connection)"/>
      </ex:finally>
    </ex:try>  
  </xsl:template>

  <xsl:template match="@*|node()">
    <xsl:apply-templates select="@*|node()"/>
  </xsl:template>

  <xsl:template match="report-batch">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="report">
    <xsl:param name="whereClause">
      <xsl:apply-templates mode="makeWhereClause" select="@*|node()"/>
    </xsl:param>
    <xsl:choose>
      <xsl:when test="$whereClause">
        <xsl:apply-templates mode="sqlselect" select=".">
          <xsl:with-param name="whereClause"
	    select="concat(' WHERE',substring-after($whereClause, 'AND'))"/>
        </xsl:apply-templates>
      </xsl:when>
      <xsl:otherwise>
        <xsl:apply-templates mode="sqlselect" select="."/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <xsl:template mode="sqlselect" match="report">
    <xsl:param name="schema" select="ancestor-or-self::*/@schema[1]"/>
    <xsl:param name="whereClause" select="''"/>
    <xsl:if test="$debug > 1">
      <xsl:message>
	<reportSQL>
          <xsl:value-of select="concat($reportSQL,$whereClause)"/>
	</reportSQL>
      </xsl:message>
    </xsl:if>
    <xsl:variable name="rset"
       xmlns:cn="java:java.sql.Connection"
       xmlns:st="java:java.sql.Statement"
       select="st:executeQuery(cn:createStatement($connection), 
                               concat($reportSQL,$whereClause))"/>

    <saxon:while test="rs:next($rset)">
      <xsl:variable name="id" 
	  select="rs:getLong($rset,'MULTIMEDIA_CONTENT_ID')"/>
      <xsl:variable name="institutionId" 
	  select="rs:getLong($rset,'INSTITUTION_ID')"/>
      <xsl:variable name="patientId" 
	  select="rs:getLong($rset,'PATIENT_ID')"/>
      <xsl:message>
      	<report id="{$id}" institutionId="{$institutionId}"/>
      </xsl:message>
      <ex:try atomic="yes">
        <xsl:variable name="textString">
          <xsl:choose>
            <xsl:when test="$use-clob='no'">
      	<xsl:value-of 
      	   select="rs:getString($rset,'MULTIMEDIA_TEXT_CONTENT')"/>
            </xsl:when>
            <xsl:otherwise>
      	<xsl:variable name="textClob"
      	   select="rs:getClob($rset,'MULTIMEDIA_TEXT_CONTENT')"/>       
      	<xsl:value-of xmlns:clob="java:java.sql.Clob"
      	   select="clob:getSubString($textClob,1,
      				     clob:length($textClob))"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:variable>
        <xsl:variable name="text">
          <ex:try atomic="yes">
            <xsl:apply-templates mode="strip-tags" 
      	 select="saxon:parse($textString)"/>
      
            <ex:catch exception="java.lang.Throwable">
      	<xsl:if test="$debug > 0">
      	  <xsl:message>
      	    <WARNING exception="{ex:current-exception()}"/>
      	  </xsl:message>
      	</xsl:if>
      	<ex:try atomic="yes" xmlns:t="java:org.regenstrief.saxon.tidy">
      	  <xsl:variable name="tidy-text" 
      	    select="t:tidy(rs:getAsciiStream($rset,'MULTIMEDIA_TEXT_CONTENT'))"/>
      	  <xsl:apply-templates mode="strip-tags" 
      	    select="saxon:parse($tidy-text)"/>
      
      	  <ex:catch exception="java.lang.Throwable">
      	    <xsl:message>
      	      <WARNING id="{$id}" 
      		       exception="{ex:current-exception()}"/>
      	    </xsl:message>
      	  </ex:catch>
      	</ex:try>
            </ex:catch>
          </ex:try>
        </xsl:variable>
        <xsl:if test="$text/text()">
          <report id="{$id}"
      	          institutionId="{$institutionId}"
      	          code="{rs:getString($rset,'SERVICE_CODE')}"
      	          physiologicTime="{rs:getTimestamp($rset,'PHYSIOLOGIC_TIME')}"		         site="{rs:getString($rset,'ICDO_SITE')}" 
	          laterality="{rs:getString($rset,'ICDO_LATERALITY')}" 
		  morphology="{rs:getString($rset,'ICDO_MORPHOLOGY')}/{rs:getString($rset,'ICDO_BEHAVIOR')}">

            <xsl:variable name="namesResultSet"
                  xmlns:cn="java:java.sql.Connection"
                  xmlns:st="java:java.sql.PreparedStatement"
                  select="xwsf:progn(st:setLong($namesStmt, 1, $institutionId),
                           st:setLong($namesStmt, 2, $patientId),
			   st:setLong($namesStmt, 3, $institutionId),
                           st:setLong($namesStmt, 4, $patientId),
                           st:executeQuery($namesStmt))"/>
            <saxon:while test="rs:next($namesResultSet)">
               <scrubWords>
                 <word>
 	           <xsl:value-of select="rs:getString($namesResultSet,1)"/>
                 </word>
                 <word>
 	           <xsl:value-of select="rs:getString($namesResultSet,2)"/>
                 </word>
               </scrubWords>
            </saxon:while>
      	    <xsl:sequence select="$text"/>
          </report>
        </xsl:if>
        <ex:catch exception="java.lang.Throwable">
          <xsl:call-template name="exd:dump">
            <xsl:with-param name="name" select="exception"/>
          </xsl:call-template>
        </ex:catch>
      </ex:try>
    </saxon:while>
  </xsl:template>

<!-- MODE: makeWhereClause -->

<xsl:template mode="makeWhereClause" match="report/@id[../@max]" priority="3">
  <xsl:text> AND M.MULTIMEDIA_CONTENT_ID >= </xsl:text>
  <xsl:value-of select="."/>
</xsl:template>

<xsl:template mode="makeWhereClause" match="report/@id">
  <xsl:text> AND M.MULTIMEDIA_CONTENT_ID = </xsl:text>
  <xsl:value-of select="."/>
</xsl:template>

<xsl:template mode="makeWhereClause" match="report/@code">
  <xsl:text> AND ( O.SERVICE_SYS_ID=1 AND O.SERVICE_CODE IN (''</xsl:text>
  <xsl:for-each select="tokenize(., '\s+')">
     <xsl:text>, '</xsl:text>
     <xsl:value-of select="."/>
     <xsl:text>'</xsl:text>
  </xsl:for-each>
  <xsl:text>) )</xsl:text>
</xsl:template>

<xsl:template mode="makeWhereClause" match="report/@patientId">
  <xsl:text> AND O.PATIENT_ID = </xsl:text>
  <xsl:value-of select="."/>
</xsl:template>

<xsl:template mode="makeWhereClause" match="report/@orderId">
  <xsl:text> AND O.MEDICAL_ORDER_ID = </xsl:text>
  <xsl:value-of select="."/>
</xsl:template>

<xsl:template mode="makeWhereClause" match="report/@institutionId">
  <xsl:text> AND O.INSTITUTION_ID = </xsl:text>
  <xsl:value-of select="."/>
</xsl:template>

<xsl:template mode="makeWhereClause" match="report/@physiologicTime">
  <xsl:variable name="times" select="tokenize(., '~')"/>  
  <xsl:choose>
    <xsl:when test="count($times) = 1">
      <xsl:text> AND O.PHYSIOLOGIC_TIME > TO_DATE('</xsl:text>
      <xsl:value-of select="$times[1]"/>
      <xsl:text>')</xsl:text>
    </xsl:when>
    <xsl:when test="count($times) = 2">
      <xsl:text> AND O.PHYSIOLOGIC_TIME BETWEEN TO_DATE('</xsl:text>
      <xsl:value-of select="$times[1]"/>
      <xsl:text>') AND TO_DATE('</xsl:text>
      <xsl:value-of select="$times[2]"/>
      <xsl:text>')</xsl:text>
    </xsl:when>
  </xsl:choose>
</xsl:template>

<xsl:template mode="makeWhereClause" match="report/@max">
  <xsl:text> AND ROWNUM &lt;= </xsl:text>
  <xsl:value-of select="."/>
</xsl:template>

<xsl:template mode="makeWhereClause" match="/|@*|node()">
  <xsl:apply-templates mode="makeWhereClause" select="@*|node()"/>
</xsl:template>


<!-- MODE: text -->

<xsl:template mode="text" match="/|@*|node()">
  <xsl:copy>
    <xsl:apply-templates mode="text" select="@*|node()"/>
  </xsl:copy>
</xsl:template>

<xsl:template mode="text" match="text_report">
  <text>
    <xsl:apply-templates mode="text" select="@*|node()"/>    
  </text>
</xsl:template>

<xsl:template mode="text" match="text">
  <p>
    <xsl:apply-templates mode="text" select="@*|node()"/>    
  </p>
</xsl:template>

<!-- MODE: strip-tags: remove all layout tags and render everything in
       plain text.  This is a deep null-transform that only catches
       text nodes and some handling of paragraphs, text_report,
       text/@title etc.  
-->
<xsl:template mode="strip-tags" match="/|node()|@*">
  <xsl:apply-templates mode="strip-tags" select="@*|node()"/>
</xsl:template>

<xsl:template mode="strip-tags" match="text()" priority="0">
  <xsl:value-of select="current()"/>
</xsl:template>

<xsl:template mode="strip-tags" 
	      match="text[@title and starts-with(text()[1],@title)]"
	      priority="3">
  <xsl:value-of select="'&#xA;'"/>
  <xsl:value-of select="@title"/>
  <xsl:value-of select="':&#xA;'"/>
  <xsl:value-of 
       select="substring-after(substring-after(text()[1],@title),':')"/>
  <xsl:apply-templates mode="strip-tags" select="@*|node() except text()[1]"/>
  <xsl:value-of select="'&#xA;'"/>
</xsl:template>

<xsl:template mode="strip-tags" match="text[@title]">
  <xsl:value-of select="'&#xA;'"/>
  <xsl:value-of select="@title"/>
  <xsl:value-of select="':&#xA;'"/>
  <xsl:apply-templates mode="strip-tags" select="@*|node()"/>
  <!-- xsl:value-of select="'&#xA;'"/-->
</xsl:template>

<xsl:template mode="strip-tags" match="p">
  <xsl:value-of select="'&#xA;'"/>
  <xsl:apply-templates mode="strip-tags" select="@*|node()"/>
  <xsl:value-of select="'&#xA;'"/>
</xsl:template>

<xsl:template mode="strip-tags" match="br">
  <xsl:value-of select="'&#xA;'"/>
</xsl:template>

</xsl:transform>
