"""
package = "ZSparklines"
author = "Joe Gregorio (joe@bitworking.org), eric casteleijn (eric@infrae.com)"
copyright = "Copyright 2005, Joe Gregorio, 2006 Infrae"
contributors = []
version = "0.1"
license = "MIT"
history = 
ZSparklines is basically Joe Gregorio's spark cgi script (1.0.0), where the
cgi layer was replaced with a Zope layer, so it can be used as a zope
product. """

from Products.Five import BrowserView
from PIL import Image, ImageDraw
import StringIO

class Sparkline(BrowserView):
    """A literal copy of Joe Gregorio's excellent spark.cgi rewrapped as a 
    Five view for generating sparklines. Requires the Python Imaging Library 
    """
    
    spark_type = ''
    
    def __call__(self):
        context = self.context
        kw = context.getSparklineLayout(self.spark_type)
        return self._plot(context.getSparklineData(), **kw)
        
class SparklineDiscrete(Sparkline):
    """A discrete sparkline graph
    """
    spark_type = 'discrete'

    def _plot(
        self, results, height=14, upper=50, below_color='gray', 
        above_color='red', dmin=0, dmax=100):
        """The source data is a list of values between
        0 and 100 (or 'limits' if given). Values greater than 95 
        (or 'upper' if given) are displayed in red, otherwise 
        they are displayed in green"""
        im = Image.new("RGB", (len(results)*2-1, height), 'white') 
        draw = ImageDraw.Draw(im)
        for (r, i) in zip(results, range(0, len(results)*2, 2)):
            color = (r >= upper) and above_color or below_color
            draw.line((
                i,
                im.size[1]-(r - dmin)/(float(dmax - dmin + 1)/(height-4))-4,
                i, 
                (im.size[1]-(r-dmin)/(float(dmax - dmin + 1)/(height-4)))), 
                fill=color)
        del draw                                                      
        f = StringIO.StringIO()
        im.save(f, "PNG")
        return f.getvalue()

class SparklineSmooth(Sparkline):
    """A smooth sparkline graph
    """
    
    spark_type = 'smooth'
    
    def _plot(
        self, results, step=2, height=20, dmin=0, dmax=100, 
        min_color='#0000FF', max_color='#00FF00', last_color='#FF0000', 
        has_min=False, has_max=False, has_last=False):
        im = Image.new("RGB", ((len(results)-1)*step+4, height), 'white')
        draw = ImageDraw.Draw(im)
        coords = zip(
            range(1,len(results)*step+1, step), 
            [height - 3  - (y-dmin)/(
                float(dmax - dmin +1)/(height-4)) for y in results])
        draw.line(coords, fill="#888888")
        if has_min:
            min_pt = coords[results.index(min(results))]
            draw.rectangle([
                min_pt[0]-1, 
                min_pt[1]-1, 
                min_pt[0]+1, 
                min_pt[1]+1], 
                fill=min_color)
        if has_max:
            max_pt = coords[results.index(max(results))]
            draw.rectangle([
                max_pt[0]-1, 
                max_pt[1]-1, 
                max_pt[0]+1, 
                max_pt[1]+1], 
                fill=max_color)
        if has_last:
            end = coords[-1]
            draw.rectangle([
                end[0]-1, 
                end[1]-1, 
                end[0]+1, 
                end[1]+1], 
                fill=last_color)
        del draw 
        f = StringIO.StringIO()
        im.save(f, "PNG")
        return f.getvalue()
