<?php
/**
 * File containing the ezcGraphFlashDriver class
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 * @package Graph
 * @version //autogentag//
 * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
 */
/**
 * Driver to create Flash4 (SWF) files as graph output. The options of this
 * class are defined in The options of this class are defined in the option
 * class {@link ezcGraphFlashDriverOptions} extending the basic
 * {@link ezcGraphDriverOptions}.
 *
 * <code>
 *   $graph = new ezcGraphPieChart();
 *   $graph->title = 'Access statistics';
 *   $graph->legend = false;
 *   
 *   $graph->driver = new ezcGraphFlashDriver();
 *   $graph->options->font = 'tutorial_font.fdb';
 *   
 *   $graph->driver->options->compression = 7;
 *   
 *   $graph->data['Access statistics'] = new ezcGraphArrayDataSet( array(
 *       'Mozilla' => 19113,
 *       'Explorer' => 10917,
 *       'Opera' => 1464,
 *       'Safari' => 652,
 *       'Konqueror' => 474,
 *   ) );
 *   
 *   $graph->render( 400, 200, 'tutorial_driver_flash.swf' );
 * </code>
 *
 *
 * @version //autogentag//
 * @package Graph
 * @mainclass
 */
class ezcGraphFlashDriver extends ezcGraphDriver
{
    /**
     * Flash movie
     * 
     * @var SWFMovie
     */
    protected $movie;

    /**
     * Unique element id
     * 
     * @var int
     */
    protected $id = 1;

    /**
     * Array with strings to draw later
     * 
     * @var array
     */
    protected $strings = array();

    /**
     * Constructor
     * 
     * @param array $options Default option array
     * @return void
     * @ignore
     */
    public function __construct( array $options = array() )
    {
        ezcBase::checkDependency( 'Graph', ezcBase::DEP_PHP_EXTENSION, 'ming' );
        $this->options = new ezcGraphFlashDriverOptions( $options );
    }

    /**
     * Returns unique movie object as a parent canvas for all swf objects.
     * 
     * @return SWFMovie
     */
    public function getDocument()
    {
        if ( $this->movie === null )
        {
            ming_setscale( 1.0 );
            $this->movie = new SWFMovie();
            $this->movie->setDimension( $this->modifyCoordinate( $this->options->width ), $this->modifyCoordinate( $this->options->height ) );
            $this->movie->setRate( 1 );
            $this->movie->setBackground( 255, 255, 255 );
        }

        return $this->movie;
    }

    /**
     * Set the fill and line properties for a SWWFShape according to the 
     * given parameters.
     * 
     * @param SWFShape $shape
     * @param ezcGraphColor $color 
     * @param mixed $thickness 
     * @param mixed $filled 
     * @return void
     */
    protected function setShapeColor( SWFShape $shape, ezcGraphColor $color, $thickness, $filled )
    {
        if ( $filled )
        {
            switch ( true )
            {
                case ( $color instanceof ezcGraphLinearGradient ):
                    $gradient = new SWFGradient();
                    $gradient->addEntry( 
                        0, 
                        $color->startColor->red, 
                        $color->startColor->green, 
                        $color->startColor->blue, 
                        255 - $color->startColor->alpha 
                    );
                    $gradient->addEntry( 
                        1, 
                        $color->endColor->red, 
                        $color->endColor->green, 
                        $color->endColor->blue, 
                        255 - $color->endColor->alpha 
                    );

                    $fill = $shape->addFill( $gradient, SWFFILL_LINEAR_GRADIENT );

                    // Calculate desired length of gradient
                    $length = sqrt( 
                        pow( $color->endPoint->x - $color->startPoint->x, 2 ) + 
                        pow( $color->endPoint->y - $color->startPoint->y, 2 ) 
                    ); 

                    $fill->scaleTo( $this->modifyCoordinate( $length ) / 32768 , $this->modifyCoordinate( $length ) / 32768 );
                    $fill->rotateTo( 
                        rad2deg( asin( 
                            ( $color->endPoint->x - $color->startPoint->x ) / $length
                        ) + 180 )
                    );
                    $fill->moveTo( 
                        $this->modifyCoordinate( 
                            ( $color->startPoint->x + $color->endPoint->x ) / 2 
                        ), 
                        $this->modifyCoordinate( 
                            ( $color->startPoint->y + $color->endPoint->y ) / 2 
                        )
                    );

                    $shape->setLeftFill( $fill );
                    break;
                case ( $color instanceof ezcGraphRadialGradient ):
                    $gradient = new SWFGradient();
                    $gradient->addEntry( 
                        0, 
                        $color->startColor->red, 
                        $color->startColor->green, 
                        $color->startColor->blue, 
                        255 - $color->startColor->alpha 
                    );
                    $gradient->addEntry( 
                        1, 
                        $color->endColor->red, 
                        $color->endColor->green, 
                        $color->endColor->blue, 
                        255 - $color->endColor->alpha 
                    );

                    $fill = $shape->addFill( $gradient, SWFFILL_RADIAL_GRADIENT );

                    $fill->scaleTo( $this->modifyCoordinate( $color->width ) / 32768, $this->modifyCoordinate( $color->height ) / 32768 );
                    $fill->moveTo( $this->modifyCoordinate( $color->center->x ), $this->modifyCoordinate( $color->center->y ) );

                    $shape->setLeftFill( $fill );
                    break;
                default:
                    $fill = $shape->addFill( $color->red, $color->green, $color->blue, 255 - $color->alpha );
                    $shape->setLeftFill( $fill );
                    break;
            }
        }
        else
        {
            $shape->setLine( $this->modifyCoordinate( $thickness ), $color->red, $color->green, $color->blue, 255 - $color->alpha );
        }
    }

    /**
     * Modifies a coordinate value, as flash usally uses twips instead of 
     * pixels for a higher solution, as it only accepts integer values.
     * 
     * @param float $pointValue 
     * @return float
     */
    protected function modifyCoordinate( $pointValue )
    {
        return $pointValue * 10;
    }

    /**
     * Demodifies a coordinate value, as flash usally uses twips instead of 
     * pixels for a higher solution, as it only accepts integer values.
     * 
     * @param float $pointValue 
     * @return float
     */
    protected function deModifyCoordinate( $pointValue )
    {
        return $pointValue / 10;
    }

    /**
     * Draws a single polygon. 
     * 
     * @param array $points Point array
     * @param ezcGraphColor $color Polygon color
     * @param mixed $filled Filled
     * @param float $thickness Line thickness
     * @return void
     */
    public function drawPolygon( array $points, ezcGraphColor $color, $filled = true, $thickness = 1. )
    {
        $movie = $this->getDocument();

        if ( !$filled )
        {
            // The middle of the border is on the outline of a polygon in ming, 
            // fix that:
            try
            {
                $points = $this->reducePolygonSize( $points, $thickness / 2 );
            }
            catch ( ezcGraphReducementFailedException $e )
            {
                return false;
            }
        }

        $shape = new SWFShape();

        $this->setShapeColor( $shape, $color, $thickness, $filled );

        $lastPoint = end( $points );
        $shape->movePenTo( $this->modifyCoordinate( $lastPoint->x ), $this->modifyCoordinate( $lastPoint->y ) );

        foreach ( $points as $point )
        {
            $shape->drawLineTo( $this->modifyCoordinate( $point->x ), $this->modifyCoordinate( $point->y ) );
        }

        $object = $movie->add( $shape );
        $object->setName( $id = 'ezcGraphPolygon_' . $this->id++ );

        return $id;
    }
    
    /**
     * Draws a line 
     * 
     * @param ezcGraphCoordinate $start Start point
     * @param ezcGraphCoordinate $end End point
     * @param ezcGraphColor $color Line color
     * @param float $thickness Line thickness
     * @return void
     */
    public function drawLine( ezcGraphCoordinate $start, ezcGraphCoordinate $end, ezcGraphColor $color, $thickness = 1. )
    {
        $movie = $this->getDocument();

        $shape = new SWFShape();

        $this->setShapeColor( $shape, $color, $thickness, false );

        $shape->movePenTo( $this->modifyCoordinate( $start->x ), $this->modifyCoordinate( $start->y ) );
        $shape->drawLineTo( $this->modifyCoordinate( $end->x ), $this->modifyCoordinate( $end->y ) );

        $object = $movie->add( $shape );
        $object->setName( $id = 'ezcGraphLine_' . $this->id++ );

        return $id;
    }

    /**
     * Returns boundings of text depending on the available font extension
     * 
     * @param float $size Textsize
     * @param ezcGraphFontOptions $font Font
     * @param string $text Text
     * @return ezcGraphBoundings Boundings of text
     */
    protected function getTextBoundings( $size, ezcGraphFontOptions $font, $text )
    {
        $t = new SWFText();
        $t->setFont( new SWFFont( $font->path ) );
        $t->setHeight( $size );

        $boundings = new ezcGraphBoundings( 0, 0, $t->getWidth( $text ), $size );
        
        return $boundings;
    }
    
    /**
     * Writes text in a box of desired size
     * 
     * @param string $string Text
     * @param ezcGraphCoordinate $position Top left position
     * @param float $width Width of text box
     * @param float $height Height of text box
     * @param int $align Alignement of text
     * @param ezcGraphRotation $rotation
     * @return void
     */
    public function drawTextBox( $string, ezcGraphCoordinate $position, $width, $height, $align, ezcGraphRotation $rotation = null )
    {
        $padding = $this->options->font->padding + ( $this->options->font->border !== false ? $this->options->font->borderWidth : 0 );

        $width = $this->modifyCoordinate( $width - $padding * 2 );
        $height = $this->modifyCoordinate( $height - $padding * 2 );
        $position = new ezcGraphCoordinate(
            $this->modifyCoordinate( $position->x + $padding ),
            $this->modifyCoordinate( $position->y + $padding )
        );

        // Try to get a font size for the text to fit into the box
        $maxSize = $this->modifyCoordinate( min( $height, $this->options->font->maxFontSize ) );
        $minSize = $this->modifyCoordinate( $this->options->font->minFontSize );
        $result = false;
        for ( $size = $maxSize; $size >= $minSize; )
        {
            $result = $this->testFitStringInTextBox( $string, $position, $width, $height, $size );
            if ( is_array( $result ) )
            {
                break;
            }
            $size = $this->deModifyCoordinate( $size );
            $size = $this->modifyCoordinate( floor( ( $newsize = $size * ( $result ) ) >= $size ? $size - 1 : $newsize ) );
        }

        if ( !is_array( $result ) )
        {
            if ( ( $height >= $this->options->font->minFontSize ) &&
                 ( $this->options->autoShortenString ) )
            {
                $result = $this->tryFitShortenedString( $string, $position, $width, $height, $size = $this->modifyCoordinate( $this->options->font->minFontSize ) );
            } 
            else
            {
                throw new ezcGraphFontRenderingException( $string, $this->options->font->minFontSize, $width, $height );
            }
        }


        $this->options->font->minimalUsedFont = $this->deModifyCoordinate( $size );

        $this->strings[] = array(
            'text' => $result,
            'id' => $id = 'ezcGraphTextBox_' . $this->id++,
            'position' => $position,
            'width' => $width,
            'height' => $height,
            'align' => $align,
            'font' => $this->options->font,
            'rotation' => $rotation,
        );

        return $id;
    }
    
    /**
     * Render text depending of font type and available font extensions
     * 
     * @param string $id 
     * @param string $text 
     * @param string $chars 
     * @param int $type 
     * @param string $path 
     * @param ezcGraphColor $color 
     * @param ezcGraphCoordinate $position 
     * @param float $size 
     * @param float $rotation 
     * @return void
     */
    protected function renderText( $id, $text, $chars, $type, $path, ezcGraphColor $color, ezcGraphCoordinate $position, $size, $rotation = null )
    {
        $movie = $this->getDocument();

        $tb = new SWFTextField( SWFTEXTFIELD_NOEDIT );
        $tb->setFont( new SWFFont( $path ) );
        $tb->setHeight( $size );
        $tb->setColor( $color->red, $color->green, $color->blue, 255 - $color->alpha );
        $tb->addString( $text );
        $tb->addChars( $chars );

        $object = $movie->add( $tb );
        $object->rotate(
            ( $rotation !== null ? -$rotation->getRotation() : 0 )
        );
        $object->moveTo( 
            $position->x +
                ( $rotation === null ? 0 : $this->modifyCoordinate( $rotation->get( 0, 2 ) ) ),
            $position->y -
                $size * ( 1 + $this->options->lineSpacing ) +
                ( $rotation === null ? 0 : $this->modifyCoordinate( $rotation->get( 1, 2 ) ) )
        );
        $object->setName( $id );
    }

    /**
     * Draw all collected texts
     *
     * The texts are collected and their maximum possible font size is 
     * calculated. This function finally draws the texts on the image, this
     * delayed drawing has two reasons:
     *
     * 1) This way the text strings are always on top of the image, what 
     *    results in better readable texts
     * 2) The maximum possible font size can be calculated for a set of texts
     *    with the same font configuration. Strings belonging to one chart 
     *    element normally have the same font configuration, so that all texts
     *    belonging to one element will have the same font size.
     * 
     * @access protected
     * @return void
     */
    protected function drawAllTexts()
    {
        // Iterate over all strings to collect used chars per font
        $chars = array();
        foreach ( $this->strings as $text )
        {
            $completeString = '';
            foreach ( $text['text'] as $line )
            {
                $completeString .= implode( ' ', $line );
            }

            // Collect chars for each font
            if ( !isset( $chars[$text['font']->path] ) )
            {
                $chars[$text['font']->path] = $completeString;
            }
            else
            {
                $chars[$text['font']->path] .= $completeString;
            }
        }

        foreach ( $this->strings as $text )
        {
            $size = $this->modifyCoordinate( $text['font']->minimalUsedFont );

            $completeHeight = count( $text['text'] ) * $size + ( count( $text['text'] ) - 1 ) * $this->options->lineSpacing;

            // Calculate y offset for vertical alignement
            switch ( true )
            {
                case ( $text['align'] & ezcGraph::BOTTOM ):
                    $yOffset = $text['height'] - $completeHeight;
                    break;
                case ( $text['align'] & ezcGraph::MIDDLE ):
                    $yOffset = ( $text['height'] - $completeHeight ) / 2;
                    break;
                case ( $text['align'] & ezcGraph::TOP ):
                default:
                    $yOffset = 0;
                    break;
            }

            $padding = $text['font']->padding + $text['font']->borderWidth / 2;
            if ( $this->options->font->minimizeBorder === true )
            {
                // Calculate maximum width of text rows
                $width = false;
                foreach ( $text['text'] as $line )
                {
                    $string = implode( ' ', $line );
                    $boundings = $this->getTextBoundings( $size, $text['font'], $string );
                    if ( ( $width === false) || ( $boundings->width > $width ) )
                    {
                        $width = $boundings->width;
                    }
                }

                switch ( true )
                {
                    case ( $text['align'] & ezcGraph::LEFT ):
                        $xOffset = 0;
                        break;
                    case ( $text['align'] & ezcGraph::CENTER ):
                        $xOffset = ( $text['width'] - $width ) / 2;
                        break;
                    case ( $text['align'] & ezcGraph::RIGHT ):
                        $xOffset = $text['width'] - $width;
                        break;
                }

                $borderPolygonArray = array(
                    new ezcGraphCoordinate(
                        $this->deModifyCoordinate( $text['position']->x - $padding + $xOffset ),
                        $this->deModifyCoordinate( $text['position']->y - $padding + $yOffset )
                    ),
                    new ezcGraphCoordinate(
                        $this->deModifyCoordinate( $text['position']->x + $padding * 2 + $xOffset + $width ),
                        $this->deModifyCoordinate( $text['position']->y - $padding + $yOffset )
                    ),
                    new ezcGraphCoordinate(
                        $this->deModifyCoordinate( $text['position']->x + $padding * 2 + $xOffset + $width ),
                        $this->deModifyCoordinate( $text['position']->y + $padding * 2 + $yOffset + $completeHeight )
                    ),
                    new ezcGraphCoordinate(
                        $this->deModifyCoordinate( $text['position']->x - $padding + $xOffset ),
                        $this->deModifyCoordinate( $text['position']->y + $padding * 2 + $yOffset + $completeHeight )
                    ),
                );
            }
            else
            {
                $borderPolygonArray = array(
                    new ezcGraphCoordinate(
                        $this->deModifyCoordinate( $text['position']->x - $padding ),
                        $this->deModifyCoordinate( $text['position']->y - $padding )
                    ),
                    new ezcGraphCoordinate(
                        $this->deModifyCoordinate( $text['position']->x + $padding * 2 + $text['width'] ),
                        $this->deModifyCoordinate( $text['position']->y - $padding )
                    ),
                    new ezcGraphCoordinate(
                        $this->deModifyCoordinate( $text['position']->x + $padding * 2 + $text['width'] ),
                        $this->deModifyCoordinate( $text['position']->y + $padding * 2 + $text['height'] )
                    ),
                    new ezcGraphCoordinate(
                        $this->deModifyCoordinate( $text['position']->x - $padding ),
                        $this->deModifyCoordinate( $text['position']->y + $padding * 2 + $text['height'] )
                    ),
                );
            }

            if ( $text['rotation'] !==  null )
            {
                foreach ( $borderPolygonArray as $nr => $point )
                {
                    $borderPolygonArray[$nr] = $text['rotation']->transformCoordinate( $point );
                }
            }

            if ( $text['font']->background !== false )
            {
                $this->drawPolygon( 
                    $borderPolygonArray, 
                    $text['font']->background,
                    true
                );
            }

            if ( $text['font']->border !== false )
            {
                $this->drawPolygon( 
                    $borderPolygonArray, 
                    $text['font']->border,
                    false,
                    $text['font']->borderWidth
                );
            }

            // Render text with evaluated font size
            $completeString = '';
            foreach ( $text['text'] as $line )
            {
                $string = implode( ' ', $line );
                $completeString .= $string;
                $boundings = $this->getTextBoundings( $size, $text['font'], $string );
                $text['position']->y += $size;

                switch ( true )
                {
                    case ( $text['align'] & ezcGraph::LEFT ):
                        $position = new ezcGraphCoordinate( 
                            $text['position']->x, 
                            $text['position']->y + $yOffset
                        );
                        break;
                    case ( $text['align'] & ezcGraph::RIGHT ):
                        $position = new ezcGraphCoordinate( 
                            $text['position']->x + ( $text['width'] - $boundings->width ), 
                            $text['position']->y + $yOffset
                        );
                        break;
                    case ( $text['align'] & ezcGraph::CENTER ):
                        $position = new ezcGraphCoordinate( 
                            $text['position']->x + ( ( $text['width'] - $boundings->width ) / 2 ), 
                            $text['position']->y + $yOffset
                        );
                        break;
                }

                // Optionally draw text shadow
                if ( $text['font']->textShadow === true )
                {
                    $this->renderText( 
                        $text['id'],
                        $string,
                        $chars[$text['font']->path],
                        $text['font']->type, 
                        $text['font']->path, 
                        $text['font']->textShadowColor,
                        new ezcGraphCoordinate(
                            $position->x + $this->modifyCoordinate( $text['font']->textShadowOffset ),
                            $position->y + $this->modifyCoordinate( $text['font']->textShadowOffset )
                        ),
                        $size,
                        $text['rotation']
                    );
                }
                
                // Finally draw text
                $this->renderText( 
                    $text['id'],
                    $string,
                    $chars[$text['font']->path],
                    $text['font']->type, 
                    $text['font']->path, 
                    $text['font']->color, 
                    $position,
                    $size,
                    $text['rotation']
                );

                $text['position']->y += $size * $this->options->lineSpacing;
            }
        }
    }

    /**
     * Draws a sector of cirlce
     * 
     * @param ezcGraphCoordinate $center Center of circle
     * @param mixed $width Width
     * @param mixed $height Height
     * @param mixed $startAngle Start angle of circle sector
     * @param mixed $endAngle End angle of circle sector
     * @param ezcGraphColor $color Color
     * @param mixed $filled Filled
     * @return void
     */
    public function drawCircleSector( ezcGraphCoordinate $center, $width, $height, $startAngle, $endAngle, ezcGraphColor $color, $filled = true )
    {
        if ( $startAngle > $endAngle )
        {
            $tmp = $startAngle;
            $startAngle = $endAngle;
            $endAngle = $tmp;
        }

        $movie = $this->getDocument();

        $shape = new SWFShape();
        $this->setShapeColor( $shape, $color, 1, $filled );

        if ( !$filled )
        {
            try
            {
                $reduced = $this->reduceEllipseSize( $center, $width, $height, $startAngle, $endAngle, .5 );
            }
            catch ( ezcGraphReducementFailedException $e )
            {
                return false;
            }

            $startAngle = $reduced['startAngle'];
            $endAngle = $reduced['endAngle'];

            $width -= 1;
            $height -= 1;
        }

        $shape->movePenTo( $this->modifyCoordinate( $center->x ), $this->modifyCoordinate( $center->y ) );

        // @TODO: User SWFShape::curveTo
        for(
            $angle = $startAngle;
            $angle <= $endAngle;
            $angle = min( $angle + $this->options->circleResolution, $endAngle ) )
        {
            $shape->drawLineTo( 
                $this->modifyCoordinate( $center->x + cos( deg2rad( $angle ) ) * $width / 2 ), 
                $this->modifyCoordinate( $center->y + sin( deg2rad( $angle ) ) * $height / 2 )
            );

            if ( $angle === $endAngle )
            {
                break;
            }
        }

        $shape->drawLineTo( 
            $this->modifyCoordinate( $center->x ), 
            $this->modifyCoordinate( $center->y ) 
        );

        $object = $movie->add( $shape );
        $object->setName( $id = 'ezcGraphCircleSector_' . $this->id++ );

        return $id;
    }

    /**
     * Draws a circular arc consisting of several minor steps on the bounding 
     * lines.
     * 
     * @param ezcGraphCoordinate $center 
     * @param mixed $width 
     * @param mixed $height 
     * @param mixed $size 
     * @param mixed $startAngle 
     * @param mixed $endAngle 
     * @param ezcGraphColor $color 
     * @param bool $filled 
     * @return string Element id
     */
    protected function simulateCircularArc( ezcGraphCoordinate $center, $width, $height, $size, $startAngle, $endAngle, ezcGraphColor $color, $filled )
    {
        $movie = $this->getDocument();
        $id = 'ezcGraphCircularArc_' . $this->id++;

        for ( 
            $tmpAngle = min( ceil ( $startAngle / 180 ) * 180, $endAngle ); 
            $tmpAngle <= $endAngle; 
            $tmpAngle = min( ceil ( $startAngle / 180 + 1 ) * 180, $endAngle ) )
        {
            $shape = new SWFShape();
            $this->setShapeColor( $shape, $color, 1, $filled );

            $shape->movePenTo( 
                $this->modifyCoordinate( $center->x + cos( deg2rad( $startAngle ) ) * $width / 2 ), 
                $this->modifyCoordinate( $center->y + sin( deg2rad( $startAngle ) ) * $height / 2 )
            );

            // @TODO: Use SWFShape::curveTo
            for(
                $angle = $startAngle;
                $angle <= $tmpAngle;
                $angle = min( $angle + $this->options->circleResolution, $tmpAngle ) )
            {
                $shape->drawLineTo( 
                    $this->modifyCoordinate( $center->x + cos( deg2rad( $angle ) ) * $width / 2 ), 
                    $this->modifyCoordinate( $center->y + sin( deg2rad( $angle ) ) * $height / 2 + $size )
                );

                if ( $angle === $tmpAngle )
                {
                    break;
                }
            }

            for(
                $angle = $tmpAngle;
                $angle >= $startAngle;
                $angle = max( $angle - $this->options->circleResolution, $startAngle ) )
            {
                $shape->drawLineTo( 
                    $this->modifyCoordinate( $center->x + cos( deg2rad( $angle ) ) * $width / 2 ), 
                    $this->modifyCoordinate( $center->y + sin( deg2rad( $angle ) ) * $height / 2 )
                );

                if ( $angle === $startAngle )
                {
                    break;
                }
            }

            $object = $movie->add( $shape );
            $object->setName( $id );

            $startAngle = $tmpAngle;
            if ( $tmpAngle === $endAngle ) 
            {
                break;
            }
        }

        return $id;
    }

    /**
     * Draws a circular arc
     * 
     * @param ezcGraphCoordinate $center Center of ellipse
     * @param integer $width Width of ellipse
     * @param integer $height Height of ellipse
     * @param integer $size Height of border
     * @param float $startAngle Starting angle of circle sector
     * @param float $endAngle Ending angle of circle sector
     * @param ezcGraphColor $color Color of Border
     * @param bool $filled
     * @return void
     */
    public function drawCircularArc( ezcGraphCoordinate $center, $width, $height, $size, $startAngle, $endAngle, ezcGraphColor $color, $filled = true )
    {
        if ( $startAngle > $endAngle )
        {
            $tmp = $startAngle;
            $startAngle = $endAngle;
            $endAngle = $tmp;
        }

        $id = $this->simulateCircularArc( $center, $width, $height, $size, $startAngle, $endAngle, $color, $filled );

        if ( ( $this->options->shadeCircularArc !== false ) &&
             $filled )
        {
            $gradient = new ezcGraphLinearGradient(
                new ezcGraphCoordinate(
                    $center->x - $width,
                    $center->y
                ),
                new ezcGraphCoordinate(
                    $center->x + $width,
                    $center->y
                ),
                ezcGraphColor::fromHex( '#FFFFFF' )->transparent( $this->options->shadeCircularArc * 1.5 ),
                ezcGraphColor::fromHex( '#000000' )->transparent( $this->options->shadeCircularArc * 1.5 )
            );
        
            $this->simulateCircularArc( $center, $width, $height, $size, $startAngle, $endAngle, $gradient, $filled );
        }

        return $id;
    }

    /**
     * Draw circle 
     * 
     * @param ezcGraphCoordinate $center Center of ellipse
     * @param mixed $width Width of ellipse
     * @param mixed $height height of ellipse
     * @param ezcGraphColor $color Color
     * @param mixed $filled Filled
     * @return void
     */
    public function drawCircle( ezcGraphCoordinate $center, $width, $height, ezcGraphColor $color, $filled = true )
    {
        $movie = $this->getDocument();

        $shape = new SWFShape();
        $this->setShapeColor( $shape, $color, 1, $filled );

        // Reduce size
        if ( !$filled )
        {
            $width -= 1;
            $height -= 1;
        }

        $shape->movePenTo( 
            $this->modifyCoordinate( $center->x + $width / 2 ), 
            $this->modifyCoordinate( $center->y )
        );

        // @TODO: User SWFShape::curveTo
        for ( $angle = $this->options->circleResolution; $angle < 360; $angle += $this->options->circleResolution )
        {
            $shape->drawLineTo( 
                $this->modifyCoordinate( $center->x + cos( deg2rad( $angle ) ) * $width / 2 ), 
                $this->modifyCoordinate( $center->y + sin( deg2rad( $angle ) ) * $height / 2 )
            );
        }

        $shape->drawLineTo( 
            $this->modifyCoordinate( $center->x + $width / 2 ), 
            $this->modifyCoordinate( $center->y )
        );

        $object = $movie->add( $shape );
        $object->setName( $id = 'ezcGraphCircle_' . $this->id++ );

        return $id;
    }

    /**
     * Draw an image 
     *
     * The image will be inlined in the SVG document using data URL scheme. For
     * this the mime type and base64 encoded file content will be merged to 
     * URL.
     * 
     * @param mixed $file Image file
     * @param ezcGraphCoordinate $position Top left position
     * @param float $width Width of image in destination image
     * @param float $height Height of image in destination image
     * @return void
     */
    public function drawImage( $file, ezcGraphCoordinate $position, $width, $height )
    {
        $movie = $this->getDocument();

        $imageData = getimagesize( $file );
        if ( ( $imageData[2] !== IMAGETYPE_JPEG ) && ( $imageData[2] !== IMAGETYPE_PNG ) )
        {
            throw new ezcGraphFlashBitmapTypeException( $imageData[2] );
        }

        // Try to create a new SWFBitmap object from provided file
        $bitmap = new SWFBitmap( fopen( $file, 'rb' ) );

        // Add the image to the movie
        $object = $this->movie->add( $bitmap );

        // Image size is calculated on the base of a tick size of 20, so
        // that we need to transform this, to our tick size.
        $factor = $this->modifyCoordinate( 1 ) / 20;
        $object->scale( $factor, $factor );

        // Scale by ratio of requested and original image size
        $object->scale(
            $width / $imageData[0],
            $height / $imageData[1]
        );

        // Move object to the right position
        $object->moveTo( 
            $this->modifyCoordinate( $position->x ),
            $this->modifyCoordinate( $position->y )
        );

        // Create, set and return unique ID
        $object->setName( $id = 'ezcGraphImage_'. $this->id++ );
        return $id;
    }

    /**
     * Return mime type for current image format
     * 
     * @return string
     */
    public function getMimeType()
    {
        return 'application/x-shockwave-flash';
    }

    /**
     * Finally save image
     * 
     * @param string $file Destination filename
     * @return void
     */
    public function render( $file )
    {
        $this->drawAllTexts();
        $movie = $this->getDocument();
        $movie->save( $file, $this->options->compression );
    }

    /**
     * Get resource of rendered result
     *
     * Return the resource of the rendered result. You should not use this
     * method before you called either renderToOutput() or render(), as the
     * image may not be completely rendered until then.
     * 
     * @return SWFMovie
     */
    public function getResource()
    {
        return $this->movie;
    }
}

?>
