<?php
/**
 * File containing the ezcGraphAxisRotatedLabelRenderer 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
 */
/**
 * Can render axis labels rotated, so that more axis labels fit on one axis.
 * Produces best results if the axis space was increased, so that more spcae is
 * available below the axis.
 *
 * <code>
 *   $chart->xAxis->axisLabelRenderer = new ezcGraphAxisRotatedLabelRenderer();
 *
 *   // Define angle manually in degree
 *   $chart->xAxis->axisLabelRenderer->angle = 45;
 *
 *   // Increase axis space
 *   $chart->xAxis->axisSpace = .2;
 * </code>
 *
 * @property float $angle
 *           Angle of labels on axis in degrees.
 *
 * @version //autogentag//
 * @package Graph
 * @mainclass
 */
class ezcGraphAxisRotatedLabelRenderer extends ezcGraphAxisLabelRenderer
{
    /**
     * Store step array for later coordinate modifications
     * 
     * @var array(ezcGraphStep)
     */
    protected $steps;

    /**
     * Store direction for later coordinate modifications
     * 
     * @var ezcGraphVector
     */
    protected $direction;

    /**
     * Store coordinate width modifier for later coordinate modifications
     * 
     * @var float
     */
    protected $widthModifier;
    
    /**
     * Store coordinate offset for later coordinate modifications
     * 
     * @var float
     */
    protected $offset;
    
    /**
     * Constructor
     * 
     * @param array $options Default option array
     * @return void
     * @ignore
     */
    public function __construct( array $options = array() )
    {
        parent::__construct( $options );
        $this->properties['angle']  = null;
        $this->properties['labelOffset'] = true;
    }

    /**
     * __set 
     * 
     * @param mixed $propertyName 
     * @param mixed $propertyValue 
     * @throws ezcBaseValueException
     *          If a submitted parameter was out of range or type.
     * @throws ezcBasePropertyNotFoundException
     *          If a the value for the property options is not an instance of
     * @return void
     * @ignore
     */
    public function __set( $propertyName, $propertyValue )
    {
        switch ( $propertyName )
        {
            case 'angle':
                if ( !is_numeric( $propertyValue ) )
                {
                    throw new ezcBaseValueException( $propertyName, $propertyValue, '0 <= float < 360' );
                }

                $reducement = (int) ( $propertyValue - $propertyValue % 360 );
                $this->properties['angle'] = (float) $propertyValue - $reducement;
                break;

            case 'labelOffset':
                if ( !is_bool( $propertyValue ) )
                {
                    throw new ezcBaseValueException( $propertyName, $propertyValue, 'bool' );
                }

                $this->properties[$propertyName] = (bool) $propertyValue;
                break;

            default:
                return parent::__set( $propertyName, $propertyValue );
        }
    }

    /**
     * Determine label angle
     *
     * Determine the optiomal angle for the axis labels, of no angle has been
     * provided by the user.
     * 
     * @param array $steps 
     * @return void
     */
    protected function determineAngle( array $steps, $xSpace, $ySpace, ezcGraphBoundings $axisBoundings )
    {
        if ( $this->angle === null )
        {
            $minimumStepWidth = null;
            foreach ( $steps as $nr => $step )
            {
                if ( ( $minimumStepWidth === null ) || 
                     ( $step->width < $minimumStepWidth ) )
                {
                    $minimumStepWidth = $step->width;
                }
            }

            $width = abs(
                $axisBoundings->width * $minimumStepWidth * $this->direction->x +
                $axisBoundings->height * $minimumStepWidth * $this->direction->y
            );
            $height = abs(
                $ySpace * $this->direction->x +
                $xSpace * $this->direction->y
            );

            $length = sqrt( pow( $width, 2 ) + pow( $height, 2 ) );
            $this->angle = rad2deg( acos( $height / $length ) );
        }
    }

    /**
     * Determine text offset.
     *
     * Calculate the label offset and angle, from the configured or evaluated
     * text angle.
     *
     * Returns the text angle in degrees.
     * 
     * @param ezcGraphChartElementAxis $axis
     * @param array $steps
     * @return float
     */
    protected function determineTextOffset( ezcGraphChartElementAxis $axis, array $steps ) {
        // Determine additional required axis space by boxes
        $firstStep = reset( $steps );
        $lastStep = end( $steps );

        $axisAngle = -$this->direction->angle( new ezcGraphVector( 1, 0 ) );
        $textAngle = $axisAngle + 
            deg2rad( $this->angle ) + 
            ( $axis->position & ( ezcGraph::TOP | ezcGraph::BOTTOM ) ? deg2rad( 270 ) : deg2rad( 90 ) );

        // Ensure angle between 0 and 360 degrees
        $degTextAngle = rad2deg( $textAngle );
        while ( $degTextAngle < 0 )
        {
            $degTextAngle += 360.;
        }

        if ( $this->properties['labelOffset'] )
        {
            $this->offset =
                ( $this->angle < 0 ? -1 : 1 ) *
                ( $axis->position & ( ezcGraph::TOP | ezcGraph::LEFT ) ? 1 : -1 ) *
                ( 1 - cos( deg2rad( $this->angle * 2 ) ) );
        }
        else
        {
            $this->offset = 0;
        }

        return $degTextAngle;
    }

    /**
     * Calculate label size
     *
     * Calculate the size of a single lable in a single step.
     * 
     * @param array $steps
     * @param int $nr 
     * @param array $step 
     * @param float $xSpace 
     * @param float $ySpace 
     * @param ezcGraphBoundings $axisBoundings 
     * @return float
     */
    protected function calculateLabelSize( array $steps, $nr, $step, $xSpace, $ySpace, ezcGraphBoundings $axisBoundings )
    {
        switch ( true )
        {
            case ( $nr === 0 ):
                $labelSize = min(
                    abs( 
                        $xSpace * 2 * $this->direction->y +
                        $ySpace * 2 * $this->direction->x ),
                    abs( 
                        $step->width * $axisBoundings->width * $this->direction->x +
                        $step->width * $axisBoundings->height * $this->direction->y )
                );
                break;
            case ( $step->isLast ):
                $labelSize = min(
                    abs( 
                        $xSpace * 2 * $this->direction->y +
                        $ySpace * 2 * $this->direction->x ),
                    abs( 
                        $steps[$nr - 1]->width * $axisBoundings->width * $this->direction->x +
                        $steps[$nr - 1]->width * $axisBoundings->height * $this->direction->y )
                );
                break;
            default:
                $labelSize = abs( 
                    $step->width * $axisBoundings->width * $this->direction->x +
                    $step->width * $axisBoundings->height * $this->direction->y
                );
                break;
        }

        return $labelSize * cos( deg2rad( $this->angle ) );
    }

    /**
     * Calculate general label length
     * 
     * @param ezcGraphCoordinate $start 
     * @param ezcGraphCoordinate $end 
     * @param float $xSpace 
     * @param float $ySpace 
     * @param ezcGraphBoundings $axisBoundings 
     * @return float
     */
    protected function calculateLabelLength( ezcGraphCoordinate $start, ezcGraphCoordinate $end, $xSpace, $ySpace, ezcGraphBoundings $axisBoundings )
    {
        $axisSpaceFactor = abs(
            ( $this->direction->x == 0 ? 0 :
                $this->direction->x * $ySpace / $axisBoundings->width ) +
            ( $this->direction->y == 0 ? 0 :
                $this->direction->y * $xSpace / $axisBoundings->height )
        );

        $axisWidth  = $end->x - $start->x;
        $axisHeight = $end->y - $start->y;

        $start->x += max( 0., $axisSpaceFactor * $this->offset ) * $axisWidth;
        $start->y += max( 0., $axisSpaceFactor * $this->offset ) * $axisHeight;

        $end->x += min( 0., $axisSpaceFactor * $this->offset ) * $axisWidth;
        $end->y += min( 0., $axisSpaceFactor * $this->offset ) * $axisHeight;

        $labelLength = sqrt(
            pow(
                $xSpace * $this->direction->y +
                ( $this->labelOffset ? 
                    $axisSpaceFactor * $this->offset * ( $end->x - $start->x ) :
                    $ySpace * 2 * $this->direction->x
                ),
                2 ) +
            pow(
                $ySpace * $this->direction->x +
                ( $this->labelOffset ? 
                    $axisSpaceFactor * $this->offset * ( $end->y - $start->y ) :
                    $xSpace * 2 * $this->direction->y
                ),
                2 )
        );

        $this->offset *= $axisSpaceFactor;
        return $labelLength;
    }

    /**
     * Render label text.
     *
     * Render the text of a single label, depending on the position, length and
     * rotation of the label.
     * 
     * @param ezcGraphRenderer $renderer
     * @param ezcGraphChartElementAxis $axis 
     * @param ezcGraphCoordinate $position 
     * @param string $label 
     * @param float $degTextAngle 
     * @param float $labelLength 
     * @param float $labelSize 
     * @param float $lengthReducement 
     * @return void
     */
    protected function renderLabelText( ezcGraphRenderer $renderer, ezcGraphChartElementAxis $axis, ezcGraphCoordinate $position, $label, $degTextAngle, $labelLength, $labelSize, $lengthReducement )
    {
        switch ( true )
        {
            case ( ( ( $degTextAngle >= 0 ) && 
                     ( $degTextAngle < 90 ) &&
                     ( ( $axis->position === ezcGraph::LEFT ) ||
                       ( $axis->position === ezcGraph::RIGHT )
                     )
                   ) ||
                   ( ( $degTextAngle >= 270 ) && 
                     ( $degTextAngle < 360 ) &&
                     ( ( $axis->position === ezcGraph::TOP ) ||
                       ( $axis->position === ezcGraph::BOTTOM )
                     )
                   )
                 ):
                $labelBoundings = new ezcGraphBoundings(
                    $position->x,
                    $position->y,
                    $position->x + abs( $labelLength ) - $lengthReducement,
                    $position->y + $labelSize
                );
                $labelAlignement = ezcGraph::LEFT | ezcGraph::TOP;
                $labelRotation = $degTextAngle;
                break;
            case ( ( ( $degTextAngle >= 90 ) && 
                     ( $degTextAngle < 180 ) &&
                     ( ( $axis->position === ezcGraph::LEFT ) ||
                       ( $axis->position === ezcGraph::RIGHT )
                     )
                   ) ||
                   ( ( $degTextAngle >= 180 ) && 
                     ( $degTextAngle < 270 ) &&
                     ( ( $axis->position === ezcGraph::TOP ) ||
                       ( $axis->position === ezcGraph::BOTTOM )
                     )
                   )
                 ):
                $labelBoundings = new ezcGraphBoundings(
                    $position->x - abs( $labelLength ) + $lengthReducement,
                    $position->y,
                    $position->x,
                    $position->y + $labelSize
                );
                $labelAlignement = ezcGraph::RIGHT | ezcGraph::TOP;
                $labelRotation = $degTextAngle - 180;
                break;
            case ( ( ( $degTextAngle >= 180 ) && 
                     ( $degTextAngle < 270 ) &&
                     ( ( $axis->position === ezcGraph::LEFT ) ||
                       ( $axis->position === ezcGraph::RIGHT )
                     )
                   ) ||
                   ( ( $degTextAngle >= 90 ) && 
                     ( $degTextAngle < 180 ) &&
                     ( ( $axis->position === ezcGraph::TOP ) ||
                       ( $axis->position === ezcGraph::BOTTOM )
                     )
                   )
                 ):
                $labelBoundings = new ezcGraphBoundings(
                    $position->x - abs( $labelLength ) + $lengthReducement,
                    $position->y - $labelSize,
                    $position->x,
                    $position->y
                );
                $labelAlignement = ezcGraph::RIGHT | ezcGraph::BOTTOM;
                $labelRotation = $degTextAngle - 180;
                break;
            case ( ( ( $degTextAngle >= 270 ) && 
                     ( $degTextAngle < 360 ) &&
                     ( ( $axis->position === ezcGraph::LEFT ) ||
                       ( $axis->position === ezcGraph::RIGHT )
                     )
                   ) ||
                   ( ( $degTextAngle >= 0 ) && 
                     ( $degTextAngle < 90 ) &&
                     ( ( $axis->position === ezcGraph::TOP ) ||
                       ( $axis->position === ezcGraph::BOTTOM )
                     )
                   )
                 ):
                $labelBoundings = new ezcGraphBoundings(
                    $position->x,
                    $position->y,
                    $position->x - abs( $labelLength ) + $lengthReducement,
                    $position->y + $labelSize
                );
                $labelAlignement = ezcGraph::LEFT | ezcGraph::TOP;
                $labelRotation = $degTextAngle;
                break;
        }

        $renderer->drawText(
            $labelBoundings,
            $label,
            $labelAlignement,
            new ezcGraphRotation(
                $labelRotation,
                $position
            )
        );
    }

    /**
     * Render Axis labels
     *
     * Render labels for an axis.
     *
     * @param ezcGraphRenderer $renderer Renderer used to draw the chart
     * @param ezcGraphBoundings $boundings Boundings of the axis
     * @param ezcGraphCoordinate $start Axis starting point
     * @param ezcGraphCoordinate $end Axis ending point
     * @param ezcGraphChartElementAxis $axis Axis instance
     * @return void
     */
    public function renderLabels(
        ezcGraphRenderer $renderer,
        ezcGraphBoundings $boundings,
        ezcGraphCoordinate $start,
        ezcGraphCoordinate $end,
        ezcGraphChartElementAxis $axis,
        ezcGraphBoundings $innerBoundings = null )
    {
        // receive rendering parameters from axis
        $steps = $axis->getSteps();

        $axisBoundings = new ezcGraphBoundings(
            $start->x, $start->y,
            $end->x, $end->y
        );

        // Determine normalized axis direction
        $this->direction = new ezcGraphVector(
            $end->x - $start->x,
            $end->y - $start->y
        );
        $this->direction->unify();

        // Get axis space
        $gridBoundings = null;
        list( $xSpace, $ySpace ) = $this->getAxisSpace( $renderer, $boundings, $axis, $innerBoundings, $gridBoundings );

        // Determine optimal angle if none specified
        $this->determineAngle( $steps, $xSpace, $ySpace, $axisBoundings );
        $degTextAngle = $this->determineTextOffset( $axis, $steps );
        $labelLength  = $this->calculateLabelLength( $start, $end, $xSpace, $ySpace, $axisBoundings );

        // Draw steps and grid
        foreach ( $steps as $nr => $step )
        {
            $position = new ezcGraphCoordinate(
                $start->x + ( $end->x - $start->x ) * $step->position * abs( $this->direction->x ),
                $start->y + ( $end->y - $start->y ) * $step->position * abs( $this->direction->y )
            );
    
            $stepSize = new ezcGraphCoordinate(
                ( $end->x - $start->x ) * $step->width,
                ( $end->y - $start->y ) * $step->width
            );

            // Calculate label boundings
            $labelSize = $this->calculateLabelSize( $steps, $nr, $step, $xSpace, $ySpace, $axisBoundings );
            $lengthReducement = min(
                abs( tan( deg2rad( $this->angle ) ) * ( $labelSize / 2 ) ),
                abs( $labelLength / 2 )
            );

            $this->renderLabelText( $renderer, $axis, $position, $step->label, $degTextAngle, $labelLength, $labelSize, $lengthReducement );

            // Major grid
            if ( $axis->majorGrid )
            {
                $this->drawGrid( $renderer, $gridBoundings, $position, $stepSize, $axis->majorGrid );
            }
            
            // Major step
            $this->drawStep( $renderer, $position, $this->direction, $axis->position, $this->majorStepSize, $axis->border );
        }
    }
    
    /**
     * Modify chart data position
     *
     * Optionally additionally modify the coodinate of a data point
     * 
     * @param ezcGraphCoordinate $coordinate Data point coordinate
     * @return ezcGraphCoordinate Modified coordinate
     */
    public function modifyChartDataPosition( ezcGraphCoordinate $coordinate )
    {
        return new ezcGraphCoordinate(
            $coordinate->x * abs( $this->direction->y ) +
                ( $coordinate->x * ( 1 - abs( $this->offset ) ) * abs( $this->direction->x ) ) +
                ( abs( $this->offset ) * abs( $this->direction->x ) ),
            $coordinate->y * abs( $this->direction->x ) +
                ( $coordinate->y * ( 1 - abs( $this->offset ) ) * abs( $this->direction->y ) ) +
                ( abs( $this->offset ) * abs( $this->direction->y ) )
        );
    }
}
?>
