<?php
/**
 * File containing the abstract ezcGraphChartElementAxis 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
 */
/**
 * Class to represent an axis as a chart element
 *
 * Chart elements can be understood as widgets or layout container inside the
 * chart. The actual transformation to images happens inside the renderers.
 * They represent all elements inside the chart and contain mostly general
 * formatting options, while the renderer itself might define additional
 * formatting options for some chart elments. You can find more about the
 * general formatting options for chart elements in the base class
 * ezcGraphChartElement.
 *
 * The axis elements are special elements, as the border and background
 * settings do not apply directly as axis axis are not put inside any boxes.
 * The border value is reused for the color of the axis itself.
 *
 * Generally you should select the axis which matches your data best. By
 * default a labeled x axis and a numeric y axis are used. If you are using
 * date or time values on either axis, you should for example use a
 * ezcGraphChartElementDateAxis. The currently available axis types are:
 *
 * - ezcGraphChartElementDateAxis
 * - ezcGraphChartElementLabeledAxis
 * - ezcGraphChartElementLogarithmicalAxis
 * - ezcGraphChartElementNumericAxis
 *
 * Beside this there are several option to define the general layout of the
 * axis labels. The $formatString option may be used to add additional text to
 * each label on the axis, like a percent sign on the y axis:
 *
 * <code>
 *  $chart->xAxis->formatString = '%s %%';
 * </code>
 *
 * For more complex formatting operations for the label you may assign a custom
 * formatter function to the property $labelCallback.
 *
 * The orientation of labels and their position relatively to the axis ticks is
 * calcualted and rendered by the ezcGraphAxisLabelRenderer classes. You can
 * choose between different axis label renderer, or create you own, and assign
 * an instance of one to the property $axisLabelRenderer. Currently the
 * available axis label renderers are:
 * 
 * - ezcGraphAxisBoxedLabelRenderer
 *
 *   Renders grid and labels like commonly used in bar charts, with the label
 *   between two grid lines.
 *  
 * - ezcGraphAxisCenteredLabelRenderer
 *
 *   Centers the label right next to a tick. Commonly used for labeled axis.
 *
 * - ezcGraphAxisExactLabelRenderer
 *
 *   Put the label next to each tick. Commonly used for numeric axis.
 *
 * - ezcGraphAxisNoLabelRenderer
 *
 *   Renders no labels.
 *
 * - ezcGraphAxisRadarLabelRenderer
 *
 *   Special label renderer for radar charts.
 *
 * - ezcGraphAxisRotatedLabelRenderer
 *
 *   Accepts a rotation angle for the texts put at some axis, which might be
 *   useful for longer textual labels on the axis.
 *
 * The label renderer used by default is different depending on the axis type.
 *
 * @property float $nullPosition
 *           The position of the null value.
 * @property float $axisSpace
 *           Percent of the chart space used to display axis labels and 
 *           arrowheads instead of data values.
 * @property float $outerAxisSpace
 *           Percent of the chart space used to display axis arrow at the outer
 *           side of the axis. If set to null, the axisSpace will be used here.
 * @property ezcGraphColor $majorGrid
 *           Color of major majorGrid.
 * @property ezcGraphColor $minorGrid
 *           Color of minor majorGrid.
 * @property mixed $majorStep
 *           Labeled major steps displayed on the axis. @TODO: Should be moved
 *           to numeric axis.
 * @property mixed $minorStep
 *           Non labeled minor steps on the axis. @TODO: Should be moved to
 *           numeric axis.
 * @property string $formatString
 *           Formatstring to use for labeling of the axis.
 * @property string $label
 *           Axis label
 * @property int $labelSize
 *           Size of axis label
 * @property int $labelMargin
 *           Distance between label an axis
 * @property int $minArrowHeadSize
 *           Minimum Size used to draw arrow heads.
 * @property int $maxArrowHeadSize
 *           Maximum Size used to draw arrow heads.
 * @property ezcGraphAxisLabelRenderer $axisLabelRenderer
 *           AxisLabelRenderer used to render labels and grid on this axis.
 * @property callback $labelCallback
 *           Callback function to format chart labels.
 *           Function will receive two parameters and should return a 
 *           reformatted label.
 *              string function( label, step )
 * @property float $chartPosition
 *           Position of the axis in the chart. Only useful for additional
 *           axis. The basic chart axis will be automatically positioned.
 * @property-read bool $initialized
 *           Property indicating if some values were associated with axis, or a
 *           scaling has been set manually.
 * @property float $labelRotation
 *           Rotation of the axis label in degree
 *
 * @version //autogentag//
 * @package Graph
 */
abstract class ezcGraphChartElementAxis extends ezcGraphChartElement
{
    /**
     * Axis label renderer class
     * 
     * @var ezcGraphAxisLabelRenderer
     */
    protected $axisLabelRenderer;

    /**
     * Optionally set inner boundings. May be null depending on the used chart
     * implementation.
     * 
     * @var ezcGraphBoundings
     */
    protected $innerBoundings;

    /**
     * Constructor
     * 
     * @param array $options Default option array
     * @return void
     * @ignore
     */
    public function __construct( array $options = array() )
    {
        $this->properties['nullPosition'] = false;
        $this->properties['axisSpace'] = .1;
        $this->properties['outerAxisSpace'] = null;
        $this->properties['majorGrid'] = false;
        $this->properties['minorGrid'] = false;
        $this->properties['majorStep'] = null;
        $this->properties['minorStep'] = null;
        $this->properties['formatString'] = '%s';
        $this->properties['label'] = false;
        $this->properties['labelSize'] = 14;
        $this->properties['labelMargin'] = 2;
        $this->properties['minArrowHeadSize'] = 4;
        $this->properties['maxArrowHeadSize'] = 8;
        $this->properties['labelCallback'] = null;
        $this->properties['chartPosition'] = null;
        $this->properties['initialized'] = false;
        $this->properties['labelRotation'] = 0.;

        parent::__construct( $options );

        if ( !isset( $this->axisLabelRenderer ) )
        {
            $this->axisLabelRenderer = new ezcGraphAxisExactLabelRenderer();
        }
    }

    /**
     * Set colors and border fro this element
     * 
     * @param ezcGraphPalette $palette Palette
     * @return void
     */
    public function setFromPalette( ezcGraphPalette $palette )
    {
        $this->border = $palette->axisColor;
        $this->padding = $palette->padding;
        $this->margin = $palette->margin;
        $this->majorGrid = $palette->majorGridColor;
        $this->minorGrid = $palette->minorGridColor;
    }

    /**
     * __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
     */
    public function __set( $propertyName, $propertyValue )
    {
        switch ( $propertyName )
        {
            case 'nullPosition':
                $this->properties['nullPosition'] = (float) $propertyValue;
                break;
            case 'axisSpace':
                if ( !is_numeric( $propertyValue ) ||
                     ( $propertyValue < 0 ) ||
                     ( $propertyValue >= 1 ) )
                {
                    throw new ezcBaseValueException( $propertyName, $propertyValue, '0 <= float < 1' );
                }

                $this->properties['axisSpace'] = (float) $propertyValue;
                break;
            case 'outerAxisSpace':
                if ( !is_null( $propertyValue ) &&
                     ( !is_numeric( $propertyValue ) ||
                       ( $propertyValue < 0 ) ||
                       ( $propertyValue >= 1 ) ) )
                {
                    throw new ezcBaseValueException( $propertyName, $propertyValue, 'null, or 0 <= float < 1' );
                }

                $this->properties['outerAxisSpace'] = $propertyValue;
                break;
            case 'majorGrid':
                $this->properties['majorGrid'] = ezcGraphColor::create( $propertyValue );
                break;
            case 'minorGrid':
                $this->properties['minorGrid'] = ezcGraphColor::create( $propertyValue );
                break;
            case 'majorStep':
                if ( !is_numeric( $propertyValue ) ||
                     ( $propertyValue <= 0 ) )
                {
                    throw new ezcBaseValueException( $propertyName, $propertyValue, 'float > 0' );
                }
                
                $this->properties['majorStep'] = (float) $propertyValue;
                break;
            case 'minorStep':
                if ( !is_numeric( $propertyValue ) ||
                     ( $propertyValue <= 0 ) )
                {
                    throw new ezcBaseValueException( $propertyName, $propertyValue, 'float > 0' );
                }
                
                $this->properties['minorStep'] = (float) $propertyValue;
                break;
            case 'formatString':
                $this->properties['formatString'] = (string) $propertyValue;
                break;
            case 'label':
                $this->properties['label'] = (string) $propertyValue;
                break;
            case 'labelSize':
                if ( !is_numeric( $propertyValue ) ||
                     ( $propertyValue <= 6 ) )
                {
                    throw new ezcBaseValueException( $propertyName, $propertyValue, 'int >= 6' );
                }
                
                $this->properties['labelSize'] = (int) $propertyValue;
                break;
            case 'labelMargin':
                if ( !is_numeric( $propertyValue ) ||
                     ( $propertyValue <= 0 ) )
                {
                    throw new ezcBaseValueException( $propertyName, $propertyValue, 'int >= 0' );
                }
                
                $this->properties['labelMargin'] = (int) $propertyValue;
                break;
            case 'maxArrowHeadSize':
                if ( !is_numeric( $propertyValue ) ||
                     ( $propertyValue <= 0 ) )
                {
                    throw new ezcBaseValueException( $propertyName, $propertyValue, 'int >= 0' );
                }
                
                $this->properties['maxArrowHeadSize'] = (int) $propertyValue;
                break;
            case 'minArrowHeadSize':
                if ( !is_numeric( $propertyValue ) ||
                     ( $propertyValue <= 0 ) )
                {
                    throw new ezcBaseValueException( $propertyName, $propertyValue, 'int >= 0' );
                }
                
                $this->properties['minArrowHeadSize'] = (int) $propertyValue;
                break;
            case 'axisLabelRenderer':
                if ( $propertyValue instanceof ezcGraphAxisLabelRenderer )
                {
                    $this->axisLabelRenderer = $propertyValue;
                }
                else
                {
                    throw new ezcBaseValueException( $propertyName, $propertyValue, 'ezcGraphAxisLabelRenderer' );
                }
                break;
            case 'labelCallback':
                if ( is_callable( $propertyValue ) )
                {
                    $this->properties['labelCallback'] = $propertyValue;
                }
                else
                {
                    throw new ezcBaseValueException( $propertyName, $propertyValue, 'callback function' );
                }
                break;
            case 'chartPosition':
                if ( !is_numeric( $propertyValue ) ||
                     ( $propertyValue < 0 ) ||
                     ( $propertyValue > 1 ) )
                {
                    throw new ezcBaseValueException( $propertyName, $propertyValue, '0 <= float <= 1' );
                }

                $this->properties['chartPosition'] = (float) $propertyValue;
                break;
            case 'labelRotation':
                if ( !is_numeric( $propertyValue ) )
                {
                    throw new ezcBaseValueException( $propertyName, $propertyValue, 'float' );
                }
                
                $this->properties['labelRotation'] = fmod( (float) $propertyValue, 360. );
                break;
            default:
                parent::__set( $propertyName, $propertyValue );
                break;
        }
    }

    /**
     * __get 
     * 
     * @param mixed $propertyName 
     * @throws ezcBasePropertyNotFoundException
     *          If a the value for the property options is not an instance of
     * @return mixed
     * @ignore
     */
    public function __get( $propertyName )
    {
        switch ( $propertyName )
        {
            case 'axisLabelRenderer':
                return $this->axisLabelRenderer;
            default:
                return parent::__get( $propertyName );
        }
    }

    /**
     * Get coordinate for a dedicated value on the chart
     * 
     * @param float $value Value to determine position for
     * @return float Position on chart
     */
    abstract public function getCoordinate( $value );

    /**
     * Return count of minor steps
     * 
     * @return integer Count of minor steps
     */
    abstract public function getMinorStepCount();

    /**
     * Return count of major steps
     * 
     * @return integer Count of major steps
     */
    abstract public function getMajorStepCount();

    /**
     * Get label for a dedicated step on the axis
     * 
     * @param integer $step Number of step
     * @return string label
     */
    abstract public function getLabel( $step );

    /**
     * Return array of steps on this axis
     * 
     * @return array( ezcGraphAxisStep )
     */
    public function getSteps()
    {
        $majorSteps = $this->getMajorStepCount();
        $minorStepsPerMajorStepCount = ( $this->getMinorStepCount() / $majorSteps );

        $majorStepSize = 1 / $majorSteps;
        $minorStepSize = ( $minorStepsPerMajorStepCount > 0 ? $majorStepSize / $minorStepsPerMajorStepCount : 0 );

        $steps = array();
        for ( $major = 0; $major <= $majorSteps; ++$major )
        {
            $majorStep = new ezcGraphAxisStep(
                $majorStepSize * $major,
                $majorStepSize,
                $this->getLabel( $major ),
                array(),
                $this->isZeroStep( $major ),
                ( $major === $majorSteps )
            );

            if ( ( $minorStepsPerMajorStepCount > 0 ) &&
                 ( $major < $majorSteps ) )
            {
                // Do not add minor steps at major steps positions
                for( $minor = 1; $minor < $minorStepsPerMajorStepCount; ++$minor )
                {
                    $majorStep->childs[] = new ezcGraphAxisStep(
                        ( $majorStepSize * $major ) + ( $minorStepSize * $minor ),
                        $minorStepSize
                    );
                }
            }

            $steps[] = $majorStep;
        }

        return $steps;
    }

    /**
     * Is zero step
     *
     * Returns true if the given step is the one on the initial axis position
     * 
     * @param int $step Number of step
     * @return bool Status If given step is initial axis position
     */
    abstract public function isZeroStep( $step );

    /**
     * Add data for this axis
     * 
     * @param array $values
     * @return void
     */
    abstract public function addData( array $values );

    /**
     * Calculate axis bounding values on base of the assigned values 
     * 
     * @abstract
     * @access public
     * @return void
     */
    abstract public function calculateAxisBoundings();

    /**
     * Render the axis 
     * 
     * @param ezcGraphRenderer $renderer Renderer
     * @param ezcGraphBoundings $boundings Boundings for the axis
     * @return ezcGraphBoundings Remaining boundings
     */
    public function render( ezcGraphRenderer $renderer, ezcGraphBoundings $boundings, ezcGraphBoundings $innerBoundings = null )
    {
        $this->innerBoundings = $innerBoundings;
        $startSpace = $this->axisSpace;
        $endSpace   = $this->outerAxisSpace === null ? $this->axisSpace : $this->outerAxisSpace;

        switch ( $this->position )
        {
            case ezcGraph::TOP:
                $start = new ezcGraphCoordinate(
                    $boundings->width * $startSpace +
                        $this->nullPosition * $boundings->width * ( 1 - ( $startSpace + $endSpace ) ),
                    0
                );
                $end = new ezcGraphCoordinate(
                    $boundings->width * $startSpace +
                        $this->nullPosition * $boundings->width * ( 1 - ( $startSpace + $endSpace ) ),
                    $boundings->height
                );
                break;
            case ezcGraph::BOTTOM:
                $start = new ezcGraphCoordinate(
                    $boundings->width * $startSpace +
                        $this->nullPosition * $boundings->width * ( 1 - ( $startSpace + $endSpace ) ),
                    $boundings->height
                );
                $end = new ezcGraphCoordinate(
                    $boundings->width * $startSpace +
                        $this->nullPosition * $boundings->width * ( 1 - ( $startSpace + $endSpace ) ),
                    0
                );
                break;
            case ezcGraph::LEFT:
                $start = new ezcGraphCoordinate(
                    0,
                    $boundings->height * $endSpace +
                        $this->nullPosition * $boundings->height * ( 1 - ( $startSpace + $endSpace ) )
                );
                $end = new ezcGraphCoordinate(
                    $boundings->width,
                    $boundings->height * $endSpace +
                        $this->nullPosition * $boundings->height * ( 1 - ( $startSpace + $endSpace ) )
                );
                break;
            case ezcGraph::RIGHT:
                $start = new ezcGraphCoordinate(
                    $boundings->width,
                    $boundings->height * $endSpace +
                        $this->nullPosition * $boundings->height * ( 1 - ( $startSpace + $endSpace ) )
                );
                $end = new ezcGraphCoordinate(
                    0,
                    $boundings->height * $endSpace +
                        $this->nullPosition * $boundings->height * ( 1 - ( $startSpace + $endSpace ) )
                );
                break;
        }

        $renderer->drawAxis(
            $boundings,
            $start,
            $end,
            $this,
            $this->axisLabelRenderer,
            $innerBoundings
        );

        return $boundings;   
    }
}

?>
