<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */

/**
* Wrapper for the XML Gauge SWF movie.
*
* This package makes it easy to build configuration files for the XML/SWF Gauge available
* at http://www.maani.us/gauge/.
*
* PHP version 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt.  If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category   XML
* @package    XML_SWFGauge
* @author     Jack Herrington <jherr@pobox.com>
* @copyright  2006 Jack Herrington
* @license    http://www.php.net/license/3_0.txt  PHP License 3.0
* @version    CVS: $Id:$
* @link       http://pear.php.net/package/XML_SWFGauge
*/
class XML_SWFGauge
{
    
/**
      * The DOM object
      * @var XMLDocument
      * @access private
      */
    
private $dom;

    
/**
      * A stack of child objects where new guage items will be placed
      * @var Array
      * @access private
      */
    
private $childStack = Array();

    
/**
      * The link tag if one has been created
      * @var XMLElement
      * @access private
      */
    
private $linkTag = null;

    
/**
      * The sound tag if one has been created
      * @var XMLElement
      * @access private
      */
    
private $soundTag = null;

    
/**
      * Constructor
      */
    
public function __construct()
    {
        
$this->dom = new DomDocument();
        
$this->dom->formatOutput = true;
        
$elChild = $this->dom->createElement( 'gauge' );
        
$this->dom->appendChild( $elChild );
        
        
$this->childStack []= $elChild;
    }
    
    
/**
      * Draws a line.
      *
      * @param int $x1 The first x coordinate  
      * @param int $y1 The first y coordinate  
      * @param int $x2 The second x coordinate  
      * @param int $y2 The second y coordinate  
      */
    
public function line( $x1, $y1, $x2, $y2 )
    {
        
$elChild = $this->dom->createElement( 'line' );
        
$elChild->setAttribute( 'x1', $x1 );
        
$elChild->setAttribute( 'y1', $y1 );
        
$elChild->setAttribute( 'x2', $x2 );
        
$elChild->setAttribute( 'y2', $y2 );
        
$this->add_child( $elChild );
    }
    
    
/**
      * Sets the update rate of the gauge.
      *
      * @param string $url The update URL  
      * @param int $delay The delay between refreshes  
      * @param string $delay_type The type of delay  
      */
    
public function update( $url, $delay, $delay_type = null )
    {
        
$elChild = $this->dom->createElement( 'update' );
        
$elChild->setAttribute( 'url', $url );
        
$elChild->setAttribute( 'delay', $delay );
        if (
$delay_type != null ) $elChild->setAttribute( 'delay_type', $delay_type );
        
        
$this->add_child( $elChild );
    }
    
    
/**
      * Draws a circle.
      *
      * @param int $x The X coordinate  
      * @param int $y The Y coordinate  
      * @param int $radius The radius  
      * @param int $start The start degree  
      * @param int $end The end degree  
      * @param string $fill_color The fill color
      * @param int $fill_alpha The fill alpha  
      * @param string $line_color The line color
      * @param int $line_alpha The line alpha  
      * @param int $line_thickness The line thickness  
      */
    
public function circle( $x, $y, $radius,
        
$start = null, $end = null,
        
$fill_color = null, $fill_alpha = null,
        
$line_color = null, $line_alpha = null, $line_thickness = null )
    {
        
$elChild = $this->dom->createElement( 'circle' );
        
$elChild->setAttribute( 'x', $x );
        
$elChild->setAttribute( 'y', $y );
        
$elChild->setAttribute( 'radius', $radius );
        if (
$start != null ) $elChild->setAttribute( 'start', $start );
        if (
$end != null ) $elChild->setAttribute( 'end', $end );
        if (
$fill_color != null ) $elChild->setAttribute( 'fill_color', $fill_color );
        if (
$fill_alpha != null ) $elChild->setAttribute( 'fill_alpha', $fill_alpha );
        if (
$line_color != null ) $elChild->setAttribute( 'line_color', $line_color );
        if (
$line_alpha != null ) $elChild->setAttribute( 'line_alpha', $line_alpha );
        if (
$line_thickness != null ) $elChild->setAttribute( 'line_thickness', $line_thickness );

        
$this->add_child( $elChild );
    }
    
    
/**
      * Draws an image.
      *
      * @param url $url The URL of the image  
      * @param int $x The X coordinate  
      * @param int $y The Y coordinate  
      * @param int $width The width  
      * @param int $height The height  
      * @param int $rotation The rotation  
      * @param int $alpha The alpha  
      */
    
public function image( $url, $x, $y, $width, $height,
        
$rotation = null, $alpha = null )
    {
        
$elChild = $this->dom->createElement( 'image' );
        
$elChild->setAttribute( 'url', $url );
        
$elChild->setAttribute( 'x', $x );
        
$elChild->setAttribute( 'y', $y );
        
$elChild->setAttribute( 'width', $width );
        
$elChild->setAttribute( 'height', $height );
        if (
$rotation != null ) $elChild->setAttribute( 'rotation', $rotation );
        if (
$alpha != null ) $elChild->setAttribute( 'alpha', $alpha );

        
$this->add_child( $elChild );
    }
    
    
/**
      * Draws an polygon.
      *
      * @param Array $points The list of polygon points, where each point as a hash of 'x' any 'y'  
      * @param string $fill_color The fill color
      * @param int $fill_alpha The fill alpha  
      * @param string $line_color The line color
      * @param int $line_alpha The line alpha  
      * @param int $line_thickness The line thickness  
      */
    
public function polygon( $points, $fill_color = null, $fill_alpha = null, $line_color = null,
         
$line_alpha = null, $line_thickness = null )
    {
        
$elChild = $this->dom->createElement( 'polygon' );
        if (
$fill_color != null ) $elChild->setAttribute( 'fill_color', $fill_color );
        if (
$fill_alpha != null ) $elChild->setAttribute( 'fill_alpha', $fill_alpha );
        if (
$line_color != null ) $elChild->setAttribute( 'line_color', $line_color );
        if (
$line_alpha != null ) $elChild->setAttribute( 'line_alpha', $line_alpha );
        if (
$line_thickness != null ) $elChild->setAttribute( 'line_thickness', $line_thickness );

        foreach(
$points as $point )
        {
            
$elPoint = $this->dom->createElement( 'point' );
            
$elPoint->setAttribute( 'x', $point['x'] );
            
$elPoint->setAttribute( 'y', $point['y'] );
            
$elChild->appendChild( $elPoint );
        }

        
$this->add_child( $elChild );
    }
    
    
/**
      * Draws an rectangle.
      *
      * @param int $x The starting x coordinate  
      * @param int $y The starting y coordinate  
      * @param int $width The width  
      * @param int $height The height  
      * @param int $rotation The rotation  
      * @param string $fill_color The fill color
      * @param int $fill_alpha The fill alpha  
      * @param string $line_color The line color
      * @param int $line_alpha The line alpha  
      * @param int $line_thickness The line thickness  
      */
    
public function rect( $x, $y, $width, $height,
        
$rotation = null,
        
$fill_color = null, $fill_alpha = null,
        
$line_color = null, $line_alpha = null, $line_thickness = null )
    {
        
$elChild = $this->dom->createElement( 'rect' );
        
$elChild->setAttribute( 'x', $x );
        
$elChild->setAttribute( 'y', $y );
        
$elChild->setAttribute( 'width', $width );
        
$elChild->setAttribute( 'height', $height );
        if (
$rotation != null ) $elChild->setAttribute( 'rotation', $rotation );
        if (
$fill_color != null ) $elChild->setAttribute( 'fill_color', $fill_color );
        if (
$fill_alpha != null ) $elChild->setAttribute( 'fill_alpha', $fill_alpha );
        if (
$line_color != null ) $elChild->setAttribute( 'line_color', $line_color );
        if (
$line_alpha != null ) $elChild->setAttribute( 'line_alpha', $line_alpha );
        if (
$line_thickness != null ) $elChild->setAttribute( 'line_thickness', $line_thickness );

        
$this->add_child( $elChild );
    }
    
    
/**
      * Draws a string of text.
      *
      * @param int $x The starting x coordinate  
      * @param int $y The starting y coordinate  
      * @param string $text The text  
      * @param int $width The width  
      * @param int $height The height  
      * @param int $rotation The rotation  
      * @param string $font The font
      * @param string $bold True if the text should be rendered as bold  
      * @param string $size The font size
      * @param string $align The alignment of the string  
      * @param string $color The color  
      * @param int $alpha The alpha  
      */
    
public function text( $x, $y, $text, $width = null, $height = null,
        
$rotation = null, $font = null, $bold = null,
        
$size = null, $align = null, $color = null, $alpha = null )
    {
        
$elChild = $this->dom->createElement( 'text' );
        
$elChild->appendChild( $this->dom->createTextNode( $text ) );
        
$elChild->setAttribute( 'x', $x );
        
$elChild->setAttribute( 'y', $y );
        if (
$rotation != null ) $elChild->setAttribute( 'rotation', $rotation );
        if (
$width != null ) $elChild->setAttribute( 'width', $width );
        if (
$height != null ) $elChild->setAttribute( 'height', $height );
        if (
$font != null ) $elChild->setAttribute( 'font', $font );
        if (
$bold != null ) $elChild->setAttribute( 'bold', $bold );
        if (
$size != null ) $elChild->setAttribute( 'size', $size );
        if (
$align != null ) $elChild->setAttribute( 'align', $align );
        if (
$color != null ) $elChild->setAttribute( 'color', $color );
        if (
$alpha != null ) $elChild->setAttribute( 'alpha', $alpha );

        
$this->add_child( $elChild );
    }
    
    
/**
      * Starts a move operation.
      *
      * @param int $start_x_offset The starting x offset  
      * @param int $start_y_offset The starting y offset  
      * @param int $end_x_offset The ending x offset  
      * @param int $end_y_offset The ending y offset  
      * @param int $step The step size  
      * @param int $shake_frequency The shake frequency  
      * @param int $shake_span The shake span
      * @param int $shake_snap The shake snap
      * @param int $shadow_alpha The shadow alpha
      * @param int $shadow_x_offset The shadow x offset
      * @param int $shadow_y_offset The shadow y offset
      */
    
public function start_move( $start_x_offset = null,
        
$start_y_offset = null, $end_x_offset = null, $end_y_offset = null,
        
$step = null, $shake_frequency = null, $shake_span = null, $shake_snap = null,
        
$shadow_alpha = null, $shadow_x_offset = null, $shadow_y_offset = null )
    {
        
$elChild = $this->dom->createElement( 'move' );
        if (
$start_x_offset != null ) $elChild->setAttribute( 'start_x_offset', $start_x_offset );
        if (
$start_y_offset != null ) $elChild->setAttribute( 'start_y_offset', $start_y_offset );
        if (
$end_x_offset != null ) $elChild->setAttribute( 'end_x_offset', $end_x_offset );
        if (
$end_y_offset != null ) $elChild->setAttribute( 'end_y_offset', $end_y_offset );
        if (
$step != null ) $elChild->setAttribute( 'step', $step );
        if (
$shake_frequency != null ) $elChild->setAttribute( 'shake_frequency', $shake_frequency );
        if (
$shake_span != null ) $elChild->setAttribute( 'shake_span', $shake_span );
        if (
$shake_snap != null ) $elChild->setAttribute( 'shake_snap', $shake_snap );
        if (
$shadow_alpha != null ) $elChild->setAttribute( 'shadow_alpha', $shadow_alpha );
        if (
$shadow_x_offset != null ) $elChild->setAttribute( 'shadow_x_offset', $shadow_x_offset );
        if (
$shadow_y_offset != null ) $elChild->setAttribute( 'shadow_y_offset', $shadow_y_offset );
        
$this->add_child( $elChild );
        
        
$this->push_child( $elChild );
    }
    
    
/**
      * Ends the current move operation.
      */
    
public function end_move()
    {
        
$this->pop_child();
    }
    
    
/**
      * Starts a rotation operation.
      *
      * @param int $x The starting x offset  
      * @param int $y The starting y offset  
      * @param int $start The starting degree  
      * @param int $span The degree span  
      * @param int $step The step size  
      * @param int $shake_frequency The shake frequency  
      * @param int $shake_span The shake span
      * @param int $shake_snap The shake snap
      * @param int $shadow_alpha The shadow alpha
      * @param int $shadow_x_offset The shadow x offset
      * @param int $shadow_y_offset The shadow y offset
      */
    
public function start_rotate( $x, $y, $start, $span, $step,
        
$shake_frequency = null, $shake_span = null, $shake_snap = null,
        
$shadow_alpha = null, $shadow_x_offset = null, $shadow_y_offset = null )
    {
        
$elChild = $this->dom->createElement( 'rotate' );
        
$elChild->setAttribute( 'x', $x );
        
$elChild->setAttribute( 'y', $y );
        
$elChild->setAttribute( 'start', $start );
        
$elChild->setAttribute( 'span', $span );
        
$elChild->setAttribute( 'step', $step );
        if (
$shake_frequency != null ) $elChild->setAttribute( 'shake_frequency', $shake_frequency );
        if (
$shake_span != null ) $elChild->setAttribute( 'shake_span', $shake_span );
        if (
$shake_snap != null ) $elChild->setAttribute( 'shake_snap', $shake_snap );
        if (
$shadow_alpha != null ) $elChild->setAttribute( 'shadow_alpha', $shadow_alpha );
        if (
$shadow_x_offset != null ) $elChild->setAttribute( 'shadow_x_offset', $shadow_x_offset );
        if (
$shadow_y_offset != null ) $elChild->setAttribute( 'shadow_y_offset', $shadow_y_offset );
        
$this->add_child( $elChild );
        
        
$this->push_child( $elChild );
    }
    
    
/**
      * Ends the current rotate operation.
      */
    
public function end_rotate()
    {
        
$this->pop_child();
    }
    
    
/**
      * Starts a scaling operation.
      *
      * @param int $x The starting x offset  
      * @param int $y The starting y offset  
      * @param int $start_scale The starting scaling  
      * @param int $end_scale The ending scaling  
      * @param int $step The step size  
      * @param int $direction The direction of the scaling  
      * @param int $shake_frequency The shake frequency  
      * @param int $shake_span The shake span
      * @param int $shake_snap The shake snap
      * @param int $shadow_alpha The shadow alpha
      * @param int $shadow_x_offset The shadow x offset
      * @param int $shadow_y_offset The shadow y offset
      */
    
public function start_scale( $x, $y, $start_scale, $end_scale, $step, $direction,
        
$shake_frequency = null, $shake_span = null, $shake_snap = null,
        
$shadow_alpha = null, $shadow_x_offset = null, $shadow_y_offset = null )
    {
        
$elChild = $this->dom->createElement( 'scale' );
        
$elChild->setAttribute( 'x', $x );
        
$elChild->setAttribute( 'y', $y );
        
$elChild->setAttribute( 'start_scale', $start_scale );
        
$elChild->setAttribute( 'end_scale', $end_scale );
        
$elChild->setAttribute( 'step', $step );
        
$elChild->setAttribute( 'direction', $direction );
        if (
$shake_frequency != null ) $elChild->setAttribute( 'shake_frequency', $shake_frequency );
        if (
$shake_span != null ) $elChild->setAttribute( 'shake_span', $shake_span );
        if (
$shake_snap != null ) $elChild->setAttribute( 'shake_snap', $shake_snap );
        if (
$shadow_alpha != null ) $elChild->setAttribute( 'shadow_alpha', $shadow_alpha );
        if (
$shadow_x_offset != null ) $elChild->setAttribute( 'shadow_x_offset', $shadow_x_offset );
        if (
$shadow_y_offset != null ) $elChild->setAttribute( 'shadow_y_offset', $shadow_y_offset );
        
$this->add_child( $elChild );
        
        
$this->push_child( $elChild );
    }
    
    
/**
      * Ends the current scale operation.
      */
    
public function end_scale()
    {
        
$this->pop_child();
    }

    
/**
      * Creates a link area.
      *
      * @param int $x The starting x offset  
      * @param int $y The starting y offset  
      * @param int $width The width  
      * @param int $height The height
      * @param string $url The url
      * @param string $target The target
      */
    
public function link( $x, $y, $width, $height, $url, $target = null )
    {
        
$elChild = $this->dom->createElement( 'area' );
        
$elChild->setAttribute( 'x', $x );
        
$elChild->setAttribute( 'y', $y );
        
$elChild->setAttribute( 'width', $width );
        
$elChild->setAttribute( 'height', $height );
        
$elChild->setAttribute( 'url', $url );
        if (
$target != null ) $elChild->setAttribute( 'target', $target );

        if (
$this->linkTag == null ) {
            
$this->linkTag = $this->dom->createElement( 'link' );
            
$this->add_child( $this->linkTag );
        }
        
        
$this->linkTag->appendChild( $elChild );
    }

    
/**
      * Adds a sound.
      *
      * @param string $url The url
      * @param int $delay The delay
      */
    
public function sound( $url, $delay = null )
    {
        
$elChild = $this->dom->createElement( 'clip' );
        
$elChild->setAttribute( 'url', $url );
        if (
$delay != null ) $elChild->setAttribute( 'delay', $delay );

        if (
$this->soundTag == null ) {
            
$this->soundTag = $this->dom->createElement( 'sound' );
            
$this->add_child( $this->soundTag );
        }
        
        
$this->soundTag->appendChild( $elChild );
    }

    
/**
      * Adds a child tag.
      *
      * @param XMLElement $child The child tag
      * @access private
      */
    
private function add_child( $child )
    {
        
end($this->childStack)->appendChild( $child );
    }

    
/**
      * Pushes a child tag onto the child stack and makes it the
      * new current tag.
      *
      * @param XMLElement $child The child tag
      * @access private
      */
    
private function push_child( $child )
    {
        
$this->childStack []= $child;
    }
    
    
/**
      * Pops the current tag.
      * @access private
      */
    
private function pop_child()
    {
        
array_pop( $this->childStack );
    }
    
    
/**
      * Renders the guage as XML.
      */
    
public function render()
    {
        
header( 'content-type: text/xml' );
        return
$this->dom->saveXML();
    }
    
    
/**
      * Places the object tag for the flash movie.
      *
      * @param string $datasource The datasource URL
      * @param int $width The width
      * @param int $height The height
      */
    
public static function place( $datasource, $movie = 'gauge.swf', $width = 400, $height = 250 )
    {
        
$html = '';
        
$html .= '<OBJECT classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" ';
        
$html .= 'codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0"  ';
        
$html .= 'WIDTH='.$width.'"  ';
        
$html .= 'HEIGHT="'.$height.'">';
        
$html .= '<PARAM NAME=movie VALUE="'.$movie.'?xml_source='.$datasource.'">';
        
$html .= '<PARAM NAME=quality VALUE=high>';
        
$html .= '<EMBED src="'.$movie.'?xml_source='.$datasource.'" ';
        
$html .= 'quality=high ';
        
$html .= 'WIDTH="'.$width.'" ';
        
$html .= 'HEIGHT="'.$height.'" ';
        
$html .= 'TYPE="application/x-shockwave-flash" ';
        
$html .= 'PLUGINSPAGE="http://www.macromedia.com/go/getflashplayer">';
        
$html .= '</EMBED>';
        
$html .= '</OBJECT>';
        return
$html;
    }
}

/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* c-hanging-comment-ender-p: nil
* End:
*/
?>