<xsl:transform
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   version="1.0">

<!-- This is the XML Photo Gallery.  It is an XSLT stylesheet which
     transforms a gallery XML file (which conforms to gallery.dtd)
     into a dynamic HTML/CSS/JavaScript photo gallery for display in
     a web browser.
-->

<!--
     This file is part of the XML Photo Gallery Project
     by Philip J. Guo (Created August 2005)
     Copyright 2005 Philip J. Guo
     http://alum.mit.edu/www/pgbovine/

       based on the People Photo Gallery Project
       by Philip J. Guo (Created January 2005)
       Copyright 2005 Philip J. Guo

     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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

Major changes:
08-02-2005 - Forked off of people_gal.htm by converting it from HTML to XHTML
08-06-2005 - Converted from XHTML page which loads XML files via JavaScript
             into an XSLT template which directly loads XML files
04-28-2009 - Made it generate (hopefully) legal XHTML so that it can
             properly display in Firefox 3
05-01-2009 - Radically changed the gallery UI to not have the thumbnails bar 
             ever shift positions
-->

<!-- Fill up the JavaScript images[] array, one image at a time -->
<xsl:template match="image">

   <!-- For some reason, it's very important that we don't have 
	spaces in each line of images.push(); -->
   images.push(new MyImage("<xsl:value-of select="filename"/>", "<xsl:apply-templates select="title"/>", "<xsl:apply-templates select="description"/>", <xsl:value-of select="date/month"/>, <xsl:value-of select="date/year"/>, <xsl:value-of select="physical/width"/>, <xsl:value-of select="physical/height"/>));

</xsl:template>

<xsl:template match="gallery">
    <html>
      <head>
	<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type" />
        <title>
          <xsl:value-of select="galleryName"/> | XML Photo Gallery
        </title>
        <link rel="stylesheet" type="text/css" href="xml_gal_style.css" />
        
	<!-- JavaScript includes -->
        <script type="text/javascript" language="javascript" src="xml_gal.js" />
        
	<!-- Gallery data initialized by XSLT and passed into JavaScript -->
	<script type="text/javascript" language="javascript">

function InitData() {
  images = new Array();

  numImages = <xsl:value-of select="count(//image)"/>;

  folderName = "<xsl:value-of select="folderName"/>";
  galleryName = "<xsl:value-of select="galleryName"/>";

  actualwidth = (numImages + 4) * totalImageWidth;
         
  <!-- fill up the images[] array here -->
  <xsl:apply-templates select="images/image"/>

  checkBrowserWidth();
}

// Set a 1-second delay before initialization to prevent Safari from screwing up
// Hmm, it seems that body onload="InitGallery()" works better :)
//setTimeout("InitGallery()", 1000)

	</script>            

      </head>

      <body onload="InitGallery()" 
            onkeydown="return HandleKeyDown(event);" 
            onkeyup="buttonHeldDown=false;">
        <xsl:apply-templates select="images"/>
      </body>

    </html>
</xsl:template>
    
<!-- This template fills up the body of the HTML file -->
<xsl:template match="images">

    <center>

      <div id="MainDisplayPanel"> 

         <div id="sliderPane" class="sliderPane">
          <div class="centerSlide">
            <img class="thumbnail" 
                 src="transparent_frame_160.gif" 
                 alt="center thumbnail"
                 onclick="SelectCenterImage();" />
          </div> <!-- centerSlide -->

          <!--
              width of the slider = 5 slides * 150px per slide = 750px
              height of the slider = 142px
            -->
	  <div style="position: relative; width: 750px; height: 142px; overflow: hidden;">

	    <span id="SliderContents" style="text-align:center; 
					     position:absolute; 
					     top:0px; left:0px;">

	      <nobr>

		<xsl:for-each select="image">
		  <xsl:variable name="filename" select="filename"/>

                  <div class="slide">
                    <xsl:attribute name="style">
                      left:<xsl:value-of select="(position() + 1) * 150" />px;
                    </xsl:attribute>

                    <img alt="thumb" class="thumbnail">              
                      <xsl:attribute name="src">
                        <xsl:value-of select="//folderName"/>/thumbnails/<xsl:value-of select="$filename"/>
                      </xsl:attribute>
                        
<!-- The thumbnail dimensions should have their longer side be 130 pixels, and the slide 
     dimensions are 150 x 142 -->

                      <xsl:attribute name="style">
                        position: absolute;

                        top:
                        <xsl:variable name="myHStr" select="physical/height" />
                        <xsl:variable name="myWStr" select="physical/width" />
			<xsl:variable name="myH" select="number($myHStr)" />
			<xsl:variable name="myW" select="number($myWStr)" />

                        <xsl:choose>
                          <xsl:when test="$myH &gt; $myW">
                            4px;
                          </xsl:when>
                	  <xsl:otherwise>
                            20px;
                	  </xsl:otherwise>
                        </xsl:choose>
                            
                        left:

                        <xsl:choose>
                         <xsl:when test="$myH &gt; $myW">
			 <xsl:value-of select="((150 - (($myW div $myH) * 130)) div 2) - 2" />px;
<!--				22px; -->
                          </xsl:when>
                	  <xsl:otherwise>
                            5px;
                	  </xsl:otherwise>
                        </xsl:choose>                            

                      </xsl:attribute>                        
                                            
                      <xsl:attribute name="height">
                  
                        <xsl:variable name="myH" select="physical/height" />
                        <xsl:variable name="myW" select="physical/width" />
                  
                        <xsl:choose>
                          <xsl:when test="number($myH) &gt; number($myW)">
                            130px;
                          </xsl:when>
                	  <xsl:otherwise>
                            100px;
                	  </xsl:otherwise>
                        </xsl:choose>
                            
                      </xsl:attribute>

                      <xsl:attribute name="onclick">
                        LoadImage("<xsl:value-of select="$filename"/>", <xsl:value-of select="position() - 1" /> );
                      </xsl:attribute>
                    </img>                    
		  </div> <!-- slide -->
		  
		</xsl:for-each>
		
	      </nobr>

	    </span>
	  </div> <!-- 'hidden' div -->
	</div> <!-- sliderPane -->

  <div class="buttonPane">

          <span class="leftButton">
            <a class="link" onclick='JumpLeftHandler();'>&lt;&lt;</a>
          </span>

          <span class="centerButton">

          <!--
            [
            <a class="link"
               onmousedown='PrevPicHandler();' 
               onmouseup='buttonHeldDown=false;'
               onmouseout='buttonHeldDown=false;'>Prev</a>
            ]
            -->

	    <span id="picIndex">1</span> of <span id="totalPicNum"><xsl:value-of select="count(//image)" /></span> 

          <!--
            [
            <a class="link"
               onmousedown='NextPicHandler();' 
               onmouseup='buttonHeldDown=false;'
               onmouseout='buttonHeldDown=false;'>Next</a>
            ]
            -->
          </span>

          <span class="rightButton">
            <a class="link" onclick='JumpRightHandler();'>&gt;&gt;</a>
          </span>
	
      </div> <!-- buttonPane -->

      <div class="selectedImageSection">

        <div id="photoTitle">
          <span id="title">Please wait ... Loading ... </span>
        </div> <!-- photoTitle -->
	
        <img id="selectedImage" src="" alt="main image" />
                   
        <div id="photoDescription"></div>

        <div id="date"></div>

      </div> <!-- selectedImageSection -->

      <div id="GalleryTitle">
        <xsl:value-of select="//galleryName"/>
      </div>

    </div> <!-- MainDisplayPanel -->


      <div id="ThumbnailsPanel">
        <div id="ThumbnailTitle">
          <xsl:value-of select="//galleryName"/>
        </div> <!-- ThumbnailTitle -->

        <table border="0px" cellpadding="0px" cellspacing="0px" width="800px">
          <xsl:call-template name="create_thumbnails_table">
          </xsl:call-template>
        </table>
      </div> <!-- ThumbnailsPanel -->

      <div class="footer">
	
	<div id="ToggleThumbnails">
	  [
	  <a class="link" id="ToggleThumbnailsLink" onclick='ToggleThumbnailPanel();'>Show Large Images</a>
	  ]
	</div>
	  

	  Gallery generated by <a href="xml_gal.xml">this XSLT stylesheet</a>,
	  <br />
	part of the <a href="http://alum.mit.edu/www/pgbovine/xml_gal_manual.htm">XML Photo
  Gallery</a> project.
    <p />
    Copyright <a href="http://alum.mit.edu/www/pgbovine/">Philip Guo</a>.  All rights reserved.

      </div> <!-- footer -->

    </center>

</xsl:template>


<!-- super nasty recursion to create rows of 5 elements each -->
<xsl:template name="create_thumbnails_table">

  <xsl:param name="num">1</xsl:param> <!-- initial value of 1 -->

  <xsl:if test="$num &lt;= count(//image)">

        <tr>
          <!-- each row has 5 elements -->
          <xsl:for-each select="//image[position() &gt;= $num and position() &lt; $num + 5]">

            <td valign="middle" align="center" height="140px" width="160px">
              
              <a>                
                <img border="0px" class="thumbnail" alt="">
                  <xsl:attribute name="src">
                    <xsl:value-of select="//folderName"/>/thumbnails/<xsl:value-of select="filename"/>
                  </xsl:attribute>
                  
                  <xsl:attribute name="height">
                  
                    <xsl:variable name="myH" select="physical/height" />
                    <xsl:variable name="myW" select="physical/width" />
                  
                    <xsl:choose>
                      <xsl:when test="number($myH) &gt; number($myW)">
                        130px;
                      </xsl:when>
                      <xsl:otherwise>
                        100px;
                      </xsl:otherwise>
                    </xsl:choose>
                    
                  </xsl:attribute>
                  
                  <xsl:attribute name="onclick">
                    <!-- so friggin' tricky, need to get the 0-based index exactly right -->
                    SkipToImage("<xsl:value-of select="filename"/>", <xsl:value-of select="position() + $num - 2" /> );
                  </xsl:attribute>
                </img>
              </a>

            </td>
                       
          </xsl:for-each>
        </tr>

    <!-- nasty recursive call -->
    <xsl:call-template name="create_thumbnails_table">
      <xsl:with-param name="num">
        <!-- each row has 5 elements -->
        <xsl:value-of select="$num + 5"/>
      </xsl:with-param>
    </xsl:call-template>
  </xsl:if>
</xsl:template>


<!-- Ok, I've modified the following function to add in a normalize-space()
     call to strip newline characters as well, because Safari apparently
     doesn't like newlines in strings when processing JavaScript, 
     but Mozilla doesn't mind ... well, gotta make it work on the
     greatest possible number of browsers ... -->

  <!-- XSLT 1.0 doesn't have string replace(), so here is something
       I found at http://aspn.activestate.com/ASPN/Cookbook/XSLT/Recipe/65426 -->
 <!-- reusable replace-string function -->
 <xsl:template name="replace-string">
   <xsl:param name="text"/>
   <xsl:param name="from"/>
   <xsl:param name="to"/>

   <xsl:choose>
     <xsl:when test="contains($text, $from)">

       <xsl:variable name="before" select="substring-before($text, $from)"/>
       <xsl:variable name="after" select="substring-after($text, $from)"/>
<!--       <xsl:variable name="prefix" select="concat($before, $to)"/> -->

       <xsl:value-of select="normalize-space($before)"/>
       <xsl:value-of select="$to"/>
       <xsl:call-template name="replace-string">
	 <xsl:with-param name="text" select="$after"/>
	 <xsl:with-param name="from" select="$from"/>
	 <xsl:with-param name="to" select="$to"/>
       </xsl:call-template>
     </xsl:when> 
     <xsl:otherwise>
       <xsl:value-of select="normalize-space($text)"/>
     </xsl:otherwise>
   </xsl:choose>            
 </xsl:template>


<!-- We need to replace all instances of double quotes (") in the
     title and description with the escape sequence (\") so that
     JavaScript does not croak, since we are double-quoting these
     strings before passing them into the JavaScript images array.

     Also (see the replace-string template above), we need to 
     cut out all newlines from the titles and descriptions
     by using normalize-space() because Safari doesn't like
     newlines in its JavaScript strings.

     TODO: What I really should do is a search-and-replace of 
           newline characters for 'quoted' newline characters
	   so the following input:

	   "hello world

	   two newlines"

	   would get transformed into the following output:

	   "hello world\n\ntwo newlines"

	   Right now, I just cut out newlines completely.
 -->
<xsl:template match="title">
  <xsl:call-template name="replace-string">
    <xsl:with-param name="text" 
		    select="."/>
    <xsl:with-param name="from" select="'&quot;'" />
    <xsl:with-param name="to" select="'\&quot;'" />
  </xsl:call-template>
</xsl:template>

<xsl:template match="description">
  <xsl:call-template name="replace-string">
    <xsl:with-param name="text" 
		    select="."/>
    <xsl:with-param name="from" select="'&quot;'"/>
    <xsl:with-param name="to" select="'\&quot;'"/>
  </xsl:call-template>
</xsl:template>

<xsl:template match="text()">
  <xsl:value-of select="normalize-space(.)"/>
</xsl:template>

</xsl:transform>
