////////////////////////////////////////////////////////////////////////////////
//
//  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 mx.charts
{

import flash.events.Event;

import mx.charts.chartClasses.AxisBase;
import mx.charts.chartClasses.AxisLabelSet;
import mx.charts.chartClasses.IAxis;
import mx.collections.ArrayCollection;
import mx.collections.CursorBookmark;
import mx.collections.ICollectionView;
import mx.collections.IViewCursor;
import mx.collections.XMLListCollection;
import mx.core.mx_internal;
import mx.events.CollectionEvent;
import mx.events.CollectionEventKind;
use namespace mx_internal;

/**
 *  The CategoryAxis class lets charts represent data
 *  grouped by a set of discrete values along an axis.
 *  You typically use the CategoryAxis class to define
 *  a set of labels that appear along an axis of a chart.
 *  For example, charts that render data according to City,
 *  Year, Business unit, and so on.
 *  
 *  <p>You are not required to explicitly set the <code>dataProvider</code> property
 *  on a CategoryAxis. A CategoryAxis used in a chart inherits its
 *  <code>dataProvider</code> property from the containing chart.</p>
 *  
 *  <p>While you can use the same data provider to provide data
 *  to the chart and categories to the CategoryAxis, a CategoryAxis
 *  can optimize rendering if its data provider is relatively static.
 *  If possible, ensure that the categories are relatively static
 *  and that changing data is stored in separate data providers.</p>
 *  
 *  <p>The <code>dataProvider</code> property can accept
 *  either an array of strings or an array of records (Objects)
 *  with a property that specifies the category name.
 *  If you specify a <code>categoryField</code> property,
 *  the CategoryAxis assumes that the data provider is an array of Objects.
 *  If the value of the <code>categoryField</code> property is <code>null</code>,
 *  the CategoryAxis assumes that the data provider is an array of Strings.</p>
 *  
 *  @mxml
 *  
 *  <p>The <code>&lt;mx:CategoryAxis&gt;</code> tag inherits all the properties
 *  of its parent classes and adds the following properties:</p>
 *  
 *  <pre>
 *  &lt;mx:CategoryAxis
 *    <strong>Properties</strong>
 *    categoryField="null"
 *    dataFunction="<i>No default</i>"
 *    dataProvider="<i>No default</i>"
 *    labelFunction="<i>No default</i>"
 *    padding="<i>Default depends on chart type</i>"
 *    ticksBetweenLabels="<i>true</i>"
 *  /&gt;
 *  </pre>
 *
 *  @includeExample examples/HLOCChartExample.mxml
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
public class CategoryAxis extends AxisBase implements IAxis
{
    include "../core/Version.as";

    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------

    /**
     *  Constructor.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function CategoryAxis()
    {
        super();

        workingDataProvider = new ArrayCollection();
    }

    //--------------------------------------------------------------------------
    //
    //  Variables
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     */
    private var _cursor:IViewCursor;
    
    /**
     *  @private
     */
    private var _catMap:Object;

    /**
     *  @private
     */
    private var _categoryValues:Array /* of Object */;
    
    /**
     *  @private
     */
    private var _labelsMatchToCategoryValuesByIndex:Array /* of AxisLabel */;

    /**
     *  @private
     */
    private var _cachedMinorTicks:Array /* of Number */ = null; 
    
    /**
     *  @private
     */
    private var _cachedTicks:Array /* of Number */ = null;  

    /**
     *  @private
     */
    private var _labelSet:AxisLabelSet;
    
    //--------------------------------------------------------------------------
    //
    //  Overridden properties
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    //  chartDataProvider
    //----------------------------------

    /**
     *  @private
     *  Storage for the chartDataProvider property.
     */
    private var _chartDataProvider:Object;
    
    /**
     *  @private
     */
    override public function set chartDataProvider(value:Object):void
    {
		if(_chartDataProvider != value)
		{
        	_chartDataProvider = value;

	        if (!_userDataProvider)
    	        workingDataProvider = _chartDataProvider;
		}
    }
    
    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------
    
    //----------------------------------
    //  baseline
    //----------------------------------

    [Inspectable(environment="none")]

    /**
     *  @inheritDoc
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get baseline():Number
    {
        return -_padding;
    }

    //----------------------------------
    //  categoryField
    //----------------------------------

    /**
     *  @private
     *  Storage for the categoryField property.
     */
    private var _categoryField:String = "";
    
    [Inspectable(category="General")]
    
    /**
     *  Specifies the field of the data provider
     *  containing the text for the labels.
     *  If this property is <code>null</code>, CategoryAxis assumes 
     *  that the dataProvider contains an array of Strings.
     *
     *  @default null
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get categoryField():String
    {
        return _categoryField;
    }
    
    /**
     *  @private
     */
    public function set categoryField(value:String):void
    {
        _categoryField = value;

        collectionChangeHandler();
    }
    
    //---------------------------------
    // dataFunction
    //---------------------------------
    
    [Bindable]
    [Inspectable(category="General")]
    
    /**
     *  @private
     * Storage for dataFunction property
     */
     private var _dataFunction:Function = null;
     
    /**
     * Specifies a method that returns the value that should be used as
     * categoryValue for current item.If this property is set, the return 
     * value of the custom data function takes precedence over 
     * <code>categoryField</code>
     * 
     * <p>The custom <code>dataFunction</code> has the following signature:
     *  
     * <pre>
     * <i>function_name</i> (axis:CategoryAxis, item:Object):Object { ... }
     * </pre>
     * 
     * <code>axis</code> is the current axis that uses this <code>dataFunction</code>
     * <code>item</code> is the item in the dataProvider that is considered.
     * This function returns an object.
     * </p>
     *  
     * <p>An example usage of a customized <code>dataFunction</code> is to return a value
     * from a dataProvider that has items with nested fields</p>
     *   
     * @example
     * <pre>
     * public function myFunction(axis:CategoryAxis,item:Object):Object {
     *      return(item.Country.State);
     * }     
     * </pre>
     *
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get dataFunction():Function
    {
        return _dataFunction;
    }
    
    /**
     *  @private
     */
    public function set dataFunction(value:Function):void
    {
        _dataFunction = value;
        collectionChangeHandler();
    }


    //----------------------------------
    //  dataProvider
    //----------------------------------

    /**
     *  @private
     *  Storage for the dataProvider property.
     */
    private var _dataProvider:ICollectionView;
    
    /**
     *  @private
     */
    private var _userDataProvider:Object;
    
    [Inspectable(category="General")]
    
    /**
     *  Specifies the data source containing the label names.
     *  The <code>dataProvider</code> can be an Array of Strings, an Array of Objects,
     *  or any object that implements the IList or ICollectionView interface.
     *  If the <code>dataProvider</code> is an Array of Strings,
     *  ensure that the <code>categoryField</code> property
     *  is set to <code>null</code>. 
     *  If the dataProvider is an Array of Objects,
     *  set the <code>categoryField</code> property
     *  to the name of the field that contains the label text.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get dataProvider():Object
    {
        return _dataProvider;
    }
    
    /**
     *  @private
     */
    public function set dataProvider(value:Object):void
    {
        _userDataProvider = value;

        if (_userDataProvider != null)
            workingDataProvider = _userDataProvider;
        else
            workingDataProvider = _chartDataProvider;
    }

    //----------------------------------
    //  labelFunction
    //----------------------------------

    /**
     *  @private
     *  Storage for the labelFunction property.
     */
    private var _labelFunction:Function = null;
    
    [Inspectable(category="General")]
    
    /**
     *  Specifies a function that defines the labels that are generated
     *  for each item in the CategoryAxis's <code>dataProvider</code>.
     *  If no <code>labelFunction</code> is provided,
     *  the axis labels default to the value of the category itself.
     *
     *  <p>The <code>labelFunction</code> method for a CategoryAxis
     *  has the following signature:</p>
     *  <pre>
     *  function <i>function_name</i>(<i>categoryValue</i>:Object, <i>previousCategoryValue</i>:Object, <i>axis</i>:CategoryAxis, <i>categoryItem</i>:Object):String { ... }
     *  </pre>
     *  
     *  <p>Where:</p>
     *  <ul>
     *   <li><code><i>categoryValue</i></code> is the value of the category to be represented.</li>
     *   <li><code><i>previousCategoryValue</i></code> is the value of the previous category on the axis.</li>
     *   <li><code><i>axis</i></code> is the CategoryAxis being rendered.</li>
     *   <li><code><i>categoryItem</i></code> is the item from the <code>dataProvider</code> 
     *     that is being represented.</li>
     *  </ul>
     *  
     *  <p>Flex displays the returned String as the axis label.</p>
     * 
     *  <p>If the <code>categoryField</code> property is not set, the value
     *  will be the same as the <code>categoryValue</code> property.</p>
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */ 
    public function get labelFunction():Function
    {
        return _labelFunction;
    }
    
    /**
     *  @private
     */
    public function set labelFunction(value:Function):void
    {
        _labelFunction = value;

        invalidateCategories();
    }
    
    //----------------------------------
    //  minorTicks (private)
    //----------------------------------
 
    /**
     *  @private
     */
    private function get minorTicks():Array /* of Number */
    {
        if (!_cachedMinorTicks)
        {
            _cachedMinorTicks = [];

            var n:int;
            var min:Number;
            var max:Number;
            var alen:Number;
            var i:Number;
            
            if (_ticksBetweenLabels == false)
            {
                n = _categoryValues.length;
                min = -_padding;
                max = n - 1 + _padding;
                alen = max - min;
                
                var start:Number = min <= -0.5 ? 0 : 1;
                var end:Number = max >= n - 0.5 ? n : n - 1
                
                for (i = start; i <= end; i++) // <= to draw final tick
                {
                    _cachedMinorTicks.push((i - 0.5 - min) / alen);
                }
            }
            else
            {
                n = _categoryValues.length;
                min = -_padding;
                max = n - 1 + _padding;
                alen = max - min;
                
                for (i = 0; i < n; i++) // <= to draw final tick
                {
                    _cachedMinorTicks.push((i - min) / alen);
                }
            }
        }

        return _cachedMinorTicks;
    }

    //----------------------------------
    //  padding
    //----------------------------------

    /**
     *  @private
     *  Storage for the padding property.
     */
    private var _padding:Number = 0.5;
    
    [Inspectable(category="General")]

    /**
     *  Specifies the padding added to either side of the axis
     *  when rendering data on the screen.
     *  Set to 0 to map the first category to the
     *  very beginning of the axis and the last category to the end.
     *  Set to 0.5 to leave padding of half the width
     *  of a category on the axis between the beginning of the axis
     *  and the first category and between the last category
     *  and the end of the axis.
     *  
     *  <p>This is useful for chart types that render beyond the bounds
     *  of the category, such as columns and bars.
     *  However, when used as the horizontalAxis in a LineChart or AreaChart,
     *  it is reset to 0.</p>
     *  
     *  @default 0.5
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get padding():Number
    {
        return _padding;
    }
    
    /**
     *  @private
     */
    public function set padding(value:Number):void
    {
        _padding = value;

        invalidateCategories();

        dispatchEvent(new Event("mappingChange"));
        dispatchEvent(new Event("axisChange"));
    }
    
    //----------------------------------
    //  ticksBetweenLabels
    //----------------------------------

    /**
     *  @private
     *  Storage for the tickBetweenLabels property.
     */
    private var _ticksBetweenLabels:Boolean = true;
    
    [Inspectable]

    /**
     *  Specifies the location of major tick marks on the axis,
     *  relative to the category labels.
     *  If <code>true</code>, tick marks (and any associated grid lines)
     *  appear between the categories.
     *  If <code>false</code>, tick marks appear in the middle of the category,
     *  aligned with the label.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get ticksBetweenLabels():Boolean
    {
        return _ticksBetweenLabels;
    }

    /**
     *  @private
     */
    public function set ticksBetweenLabels(value:Boolean):void
    {
        _ticksBetweenLabels = value;
    }

    //----------------------------------
    //  workingDataProvider
    //----------------------------------

    /**
     *  @private
     */
    private function set workingDataProvider(value:Object):void
    {
        if (_dataProvider != null)
        {
            _dataProvider.removeEventListener(
                CollectionEvent.COLLECTION_CHANGE, collectionChangeHandler);
        }
        
        if (value is Array)
        {
            value = new ArrayCollection(value as Array);
        }
        else if (value is ICollectionView)
        {
        }
        else if (value is XMLList)
        {
            value = new XMLListCollection(XMLList(value));
        }
        else if (value != null)
        {
            value = new ArrayCollection([ value ]);
        } 
        else 
        {
            value = new ArrayCollection();
        }
            
        _dataProvider = ICollectionView(value);

        _cursor = value.createCursor();

        if (_dataProvider) 
        {
            // weak listeners to collections and dataproviders
            _dataProvider.addEventListener(
                CollectionEvent.COLLECTION_CHANGE, collectionChangeHandler, false, 0, true);
        }

        collectionChangeHandler();
    }
    
    //--------------------------------------------------------------------------
    //
    //  Methods
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @copy mx.charts.chartClasses.IAxis#mapCache()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function mapCache(cache:Array /* of ChartItem */, field:String,
                             convertedField:String,
                             indexValues:Boolean = false):void
    {
        update();

        var n:int = cache.length;
        
        // Find the first non null item in the cache so we can determine type.
        // Since these initial values are null,
        // we can safely skip assigning values for them.
        for (var i:int = 0; i < n; i++)
        {
            if (cache[i][field] != null)
                break;
        }
        if (i == n)
            return;
        
        var value:Object = cache[i][field]
        if (value is XML ||
                 value is XMLList)
        {
            for (; i < n; i++)
            {
                cache[i][convertedField] = _catMap[cache[i][field].toString()];             
            }
        }
        else if ((value is Number || value is int || value is uint) &&
                 indexValues == true)
        {
            for (i = 0; i < n; i++)
            {
                var v:Object = cache[i];
                v[convertedField] = v[field];
            }
        }
        else
        {
            for (; i < n; i++)
            {
                cache[i][convertedField] = _catMap[cache[i][field]];                
            }
        }
        
    }

    /**
     *  @copy mx.charts.chartClasses.IAxis#filterCache()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function filterCache(cache:Array /* of ChartItem */, field:String,
                                filteredField:String):void
    {
        update();

        // Our bounds are the categories, plus/minus padding,
        // plus a little fudge factor to account for floating point errors.
        var computedMaximum:Number = _categoryValues.length - 1 +
                                     _padding + 0.000001;
        var computedMinimum:Number = -_padding - 0.000001;
        
        var n:int = cache.length;
        for (var i:int = 0; i < n; i++)
        {
            var v:Number =  cache[i][field];
            cache[i][filteredField] = v >= computedMinimum &&
                                      v < computedMaximum ?
                                      v :
                                      NaN;
        }
    }

    /**
     *  @copy mx.charts.chartClasses.IAxis#transformCache()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function transformCache(cache:Array /* of ChartItem */, field:String,
                                   convertedField:String):void
    {
        update();

        var min:Number = -_padding;
        var max:Number = _categoryValues.length - 1 + _padding;
        var alen:Number = max - min;

        var n:int = cache.length;
        for (var i:int = 0; i < n; i++)
        {
            cache[i][convertedField] = (cache[i][field] - min) / alen;
        }
    }

    /**
     *  @copy mx.charts.chartClasses.IAxis#invertTransform()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function invertTransform(value:Number):Object
    {
        update();

        var min:Number = -_padding;
        var max:Number = _categoryValues.length - 1 + _padding;
        var alen:Number = max - min;

        return _categoryValues[Math.round((value * alen) + min)];
    }

    /**
     *  @copy mx.charts.chartClasses.IAxis#formatForScreen()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function formatForScreen(value:Object):String    
    {
        if (value is Number && value < _categoryValues.length)
        {
            var catValue:Object = _categoryValues[Math.round(Number(value))];
            return catValue == null ? value.toString() : catValue.toString();
        }

        return value.toString();    
    }

    /**
     *  @copy mx.charts.chartClasses.IAxis#getLabelEstimate()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function getLabelEstimate():AxisLabelSet
    {
        update();

        return _labelSet;
    }

    /**
     *  @copy mx.charts.chartClasses.IAxis#preferDropLabels()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function preferDropLabels():Boolean
    {
        return false;
    }

    /**
     *  @copy mx.charts.chartClasses.IAxis#getLabels()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function getLabels(minimumAxisLength:Number):AxisLabelSet
    {
        update();

        return _labelSet;
    }

    /**
     *  @copy mx.charts.chartClasses.IAxis#reduceLabels()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function reduceLabels(intervalStart:AxisLabel,intervalEnd:AxisLabel):AxisLabelSet
    {
        var skipCount:int = _catMap[intervalEnd.value] - _catMap[intervalStart.value] + 1;
        
        if (skipCount <= 0)
            return null;
            
        var newLabels:Array /* of AxisLabel */ = [];
        var newTicks:Array /* of Number */ = [];
        
        var min:Number = -_padding;
        var max:Number = _categoryValues.length - 1 + _padding;
        var alen:Number = (max-min);
		
		var n:int  = _categoryValues.length;
		for (var i:int = 0; i < n; i += skipCount)
        {
            newLabels.push(_labelsMatchToCategoryValuesByIndex[i]);
            newTicks.push(_labelsMatchToCategoryValuesByIndex[i].position);
        }
        
        var axisLabelSet:AxisLabelSet = new AxisLabelSet();
        axisLabelSet.labels = newLabels;
        axisLabelSet.minorTicks = minorTicks;
        axisLabelSet.ticks = generateTicks();
        return axisLabelSet;
    }

    /**
     *  @copy mx.charts.chartClasses.IAxis#update()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function update():void
    {
        if (!_labelSet)
        {
            var prop:Object;
            
            _catMap = {};
            _categoryValues = [];
            _labelsMatchToCategoryValuesByIndex = [];

            var categoryItems:Array = [];
            var i:int;
            
            if (_dataFunction != null)
            {
                _cursor.seek(CursorBookmark.FIRST);
                i = 0;
                while (!_cursor.afterLast)
                {
                    categoryItems[i] = _cursor.current;
                    prop = dataFunction(this,categoryItems[i]);
                    if (prop)
                      _catMap[prop.toString()] = i;                   
                    _categoryValues[i] = prop;
                    i++;
                    _cursor.moveNext()
                }
            }
            
            else if (_categoryField == "")
            {
                _cursor.seek(CursorBookmark.FIRST);
                i = 0;
                while (!_cursor.afterLast)
                {
                    prop = _cursor.current;
                    if (prop != null)
                        _catMap[prop.toString()] = i;                   
                    _categoryValues[i] = categoryItems[i] = prop;
                    _cursor.moveNext();
                    i++;
                }
            }
            else
            {
                _cursor.seek(CursorBookmark.FIRST);
                i = 0;
                while (!_cursor.afterLast)
                {
                    categoryItems[i] = _cursor.current;
                    if (categoryItems[i] && _categoryField in categoryItems[i])
                    {
                        prop = categoryItems[i][_categoryField];
                        if (prop != null)
                            _catMap[prop.toString()] = i;                   
                        _categoryValues[i] = prop;
                    }
                    else
                    {
                        _categoryValues[i] = null;
                    }
                    i++;
                    _cursor.moveNext()
                }
            }

            var axisLabels:Array /* of AxisLabel */ = [];
            
            var min:Number = -_padding;
            var max:Number = _categoryValues.length - 1 + _padding;
            var alen:Number = max - min;
            var label:AxisLabel;

            var n:int = _categoryValues.length;
            if (_labelFunction != null)
            {
                var previousValue:Object = null;
                for (i = 0; i < n; i++)
                {
                    if (_categoryValues[i] == null)
                        continue;
                        
                    label = new AxisLabel((i - min) / alen, _categoryValues[i],
                        _labelFunction(_categoryValues[i], previousValue,
                        this, categoryItems[i]));
                    _labelsMatchToCategoryValuesByIndex[i] = label;
                    axisLabels.push(label);

                    previousValue = _categoryValues[i];
                }
            }
            else
            {
                for (i = 0; i < n; i++)
                {
                    if (!_categoryValues[i])
                        continue;
                    
                    label = new AxisLabel((i - min) / alen, _categoryValues[i],
                        _categoryValues[i].toString());
                    _labelsMatchToCategoryValuesByIndex[i] = label;
                    axisLabels.push(label);
                }               
            }

            _labelSet = new AxisLabelSet();
            _labelSet.labels = axisLabels;
            _labelSet.accurate = true;
            _labelSet.minorTicks = minorTicks;
            _labelSet.ticks = generateTicks();          
        }
    }

    /**
     *  @private
     */
    private function generateTicks():Array /* of Number */
    {
        if (!_cachedTicks)
        {
            _cachedTicks = [];

            var n:int;
            var min:Number;
            var max:Number;
            var alen:Number;
            var i:Number;
            
            if (_ticksBetweenLabels == false)
            {
                n = _categoryValues.length;
                min = -_padding;
                max = n - 1 + _padding;
                alen = max - min;
                
                for (i = 0; i < n; i++) // <= to draw final tick
                {
                    _cachedTicks.push((i - min) / alen);
                }
            }
            else
            {
                _cachedMinorTicks = [];
                
                n = _categoryValues.length;
                min = -_padding;
                max = n - 1 + _padding;
                alen = max - min;
                
                var start:Number = _padding < 0.5 ? 0.5 : -0.5;
                var end:Number = _padding < 0.5 ? n - 1.5 : n - 0.5;
                
                for (i = start; i <= end; i += 1)
                {
                    _cachedTicks.push((i - min) / alen);
                }
            }
        }

        return _cachedTicks;
    }
    
    /**
     *  @private
     */
    private function invalidateCategories():void
    {
        _labelSet = null;
        _cachedMinorTicks = null;
        _cachedTicks = null;

        dispatchEvent(new Event("mappingChange"));
        dispatchEvent(new Event("axisChange"));
    }
    
    /**
     *  @private
     */
    mx_internal function getCategoryValues():Array /* of Object */
    {
        return _categoryValues;
    }
    
    //--------------------------------------------------------------------------
    //
    //  Event handlers
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     */
    private function collectionChangeHandler(event:CollectionEvent = null):void
    {
        if (event && event.kind == CollectionEventKind.RESET)
            _cursor = _dataProvider.createCursor();

        invalidateCategories();
    }
    
}

}
