<?xml version="1.0"?>
<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:rss="http://purl.org/rss/1.0/"
  xmlns:ml="http://www.messagelabs.com/ns/virusdetails"
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:math="http://exslt.org/math"
  xmlns:data="urn:data"
  extension-element-prefixes="math"
>
  
<xsl:output
  method="xml"
  media-type="image/svg+xml"
  indent="yes"
  />

  <data:colours>
    <data:colour>#3399FF</data:colour>
    <data:colour>#ff00bb</data:colour>
    <data:colour>#bb00ff</data:colour>
    <data:colour>#00ccff</data:colour>
    <data:colour>#99cc00</data:colour>
    <data:colour>#990066</data:colour>
    <data:colour>#ffcc99</data:colour>
    <data:colour>#ffccff</data:colour>
    <data:colour>#993333</data:colour>
    <data:colour>#000066</data:colour>
  </data:colours>
  
  <xsl:param name="max_items" select="10"/>
  <xsl:param name="pi" select="3.14159256"/>
  <xsl:param name="pie_radius" select="100"/>
  <xsl:param name="pie_center_x" select="200"/>
  <xsl:param name="pie_center_y" select="200"/>
  <xsl:param name="wedge_rotation" select="0"/>
  <xsl:param name="legend_start" select="$pie_center_y + $pie_radius + 10"/>

<xsl:template match="/">
  <svg width="400" height="600" viewBox="0 0 400 600"
    xmlns:xlink="http://www.w3.org/1999/xlink"
  >
    <title><xsl:value-of select="/virusgraph/rdf:RDF/rdf:channel/rss:title"/></title>
    <desc><xsl:value-of select="/virusgraph/rdf:RDF/rdf:channel/rss:description"/></desc>
    
    <defs>
      <filter id="blurShadow">
        <desc>Produces a blurred version of object</desc>
        
        <!-- create a blurred version of the source image -->
        <feGaussianBlur in="SourceAlpha" stdDeviation="4" result="blur"/>
      </filter>
      
      <!-- Background Gradient -->
      <radialGradient id="backgroundGradient" gradientUnits="objectBoundingBox"
        cx=".2" cy="0" r="1.2" >
        <stop offset="0%" style="stop-color:white"/>
        <stop offset="60%" style="stop-color:rgb(181, 181, 230)"/>
        <stop offset="80%" style="stop-color:rgb(102, 102, 153)"/>
        <stop offset="100%" style="stop-color:rgb(22, 22, 73)" />
      </radialGradient>
      
      <!-- Define a drop shadow filter -->
      <filter id="closeDropShadow">
        <desc>Produces a 3D effect as if the item was close to the surface</desc>
        
        <!-- create a blurred version of the source image -->
        <feGaussianBlur in="SourceAlpha" stdDeviation="3" result="blur"/>
        
        <!-- offset the image from its original position -->
        <feOffset in="blur" dx="4" dy="4" result="offsetBlur"/>
        
        <!-- merge the original image and the blurred/offset image together  --> 
        <feMerge>
          <feMergeNode in="offsetBlur"/>
          <feMergeNode in="SourceGraphic"/>
        </feMerge>
      </filter>
      
      <!-- Background Gradient -->
      <radialGradient id="backgroundGradient" gradientUnits="objectBoundingBox"
        cx="0" cy="0" r="1.2" >
        <stop offset="0%" style="stop-color:white"/>
        <stop offset="60%" style="stop-color:rgb(181, 181, 230)"/>
        <stop offset="80%" style="stop-color:rgb(102, 102, 153)"/>
        <stop offset="100%" style="stop-color:rgb(22, 22, 73)" />
      </radialGradient>
      
      <xsl:for-each select="/virusgraph/rdf:RDF/rdf:item">
        <g id="text-{position()}">
          <xsl:call-template name="datapoint">
            <xsl:with-param name="x" select="200"/>
            <xsl:with-param name="y" select="(position() * 20) + 300"/>
            <xsl:with-param name="item_id" select="position()"/>
            <xsl:with-param name="text1" select="rss:title"/>
            <xsl:with-param name="text2" select="ml:date-first-captured"/>
            <xsl:with-param name="text3" select="ml:first-stopped-from"/>
            <xsl:with-param name="text4" select="ml:total-stopped"/>
          </xsl:call-template>
        </g>
      </xsl:for-each>

    </defs>
    
    <rect width="100%" height="100%" style="fill:url(#backgroundGradient)"/>
    
    <text x="5" y="25" style="font-size:24">
      <xsl:value-of select="/virusgraph/rdf:RDF/rdf:channel/rss:title"/>
    </text>
    <text x="5" y="45" style="font-size:18">
      <xsl:value-of select="/virusgraph/rdf:RDF/rdf:channel/rss:description"/>
    </text>
    
    <g transform="translate({$pie_center_x - 50}, {$pie_center_y})" style="filter:url(#closeDropShadow)">
      <xsl:apply-templates select="/virusgraph/rdf:RDF"/>
    </g>
      
    <g style="filter:url(#closeDropShadow)">
      <!-- yellow extra text with drop shadow -->
      <xsl:for-each select="/virusgraph/rdf:RDF/rdf:item">
        <use xlink:href="#text-{position()}" transform="translate(-50,0)" opacity="0">
          <set attributeName="opacity" begin="wedge-{position()}.mouseover; mouseover" end="wedge-{position()}.mouseout; mouseout"
            to="0.8"
            />
          <set attributeName="opacity" begin="wedge-{position()}.mouseout; mouseout"
            to="0.0"
            />
        </use>
      </xsl:for-each>
    </g>
    
  </svg>
</xsl:template>
  
  <xsl:template match="rdf:RDF">
    <xsl:call-template name="doitem">
      <xsl:with-param name="wedge_rotation" select="0"/>
      <xsl:with-param name="item_id" select="1"/>
      <xsl:with-param name="legend_item_offset" select="120"/>
    </xsl:call-template>
  </xsl:template>
  
  <xsl:template name="doitem">
    <xsl:param name="ratio" select="rdf:item[$item_id]/ml:total-stopped div sum(rdf:item/ml:total-stopped)"/>
    <xsl:param name="wedge" select="$ratio * 360"/>
    <xsl:param name="radians" select="$wedge * $pi div 180"/>
    <xsl:param name="rx" select="0 - round($pie_radius * math:sin($radians))"/>
    <xsl:param name="ry" select="round($pie_radius * math:cos($radians))"/>
    <xsl:param name="do_arc" select="number($wedge &gt; 180)"/>
    <g id="wedge-{$item_id}">
    <g transform="rotate({$wedge_rotation})">
      <path
        d="M 0,{$pie_radius}
        A {$pie_radius},{$pie_radius} 0 {$do_arc} 1 {$rx},{$ry}
        L 0,0
        z"
        style="stroke: black; stroke-width: 1;">
        <xsl:attribute name="fill"><xsl:call-template name="getcolour">
            <xsl:with-param name="colourid" select="$item_id"/>
          </xsl:call-template>
        </xsl:attribute>
        <set attributeName="stroke" begin="wedge-{$item_id}.mouseover; mouseover" end="wedge-{$item_id}.mouseout; mouseout"
          to="yellow"
          />
      </path>
    </g>
    
    <g transform="translate(-100, {$legend_item_offset})">
      <rect transform="translate(-5, -4)" width="300" height="20" style="fill: white"/>
      <rect width="10" height="10">
        <xsl:attribute name="style">fill:<xsl:call-template name="getcolour">
            <xsl:with-param name="colourid" select="$item_id"/>
          </xsl:call-template>
        </xsl:attribute>
      </rect>
      <text transform="translate(15, 10)"><xsl:value-of select="rdf:item[$item_id]/rss:title"/>
        (<xsl:call-template name="trunc-float">
          <xsl:with-param name="val" select="$ratio * 100"/>
          <xsl:with-param name="digits" select="2"/>
        </xsl:call-template>%)</text>
    </g>
    </g>
    
    <xsl:choose>
      <xsl:when test="$item_id &lt; $max_items">
        <xsl:call-template name="doitem">
          <xsl:with-param name="wedge_rotation" select="$wedge_rotation + $wedge"/>
          <xsl:with-param name="item_id" select="$item_id + 1"/>
          <xsl:with-param name="legend_item_offset" select="$legend_item_offset + 20"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:when test="$item_id &lt; count(rdf:item)">
        <xsl:call-template name="datapoint">
          <xsl:with-param name="x" select="$rx"/>
          <xsl:with-param name="y" select="$ry"/>
          <xsl:with-param name="text1" select="'Other'"/>
          <xsl:with-param name="text2"/>
          <xsl:with-param name="text3"/>
          <xsl:with-param name="text4"/>
          <xsl:with-param name="item_id" select="$item_id"/>
        </xsl:call-template>
        <xsl:call-template name="doother">
          <xsl:with-param name="wedge_rotation" select="$wedge_rotation + $wedge"/>
          <xsl:with-param name="item_id" select="$item_id + 1"/>
          <xsl:with-param name="legend_item_offset" select="$legend_item_offset + 20"/>
        </xsl:call-template>
      </xsl:when>
    </xsl:choose>
    
<!--    <path style="fill:#ff00bb" d="M 120 240 A 80 80 0 0 0 200 160 L
      120,160 Z" /> -->
  </xsl:template>
  
  <xsl:template name="doother">
    <xsl:param name="wedge" select="360 - $wedge_rotation"/>
    <xsl:param name="radians" select="$wedge * $pi div 180"/>
    <xsl:param name="rx" select="0 - round($pie_radius * math:sin($radians))"/>
    <xsl:param name="ry" select="round($pie_radius * math:cos($radians))"/>
    <xsl:param name="do_arc" select="number($wedge &gt; 180)"/>
    <g transform="rotate({$wedge_rotation})">
      <path d="
        M 0,{$pie_radius}
        A {$pie_radius},{$pie_radius} 0 {$do_arc} 1 {$rx},{$ry}
        L 0,0
        z">
        <xsl:attribute name="style">fill:<xsl:call-template name="getcolour">
            <xsl:with-param name="colourid" select="$item_id"/>
          </xsl:call-template>
        </xsl:attribute>
      </path>
    </g>
    
    <g transform="translate(-100, {$legend_item_offset})">
      <rect transform="translate(-5, -4)" width="300" height="20" style="fill: white"/>
      <rect width="10" height="10">
        <xsl:attribute name="style">fill:<xsl:call-template name="getcolour">
            <xsl:with-param name="colourid" select="$item_id"/>
          </xsl:call-template>
        </xsl:attribute>
      </rect>
      <text transform="translate(15, 10)">Other
        (<xsl:call-template name="trunc-float">
          <xsl:with-param name="val" select="($wedge div 360) * 100"/>
          <xsl:with-param name="digits" select="2"/>
        </xsl:call-template>%)</text>
    </g>
  </xsl:template>
   
  <xsl:template name="getcolour">
    <xsl:value-of select="document('')/xsl:stylesheet/data:colours/data:colour[position() = $colourid]"/>
  </xsl:template>
  
  <xsl:template name="datapoint">
    <!-- rest of the template as before in listing 8 -->
    
    <g style="z-index:10" id="v-{$item_id}">
      <rect rx="2" ry="2" x="{$x}" y="{$y}" width="214" height="50" fill="yellow" stroke="black"/>
      <text y="{$y + 10}" x="{$x + 10 + 6}" style="font-family:Arial; font-size:9pt; font-weight:bold">
        <tspan style="font-size:7pt; fill:#333333"><xsl:value-of select="$text1"/></tspan>
      </text>
      <text y="{$y + 21}" x="{$x + 10}" style="font-family:Arial; font-size:8pt; font-weight:bold">
        <tspan style="font-size:7pt; fill:#333333">First Stopped:</tspan>
      </text>
      <text y="{$y + 21}" x="{$x + 100}" style="font-family:Arial; font-size:8pt">
        <tspan style="font-size:7pt; fill:#333333"><xsl:value-of select="$text2"/></tspan>
      </text>
      <text y="{$y + 32}" x="{$x + 10}" style="font-family:Arial; font-size:8pt; font-weight:bold">
        <tspan style="font-size:7pt; fill:#333333">Country First Seen:</tspan>
      </text>
      <text y="{$y + 32}" x="{$x + 100}" style="font-family:Arial; font-size:8pt">
        <tspan style="font-size:7pt; fill:#333333"><xsl:value-of select="$text3"/></tspan>
      </text>
      <text y="{$y + 43}" x="{$x + 10}" style="font-family:Arial; font-size:8pt; font-weight:bold">
        <tspan style="font-size:7pt; fill:#333333">Total Stopped:</tspan>
      </text>
      <text y="{$y + 43}" x="{$x + 100}" style="font-family:Arial; font-size:8pt">
        <tspan style="font-size:7pt; fill:#333333"><xsl:value-of select="$text4"/></tspan>
      </text>
    </g>
  </xsl:template>
  
  <xsl:template name="trunc-float">
    <xsl:choose>
      <xsl:when test="round($val) = $val">
        <xsl:value-of select="$val"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="concat(substring-before($val, '.'), '.', substring(substring-after($val, '.'), 0, $digits + 1))"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>
