////////////////////////////////////////////////////////////////////////////////
//
//  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.controls
{

import flash.display.DisplayObject;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.text.TextLineMetrics;
import flash.ui.Keyboard;
import flash.utils.describeType;
import flash.utils.getQualifiedClassName;

import mx.core.IFlexDisplayObject;
import mx.core.IFlexModuleFactory;
import mx.core.IFontContextComponent;
import mx.core.IUITextField;
import mx.core.UIComponent;
import mx.core.UITextField;
import mx.core.mx_internal;
import mx.events.CalendarLayoutChangeEvent;
import mx.events.DateChooserEvent;
import mx.events.DateChooserEventDetail;
import mx.managers.IFocusManagerComponent;
import mx.skins.halo.DateChooserIndicator;
import mx.styles.ISimpleStyleClient;

use namespace mx_internal;

//--------------------------------------
//  Styles
//--------------------------------------

include "../styles/metadata/GapStyles.as"
include "../styles/metadata/LeadingStyle.as"
include "../styles/metadata/PaddingStyles.as"
include "../styles/metadata/TextStyles.as"

/**
 *  Number of pixels between the component's top border
 *  and the top edge of its content area.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="paddingTop", type="Number", format="Length", inherit="no")]

/**
 *  Number of pixels between the component's bottom border
 *  and the bottom edge of its content area.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="paddingBottom", type="Number", format="Length", inherit="no")]

/**
 *  Name of the skin for the <code>rollOverIndicator</code>.
 *  It can be customized to some other shape other than rectangular.
 *  If you want to change just the color,
 *  use the <code>rollOverColor</code> instead.
 *  The default value is the DateChooserRollOverIndicator class.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="rollOverIndicatorSkin", type="Class", inherit="no")]

/**
 *  Name of the skin for <code>selectionIndicator</code>.
 *  It can customized to some other shape other than rectangular.
 *  If one just needs to change color,
 *  use the <code>selectionColor</code> instead.
 *  The default value is the DateChooserSelectionIndicator class.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="selectionIndicatorSkin", type="Class", inherit="no")]

/**
 *  Color of the background of today's date.
 *  The default value is <code>0x818181</code>.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="todayColor", type="uint", format="Color", inherit="yes")]

/**
 *  Name of the skin for <code>todayIndicator</code> style property. It can be customized
 *  to some other shape other than rectangular. If you
 *  want to change just the color, use the <code>todayColor</code> style property instead.
 *  The default value is the DateChooserTodayIndicator class.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="todayIndicatorSkin", type="Class", inherit="no")]

/**
 *  Name of the style sheet definition to configure the appearence of the current day's
 *  numeric text, which is highlighted
 *  in the control when the <code>showToday</code> property is <code>true</code>.
 *  Specify a "color" style to change the font color.
 *  If omitted, the current day text inherits
 *  the text styles of the control.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="todayStyleName", type="String", inherit="no")]

/**
 *  Name of the style sheet definition to configure the weekday names of
 *  the control. If omitted, the weekday names inherit the text
 *  styles of the control.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="weekDayStyleName", type="String", inherit="no")]

//--------------------------------------
//  Other metadata
//--------------------------------------

[ExcludeClass]

[ResourceBundle("controls")]
    
/**
 *  @private
 *  The CalendarLayout class handles the layout of the date grid in a month.
 *  CalendarLayout can be extended to develop DateControls with
 *  single month display control or side-by-side month displays.
 *
 *  @see mx.styles.StyleManager
 */
public class CalendarLayout extends UIComponent
                            implements IFocusManagerComponent, IFontContextComponent
{
    include "../core/Version.as";

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

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

        addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
        addEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
        addEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
    }
	
	private static const START_END:int = 1;
	private static const START_ONLY:int = 2;
	private static const END_ONLY:int = 3;
	private static const SINGLE_DATE:int = 4;

    //--------------------------------------------------------------------------
    //
    //  Variables
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     */
    private var todayRow:int = -1;

    /**
     *  @private
     */
    private var todayColumn:int = -1;

    /**
     *  @private
     */
    private var enabledDaysInMonth:Array = [];

    /**
     *  @private
     */
    private var disabledRangeMode:Array;

    /**
     *  @private
     */
    private var cellHeight:Number = 14;

    /**
     *  @private
     */
    private var cellWidth:Number = 14;

    /**
     *  @private
     */
    private var yOffset:Number = -1;

    /**
     *  @private
     */
    mx_internal var dayBlocksArray:Array = [];

    /**
     *  @private
     */
    private var disabledArrays:Array = []; // An Array of Arrays

    /**
     *  @private
     */
    private var todaysLabelReference:IUITextField = null;

    /**
     *  @private
     */
    private var selectedMonthYearChanged:Boolean = false;

    /**
     *  @private
     */
    private var todayIndicator:IFlexDisplayObject;

    /**
     *  @private
     */
    private var selectionIndicator:Array = [];

    /**
     *  @private
     */
    private var rollOverIndicator:IFlexDisplayObject;

    /**
     *  @private
     */
    private var selectedRangeCount:int = 0;

    /**
     *  @private
     */
    private var lastSelectedDate:Date;

    /**
     *  @private
     */
    private var rangeStartDate:Date = null;

    /**
     *  @private
     */
    mx_internal var selRangeMode:int = START_END;

    //--------------------------------------------------------------------------
    //
    //  Overridden properties
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    //  enabled
    //----------------------------------

    /**
     *  @private
     *  Storage for the displayedYear property.
     */
    private var _enabled:Boolean = true;

    /**
     *  @private
     */
    private var enabledChanged:Boolean = false;

    [Inspectable(category="General", defaultValue="true")]

    /**
     *  @private
     */
    override public function get enabled():Boolean
    {
        return _enabled;
    }

    /**
     *  @private
     */
    override public function set enabled(value:Boolean):void
    {
        super.enabled = value;

        _enabled = value;
        enabledChanged = true;

        invalidateProperties();
    }

    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    //  allowDisjointSelection
    //----------------------------------

    /**
     *  @private
     *  Storage for the allowDisjointSelection property.
     */
    private var _allowDisjointSelection:Boolean = true;

    [Inspectable(category="General", defaultValue="true")]

    /**
     *  @private
     */
    public function get allowDisjointSelection():Boolean
    {
        return _allowDisjointSelection;
    }

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

    //----------------------------------
    //  allowMultipleSelection
    //----------------------------------

    /**
     *  @private
     *  Storage for the allowMultipleSelection property.
     */
    private var _allowMultipleSelection:Boolean = false;

    [Inspectable(category="General", defaultValue="false")]

    /**
     *  @private
     */
    public function get allowMultipleSelection():Boolean
    {
        return _allowMultipleSelection;
    }

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

    //----------------------------------
    //  dayNames
    //----------------------------------

    /**
     *  @private
     *  Storage for the dayNames property.
     */
    private var _dayNames:Array;

    /**
     *  @private
     */
    private var dayNamesChanged:Boolean = false;

    /**
     *  @private
     */
    private var dayNamesOverride:Array;
    
    [Inspectable(category="Other", arrayType="String", defaultValue="null")]

    /**
     *  @private
     */
    public function get dayNames():Array
    {
        return _dayNames;
    }

    /**
     *  @private
     */
    public function set dayNames(value:Array):void
    {
        dayNamesOverride = value;

        _dayNames = value != null ?
                    value :
                    resourceManager.getStringArray(
                        "controls", "dayNamesShortest");

        // _dayNames will be null if there are no resources.
        _dayNames = _dayNames ? _dayNames.slice(0) : null;

        dayNamesChanged = true;

        invalidateProperties();
        invalidateSize();
        invalidateDisplayList();
    }

    //----------------------------------
    //  disabledDays
    //----------------------------------

    /**
     *  @private
     *  Storage for the disabledDays property.
     */
    private var _disabledDays:Array = [];

    [Inspectable(category="General", arrayType="int")]

    /**
     *  @private
     */
    public function get disabledDays():Array
    {
        var result:Array = [];
        
        for (var i:int = 0, k:int = 0; i < _disabledDays.length; i++)
        {
            if (_disabledDays[i] >= 0 && _disabledDays[i] <= 6)
            {
                result[k] = _disabledDays[i];
                k++;
            }
        }

        return result;
    }

    /**
     *  @private
     */
    public function set disabledDays(value:Array):void
    {
        _disabledDays = value.slice(0);
        selectedMonthYearChanged = true;
        
        invalidateProperties();
        
        // This removes the disabled ranges/days from the selected ranges.
        var selRange:Array = selectedRanges;
    }

    //----------------------------------
    //  disabledRanges
    //----------------------------------

    /**
     *  @private
     *  Storage for the disabledRanges property.
     */
    private var _disabledRanges:Array = [];

    [Inspectable(category="General", arrayType="Object")]

    /**
     *  @private
     */
    public function get disabledRanges():Array
    {
        return _disabledRanges.slice(0);
    }

    /**
     *  @private
     */
    public function set disabledRanges(value:Array):void
    {
        _disabledRanges = value.slice(0);
        disabledRangeMode = [];

        for (var i:int = 0; i < _disabledRanges.length; i++)
        {
            if (_disabledRanges[i] is Date)
            {
                disabledRangeMode[i] = SINGLE_DATE;
                _disabledRanges[i] = new Date(value[i].getFullYear(),
                                              value[i].getMonth(),
                                              value[i].getDate());
            }
            else if (_disabledRanges[i] is Object)
            {
                _disabledRanges[i] = {};
                _disabledRanges[i] = value[i];

                if (!_disabledRanges[i].rangeStart &&
                    _disabledRanges[i].rangeEnd)
                {
                    disabledRangeMode[i] = END_ONLY;
                }
                else if (_disabledRanges[i].rangeStart &&
                        !_disabledRanges[i].rangeEnd)
                {
                    disabledRangeMode[i] = START_ONLY;
                }
                else if (_disabledRanges[i].rangeStart &&
                         _disabledRanges[i].rangeEnd)
                {
                    disabledRangeMode[i] = START_END;
                }
            }
        }

        selectedMonthYearChanged = true;

        invalidateProperties();

        // To remove the disabled ranges/days from the selected ranges.
        var selRange:Array=selectedRanges;
    }

    //----------------------------------
    //  displayedMonth
    //----------------------------------

    /**
     *  @private
     *  Storage for the displayedMonth property.
     */
    private var _displayedMonth:int = (new Date()).getMonth();

    /**
     *  @private
     *  Holds the proposed value of displayedMonth until it can be verified in commitProperties
     */
    private var _proposedDisplayedMonth:int = -1;

    [Inspectable(category="General", defaultValue="0")]

    /**
     *  @private
     */
    public function get displayedMonth():int
    {
        return _proposedDisplayedMonth == -1 ? _displayedMonth : _proposedDisplayedMonth;
    }

    /**
     *  @private
     */
    public function set displayedMonth(value:int):void
    {
        if (value < 0 || value > 11)
            return;

        if (value == _proposedDisplayedMonth)
            return;

        _proposedDisplayedMonth = value;
        selectedMonthYearChanged = true;
        invalidateProperties();
    }

    //----------------------------------
    //  displayedYear
    //----------------------------------

    /**
     *  @private
     *  Storage for the displayedYear property.
     */
    private var _displayedYear:int = (new Date()).getFullYear();

    /**
     *  @private
     *  Holds the proposed value of displayedYear until it can be verified in commitProperties
     */
    private var _proposedDisplayedYear:int = -1;

    [Inspectable(category="General", defaultValue="2014")]

    /**
     *  @private
     */
    public function get displayedYear():int
    {
        return _proposedDisplayedYear == -1 ? _displayedYear : _proposedDisplayedYear;
    }

    /**
     *  @private
     */
    public function set displayedYear(value:int):void
    {
        if (value <= 0)
            return;

        if (value == _displayedYear)
            return;
            
        _proposedDisplayedYear = value;
        selectedMonthYearChanged = true;
        invalidateProperties();
    }

    //----------------------------------
    //  firstDayOfWeek
    //----------------------------------

    /**
     *  @private
     *  Storage for the firstDayOfWeek property.
     */
    private var _firstDayOfWeek:int = 0; // Sunday

    [Inspectable(category="General", defaultValue="0")]

    /**
     *  @private
     */
    public function get firstDayOfWeek():int
    {
        return _firstDayOfWeek;
    }

    /**
     *  @private
     */
    public function set firstDayOfWeek(value:int):void
    {
        if (value < 0 || value > 6)
            return;

        if (value == _firstDayOfWeek)
            return;

        _firstDayOfWeek = value;
        dayNamesChanged = true;
        selectedMonthYearChanged = true;
        
        invalidateProperties();
    }

    //----------------------------------
    //  fontContext
    //----------------------------------
    
    /**
     *  @private
     */
    public function get fontContext():IFlexModuleFactory
    {
        return moduleFactory;
    }

    /**
     *  @private
     */
    public function set fontContext(moduleFactory:IFlexModuleFactory):void
    {
        this.moduleFactory = moduleFactory;
    }
    
    //----------------------------------
    //  selectableRange
    //----------------------------------

    /**
     *  @private
     *  Storage for the selectableRange property.
     */
    private var _selectableRange:Object = null;

    [Inspectable(category="General")]

    /**
     *  @private
     */
    public function get selectableRange():Object
    {
        return _selectableRange;
    }

    /**
     *  @private
     */
    public function set selectableRange(value:Object):void
    {
        if (!value)
        {
            _selectableRange = null;
            selectedMonthYearChanged = true;
            invalidateProperties();
            return;
        }

        var todaysDate:Date = new Date();
        var todaysMonth:int = todaysDate.getMonth();
        var todaysYear:int = todaysDate.getFullYear();
        var callMonth:int;
        var callYear:int;
        
        if (value is Date)
        {
            selRangeMode = SINGLE_DATE;
            
            _selectableRange = new Date(value.getFullYear(),
                                        value.getMonth(),
                                        value.getDate());
            
            callMonth  = value.getMonth();
            callYear = value.getFullYear();
        }
        else if (value is Object)
        {
            _selectableRange = {};

            if (!value.rangeStart && value.rangeEnd)
            {
                selRangeMode = END_ONLY;
                _selectableRange.rangeEnd = value.rangeEnd;
                
                if (todaysYear <= _selectableRange.rangeEnd.getFullYear())
                {
                    if (todaysMonth >= _selectableRange.rangeEnd.getMonth())
                    {
                        callMonth = _selectableRange.rangeEnd.getMonth();
                        callYear = _selectableRange.rangeEnd.getFullYear();
                    }
                    else if (todaysMonth <=
                             _selectableRange.rangeEnd.getMonth())
                    {
                        callMonth = todaysMonth;
                        callYear = todaysYear;
                    }
                }
                else if (todaysYear > _selectableRange.rangeEnd.getFullYear())
                {
                    callMonth = _selectableRange.rangeEnd.getMonth();
                    callYear = _selectableRange.rangeEnd.getFullYear();
                }

            }
            else if (!value.rangeEnd && value.rangeStart)
            {
                selRangeMode = START_ONLY;
                _selectableRange.rangeStart = value.rangeStart;
                
                if (todaysYear >= _selectableRange.rangeStart.getFullYear())
                {
                    if (todaysMonth <= _selectableRange.rangeStart.getMonth())
                    {
                        callMonth = _selectableRange.rangeStart.getMonth();
                        callYear = _selectableRange.rangeStart.getFullYear();
                    }
                    else if (todaysMonth >=
                             _selectableRange.rangeStart.getMonth())
                    {
                        callMonth = todaysMonth;
                        callYear = todaysYear;
                    }
                }
                else if (todaysYear < _selectableRange.rangeStart.getFullYear())
                {
                    callMonth = _selectableRange.rangeStart.getMonth();
                    callYear = _selectableRange.rangeStart.getFullYear();
                }
            }
            else if (value.rangeStart && value.rangeEnd)
            {
                selRangeMode = START_END;
                _selectableRange.rangeStart = value.rangeStart;
                _selectableRange.rangeEnd = value.rangeEnd;
                
                if (todaysDate >= _selectableRange.rangeStart &&
                    todaysDate <= _selectableRange.rangeEnd)
                {
                    callMonth = todaysMonth;
                    callYear = todaysYear;
                }
                else if (todaysDate < _selectableRange.rangeStart)
                {
                    callMonth = _selectableRange.rangeStart.getMonth();
                    callYear = _selectableRange.rangeStart.getFullYear();
                }
                else if (todaysDate > _selectableRange.rangeEnd)
                {
                    callMonth = _selectableRange.rangeEnd.getMonth();
                    callYear = _selectableRange.rangeEnd.getFullYear();
                }
            }
        }

        _displayedMonth = callMonth;
        _displayedYear = callYear;

        selectedMonthYearChanged = true;
        invalidateProperties();
        
        // This removes the non-selectable ranges from the selected ranges.
        var selRange:Array = selectedRanges;
    }

    //----------------------------------
    //  selectedRanges
    //----------------------------------

    /**
     *  @private
     *  Storage for the selectableRange property.
     */
    private var _selectedRanges:Array = [];

    [Inspectable(category="General", arrayType="Object")]

    /**
     *  @private
     */
    public function get selectedRanges():Array
    {
        if (_selectableRange)
        {		
            switch (selRangeMode)
            {
                case START_END:
                {
                    removeRangeFromSelection(null, addSubtractDays(_selectableRange.rangeStart, -1));
                    removeRangeFromSelection(addSubtractDays(_selectableRange.rangeEnd, +1), null);
                    break;
                }

                case START_ONLY:
                case END_ONLY:
                {
                    removeRangeFromSelection(addSubtractDays(_selectableRange.rangeStart, -1),
												addSubtractDays(_selectableRange.rangeEnd, +1));
                    break;
                }

                case SINGLE_DATE:
                {
                    removeDayFromSelection(_selectableRange as Date);
                    break;
                }
            }
        }

        var i:int;
        
        for (i = 0; i < _disabledRanges.length; i++)
        {
            switch (disabledRangeMode[i])
            {
                case START_END:
                case START_ONLY:
                case END_ONLY:
                {
                    removeRangeFromSelection(_disabledRanges[i].rangeStart, _disabledRanges[i].rangeEnd);
                    break;
                }

                case SINGLE_DATE:
                {
                    removeDayFromSelection(_disabledRanges[i]);
                    break;
                }
            }
        }

        if (_disabledDays.length > 0 && selectedRangeCount)
        {
            var minDate:Date = _selectedRanges[0].rangeStart;
            var maxDate:Date = _selectedRanges[0].rangeEnd;

            for (i = 1; i < selectedRangeCount; i++)
            {
                if (minDate > _selectedRanges[i].rangeStart)
                    minDate = _selectedRanges[i].rangeStart;

                if (maxDate < _selectedRanges[i].rangeEnd)
                    maxDate = _selectedRanges[i].rangeEnd;
            }

            for (i = 0; i < _disabledDays.length; i++)
            {
                var tempDate:Date = minDate;

                var dayOffset:int = _disabledDays[i] - tempDate.getDay();

                if (dayOffset < 0)
                    dayOffset += 7;

                tempDate = addSubtractDays(tempDate, dayOffset);

                while (tempDate < maxDate)
                {
                    removeDayFromSelection(tempDate);
                    tempDate = addSubtractDays(tempDate, 7);
                }
            }
        }

        _selectedRanges.length = selectedRangeCount;
        return _selectedRanges;
    }

    /**
     *  @private
     */
    public function set selectedRanges(value:Array):void
    {
        _selectedRanges = value;

        selectedRangeCount = _selectedRanges.length;

        setSelectedIndicators();
    }

    //----------------------------------
    //  showToday
    //----------------------------------

    /**
     *  @private
     *  Storage for the showToday property.
     */
    private var _showToday:Boolean = true;

    [Inspectable(category="General", defaultValue="true")]

    /**
     *  @private
     */
    public function get showToday():Boolean
    {
        return _showToday;
    }

    /**
     *  @private
     */
    public function set showToday(value:Boolean):void
    {
        if (_showToday != value)
            _showToday = value;

        selectedMonthYearChanged = true;

        invalidateProperties();
    }

    //----------------------------------
    //  selectedDate
    //----------------------------------

    [Inspectable(category="General", defaultValue="null")]

    /**
     *  @private
     */
    public function get selectedDate():Date
    {
        return selectedRangeCount ? _selectedRanges[0].rangeStart : null;
    }

    /**
     *  @private
     */
    public function set selectedDate(value:Date):void
    {
        selectedRangeCount = 0;

        if (value && !checkDateIsDisabled(value))
        {
            addToSelected(value);
            
            _displayedMonth = value.getMonth();
            _displayedYear = value.getFullYear();
            selectedMonthYearChanged = true;
            
            invalidateProperties();
        }
        else
        {
            setSelectedIndicators();
        }
    }

    //--------------------------------------------------------------------------
    //
    //  Overridden methods
    //
    //--------------------------------------------------------------------------

    /*

    A note about DayBlocks:

    dayBlock0..dayBlock6 are skins for the 7 grid columns.
    They are dynamically created instances of the "DayBlock" symbol.
    Three additional properties are set when each dayBlock is created
    in createChildren():

        columnIndex:int (0-6)
            keeps track of where this dayBlock is in the grid

        selectedArray:Array
            7 elements, one for each row
            selectedArray[rowIndex] is true
                if that row in the dayBlock is selected

        disabledArray:Array
            7 elements, one for each row
            disabledArray[rowIndex] is true
                if that row in the dayBlock is disabled

    Additional properties are created dynamically to hold the skins
    for selected and disabled rows in the dayBlock:

        selectedSkin0..selectedSkin6

        disabledSkin0..disabledSkin6

    */

    /**
     *  @private
     *  Everything that gets initially created now exists.
     *  Some things, such as the selection skins and disabled skins,
     *  are created later as they are needed.
     *  Set the "S", "M", etc. labels in the first row.
     *  
     *  Set the day-number labels ("1".."31") in the other rows.
     *  This method also displays the selection skins,
     *  the disabled skins, and the "today" indicator.
     */
    override protected function createChildren():void
    {
        super.createChildren();

        var labelPosition:Number = 0;

        createDayLabels(-1);
        createTodayIndicator(0);
        
        if (!rollOverIndicator)
        {
            var rollOverIndicatorClass:Class = getStyle("rollOverIndicatorSkin");
            if (!rollOverIndicatorClass)
                rollOverIndicatorClass = DateChooserIndicator;
            rollOverIndicator = IFlexDisplayObject(new rollOverIndicatorClass());
            // too lazy to make an interface for this.
            if (isDateChooserIndicator(rollOverIndicator))
                Object(rollOverIndicator).indicatorColor = "rollOverColor";
            if (rollOverIndicator is ISimpleStyleClient)
                ISimpleStyleClient(rollOverIndicator).styleName = this;
            addChildAt(DisplayObject(rollOverIndicator), 0);
            rollOverIndicator.visible = false;
        }

        // Wait for all of the properties to be set before calling setSelectedMonthAndYear
        dayNamesChanged = true;
        selectedMonthYearChanged = true;
    }

    /**
     *  @private
     */
    override protected function commitProperties():void
    {
        super.commitProperties();

        if (hasFontContextChanged() && todayIndicator != null)
        {
            // Re-create the children so we can display
            // the embedded font from the new font context.
            removeSelectionIndicators();
            
            var childIndex:int = getChildIndex(DisplayObject(todayIndicator));
            removeTodayIndicator();
            createTodayIndicator(childIndex);

            childIndex = getChildIndex(dayBlocksArray[0][0]);
            removeDayLabels();
            createDayLabels(childIndex);
            
            enabledChanged = true;
            dayNamesChanged = true;
            selectedMonthYearChanged = true;
        }

        if (enabledChanged)
        {
            enabledChanged = false;

            for (var o:int = 0; o < 7; o++)
            {
                for (var r:int = 0; r < 7; r++)
                {
                    dayBlocksArray[o][r].enabled = _enabled;
                    disabledArrays[o][r] = _enabled;
                }
            }

            if (!_enabled)
            {

                if (todayIndicator)
                    todayIndicator.alpha = 0.3;

                // Remove the mouse event listeners
                removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
                removeEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
                removeEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
                removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
            }
            else
            {
                if (todayIndicator)
                    todayIndicator.alpha = 1.0;

                selectedMonthYearChanged = true;

                // Restore the mouse event listeners
                addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
                addEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
                addEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
                addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
            }
        }

        if (dayNamesChanged)
        {
            dayNamesChanged = false;

            drawDayNames();
        }

        if (selectedMonthYearChanged)
        {
            selectedMonthYearChanged = false;

            var proposedDate:Date = 
                new Date(_proposedDisplayedYear == -1 ? _displayedYear : _proposedDisplayedYear,
                         _proposedDisplayedMonth == -1 ? _displayedMonth : _proposedDisplayedMonth);
                         
            if (isDateInRange(proposedDate, _selectableRange, selRangeMode, true))
            {            
                setSelectedMonthAndYear();
            }   
            
            _proposedDisplayedYear = -1;
            _proposedDisplayedMonth = -1;
        }
    }

    /**
     *  @private
     */
    override protected function measure():void
    {
        super.measure();

        var verticalGap:Number = getStyle("verticalGap");
        var horizontalGap:Number = getStyle("horizontalGap");

        var paddingLeft:Number = getStyle("paddingLeft");
        var paddingRight:Number = getStyle("paddingRight");
        var paddingBottom:Number = getStyle("paddingBottom");
        var paddingTop:Number = getStyle("paddingTop");

        var lineMetrics:TextLineMetrics;

        cellWidth = 0;
        cellHeight = 0;

        for (var dayOfWeek:int = 0; dayOfWeek < 7; dayOfWeek++)
        {
            // dayNames will be null if there are no resources.
            var dayName:String = dayNames ? dayNames[dayOfWeek] : "";
            lineMetrics = measureText(dayName);
            if (lineMetrics.width > cellWidth)
                cellWidth = lineMetrics.width;
            if (lineMetrics.height > cellHeight)
                cellHeight = lineMetrics.height;
        }

        lineMetrics = measureText("30");

        if (lineMetrics.width > cellWidth)
            cellWidth = lineMetrics.width;

        if (lineMetrics.height > cellHeight)
            cellHeight = lineMetrics.height;

        measuredWidth = paddingLeft + horizontalGap * 6 +
                        cellWidth * 7 + paddingRight;
        measuredHeight = verticalGap * 6 + cellHeight * 7 +
                         paddingBottom + paddingTop;
        measuredMinWidth = cellWidth * 7;
        measuredMinHeight = cellHeight * 7;
    }

    /**
     *  @private
     */
    override protected function updateDisplayList(unscaledWidth:Number,
                                                  unscaledHeight:Number):void
    {
        super.updateDisplayList(unscaledWidth, unscaledHeight);

        //var verticalGap:Number = getStyle("verticalGap");
        //var horizontalGap:Number = getStyle("horizontalGap");

        var paddingLeft:Number = getStyle("paddingLeft");
        var paddingRight:Number = getStyle("paddingRight");
        var paddingBottom:Number = getStyle("paddingBottom");
        var paddingTop:Number = getStyle("paddingTop");

        var blockX:Number = paddingLeft;

        // Bug 134794, clip height/width so that RTE's are not thrown
        cellWidth = Math.max((unscaledWidth - (paddingLeft + paddingRight))/7, 4);
        cellHeight = Math.max((unscaledHeight - paddingBottom)/7, 4);

        var labelPosition:Number = paddingTop;

        rollOverIndicator.setActualSize(cellWidth, cellHeight);
        todayIndicator.setActualSize(cellWidth, cellHeight);

        for (var columnIndex:int = 0; columnIndex < 7; columnIndex++)
        {
            // Remember the height of the cells if not set by user.
            // Create the 7 labels within each DayBlock.
            // The first row in each column displays a day name string, such as "Sun".
            // The other six rows displays day numbers in the range 1-31.

            for (var rowIndex:int = 0; rowIndex < 7; rowIndex++)
            {
                var label:IUITextField = dayBlocksArray[columnIndex][rowIndex];
                if (rowIndex == 0)
                    labelPosition = paddingTop;
                else
                    labelPosition += cellHeight;

                label.setActualSize(cellWidth, cellHeight);
                label.move(blockX, labelPosition);

                if (selectionIndicator[columnIndex][rowIndex])
                {
                    selectionIndicator[columnIndex][rowIndex].setActualSize(cellWidth, cellHeight);
                    selectionIndicator[columnIndex][rowIndex].move(blockX, labelPosition + yOffset);
                }
               //label.width = cellWidth;
                //label.height = cellHeight;
                //label.x = blockX;
                //label.y = labelPosition;
            }

            blockX += cellWidth;
        }

        drawDayNames();
        setSelectedMonthAndYear();
    }

    /**
     *  @private
     */
    override public function styleChanged(styleProp:String):void
    {
        var allStyles:Boolean = !styleProp || styleProp == "styleName";

        if (allStyles || styleProp == "todayStyleName")
        {
            selectedMonthYearChanged = true;
            invalidateProperties();
        }

        if (allStyles || styleProp == "weekDayStyleName")
        {
            var weekDayStyleName:Object = getStyle("weekDayStyleName");
            if (!weekDayStyleName)
                weekDayStyleName = this;

            if (dayBlocksArray)
            {
                for (var i:int = 0; i < 7; i++)
                {
                    // Set the styleName on the top row of day name labels
                    if (dayBlocksArray[i] && dayBlocksArray[i][0])
                        dayBlocksArray[i][0].styleName = weekDayStyleName;
                }
            }
        }

        super.styleChanged(styleProp);
    }

    /**
     *  @private
     */
    override protected function resourcesChanged():void
    {
        super.resourcesChanged();

        dayNames = dayNamesOverride;
    }

    //--------------------------------------------------------------------------
    //
    //  Methods
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     *  Creates the day labels and adds them as children of this component.
     * 
     *  @param childIndex The index of where to add the children.
     *  If -1, the text fields are appended to the end of the list.
     */
    mx_internal function createDayLabels(childIndex:int):void
    {
        var weekDayStyleName:Object = getStyle("weekDayStyleName");

        // Remember the height of the cells if not set by user.
        // Create the 7 labels within each DayBlock.
        // The first row in each column displays a day name string,
        // such as "Sun".
        // The other six rows displays day numbers in the range 1-31.

        // Calendar days
        for (var columnIndex:int = 0; columnIndex < 7; columnIndex++)
        {
            dayBlocksArray[columnIndex] = [];
            selectionIndicator[columnIndex] = [];

            for (var rowIndex:int = 0; rowIndex < 7; rowIndex++)
            {
                var label:IUITextField =
                dayBlocksArray[columnIndex][rowIndex] =
                    IUITextField(createInFontContext(UITextField));
                
                label.selectable = false;
                label.ignorePadding = true;
    
                if (childIndex == -1)
                    addChild(DisplayObject(label));         
                else
                    addChildAt(DisplayObject(label), childIndex++);
    
                if (rowIndex == 0)
                {
                    label.styleName = weekDayStyleName ?
                                      weekDayStyleName :
                                      this;
                }
                else
                {
                    label.styleName = this;
                }
            }

            disabledArrays[columnIndex] = new Array(7);
        }
    }

    /**
     *  @private
     *  Removes the day labels from this component.
     */
    mx_internal function removeDayLabels():void
    {
       for (var columnIndex:int = 0; columnIndex < 7; columnIndex++)
        {
            for (var rowIndex:int = 0; rowIndex < 7; rowIndex++)
            {
                removeChild(dayBlocksArray[columnIndex][rowIndex]);
                dayBlocksArray[columnIndex][rowIndex] = null;
            }
        }
    }
    
    /**
     *  @private
     *  @param childIndex The index of where to add the child.
     */
    mx_internal function createTodayIndicator(childIndex:int):void
    {
        if (!todayIndicator)
        {
            var todayIndicatorClass:Class = getStyle("todayIndicatorSkin");
            if (!todayIndicatorClass)
                todayIndicatorClass = DateChooserIndicator;
            todayIndicator = IFlexDisplayObject(new todayIndicatorClass());
            
            if (isDateChooserIndicator(todayIndicator))
            {
                Object(todayIndicator).indicatorColor =
                    "todayColor";
            }
            if (todayIndicator is ISimpleStyleClient)
                ISimpleStyleClient(todayIndicator).styleName = this;
            
            addChildAt(DisplayObject(todayIndicator), childIndex);
            
            todayIndicator.visible = false;
        }
    }

    /**
     *  @private
     */
    mx_internal function removeTodayIndicator():void
    {
        if (todayIndicator)
        {
            removeChild(DisplayObject(todayIndicator));
            todayIndicator = null;
        }       
    }

    /**
     *  @private
     */
    mx_internal function drawDayNames():void
    {
        for (var columnIndex:int = 0; columnIndex < 7; columnIndex++)
        {
            var dayOfWeek:int = (columnIndex + firstDayOfWeek) % 7;
            // dayNames will be null if there are no resources.
            var dayName:String = dayNames ? dayNames[dayOfWeek] : "";
            dayBlocksArray[columnIndex][0].text = dayName;
        }
    }

    /**
     *  @private
     */
    mx_internal function setSelectedMonthAndYear(monthVal:int = -1, yearVal:int = -1):void
    {
        // This lengthy method updates the UI to display a specified month
        // and year. In particular, it updates the day numbers (1-31) in the grid.

        // It does NOT update the day names ("Sun", "Mon", etc.),
        // since these do not change when the month and year change.
        //
        // It also takes care of displaying days that are disabled or selected.
        // Instances of the skins cal_monthDayDisabled (for disabled days) and
        // cal_monthDaySelected (for selected days) get created as they
        // are required, to minimize initialization time.

        var dayNumber:int; // 1 - 31
        var columnIndex:int; // 0 - 6
        var rowIndex:int; // 1 - 6
        var i:int;
        var displayTodayInCurrentMonth:Boolean = false;
        var displayDate:Date = null;


        // When another method needs to redraw the UI without changing the
        // currently selected month and year (because the firstDayOfWeek
        // property changed, for example) it calls setSelectedMonthAndYear()
        // with no arguments. Therefore we need to handle undefined arguments.
        var newMonth:int = monthVal == -1 ? displayedMonth : monthVal;
        var newYear:int = yearVal == -1 ? displayedYear : yearVal;

        // Determine where in the grid the 1st of the month should appear,
        // how many days are in the month, and today's date.

        enabledDaysInMonth = [];
        var offset:int = getOffsetOfMonth(newYear, newMonth);
        var daysInMonth:int = getNumberOfDaysInMonth(newYear, newMonth);

        // Determine whether this month contains today.
        var today:Date = new Date();
        var currentMonthContainsToday:Boolean = (today.getFullYear() == newYear && today.getMonth() == newMonth);

        // Set up the days (if any) in row 1 that come from the previous month.
        var previousMonth:int = Math.max(newMonth - 1,0);
        var previousMonthDate:Date = new Date(newYear, previousMonth, 1);
        dayNumber = getNumberOfDaysInMonth(previousMonthDate.getFullYear(), previousMonthDate.getMonth());
        rowIndex = 1;

        for (columnIndex = 0; columnIndex < offset; columnIndex++)
        {
            dayBlocksArray[columnIndex][rowIndex].text = "";

            // Disable the day.
            disabledArrays[columnIndex][rowIndex] = true;

            removeSelectionIndicator(columnIndex,rowIndex);
        }

        // Set up the days of the new month.
        for (dayNumber = 1; dayNumber <= daysInMonth; dayNumber++)
        {
            var cellDate:Date = new Date(newYear, newMonth, dayNumber);
            i = offset + dayNumber - 1;
            columnIndex = i % 7;
            rowIndex = 1 + Math.floor(i / 7);

            var todayLabel:IUITextField = dayBlocksArray[columnIndex][rowIndex];//this["dayBlock" + columnIndex+"label" + rowIndex];
            todayLabel.text = dayNumber.toString();
            // Enable the day.

            if (_enabled)
            {
                disabledArrays[columnIndex][rowIndex] = false;
                todayLabel.enabled = true;
            }

            if (!todayLabel.styleName)
                todayLabel.styleName = this;

            // Some of these days may be selected.
            // One of these days may be today's date.
            if (currentMonthContainsToday && (cellDate.getDate() == today.getDate()) && _showToday)
            {
                todayRow = rowIndex;
                todayColumn = columnIndex;
                displayTodayInCurrentMonth = true;

                todayIndicator.visible = _showToday;
                todayLabel.styleName = getStyle("todayStyleName");

                todayIndicator.move(todayLabel.x, todayLabel.y + yOffset); // Don't trigger layout
                todaysLabelReference = todayLabel;

            }
            else
            {
                if (!displayTodayInCurrentMonth)
                {
                    if (todaysLabelReference)
                    {
                        todaysLabelReference.styleName = this;
                        //todaysLabelReference.styleName = this;
                    }
                    todayIndicator.visible = false;
                }
            }

            var cellString:String;

            // Selectable Range
            // set up the selectable Range: type: Object/ Date Object
            // Object Attrib: rangeStart[Date Object], rangeEnd[Date Object]
            // 1 :: if both attribs are defined
            // 2 :: If only rangeStart is defined: All dates after the specified date are enabled
            // 3 :: if only rangeEnd is defined: All dates before ths specified date are enabled
            // 4 :: If selectable Range param is a Date Object, then only that day has to be defined

            if (_selectableRange)
            {
                if (!isDateInRange(cellDate, _selectableRange, selRangeMode))
                {
                    todayLabel.enabled = false;
                    disabledArrays[columnIndex][rowIndex] = true;
                }
            }

            // Disabled Ranges
            // set up the disabledRanges: type: Array
            // Array can contain an Object || Date Object.
            // Attrib for Object: rangeStart[Date Object], rangeEnd[Date Object]
            // "start"::All dates after the specified date are disabled, including the startDate
            // "end"::All dates before ths specified date are disabled, including the end Date
            // "date"::Only that day has to be disabled
            // "normal"::range is disabled including the start and end date
            if (_disabledRanges.length > 0)
            {
                for (var dRanges:int = 0; dRanges < _disabledRanges.length; dRanges++)
                {
                    if (isDateInRange(cellDate, _disabledRanges[dRanges], disabledRangeMode[dRanges]))
                    {
                        todayLabel.enabled = false;
                        disabledArrays[columnIndex][rowIndex] = true;
                    }
                }
            }

            var valToPush:Object = {};
            if (todayLabel.enabled)
            {
                valToPush.name = todayLabel.name;
                valToPush.text = todayLabel.text;
                valToPush.x = todayLabel.x;
                valToPush.y = todayLabel.y;
            }
            enabledDaysInMonth.push(valToPush);
        }

        // Set up the days (if any) at the end of the grid
        // that come from the following month.
        dayNumber = 1;
        for (i = offset + daysInMonth; i < 42; i++)
        {
            columnIndex = i % 7;
            rowIndex = 1 + Math.floor(i / 7);

            dayBlocksArray[columnIndex][rowIndex].text = "";


            // Disable the day.
            disabledArrays[columnIndex][rowIndex] = true;
            removeSelectionIndicator(columnIndex,rowIndex);
        }

        if (_disabledDays.length>0)
        {
            for (i = 0; i < _disabledDays.length; i++)
            {
                if (_disabledDays[i] >= 0 && _disabledDays[i] <= 6 && _disabledDays[i] != -1)
                {
                    columnIndex = ((7 + _disabledDays[i] - _firstDayOfWeek) % 7);

                    for (rowIndex = 1; rowIndex < 7; rowIndex++)
                    {
                        // Disable the day.
                        disabledArrays[columnIndex][rowIndex] = true;
                        var tempCalcDate:Number = Number(dayBlocksArray[columnIndex][rowIndex].text);
                        var tempOffset:Number;
                        if (!isNaN(tempCalcDate))
                        {
                            tempOffset = offset + tempCalcDate % 7;
                            enabledDaysInMonth[tempCalcDate-1] = null;
                        }
                        dayBlocksArray[columnIndex][rowIndex].enabled = false;
                    }
                }
            }
        }

        _displayedMonth = newMonth;
        _displayedYear = newYear;
        displayDate = new Date(newYear, newMonth, 1);
        todayIndicator.alpha = (todaysLabelReference) ? ((todaysLabelReference.enabled == false) ? 0.3 : 1.0) : 1.0;
        setSelectedIndicators();
        invalidateDisplayList();
    }

    /**
     *  @private
     *  Called from setSelectedMonthAndYear() to get an Offset of the starting day of the month
     */
    mx_internal function getOffsetOfMonth(year:int, month:int):int
    {
        // Determine whether the 1st of the month is a Sunday, Monday, etc.
        // and then determine which column of the grid where it appears.
        var first:Date = new Date(year, month, 1);
        var offset:int = first.getDay() - _firstDayOfWeek;
        return offset < 0 ? offset + 7 : offset;
    }

    /**
     *  @private
     */
    mx_internal function getNumberOfDaysInMonth(year:int, month:int):int
    {
        // "Thirty days hath September..."

        var n:int;

        if (month == 1) // Feb
        {
            if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) // leap year
                n = 29;
            else
                n = 28;
        }

        else if (month == 3 || month == 5 || month == 8 || month == 10)
            n = 30;

        else
            n = 31;

        return n;
    }

    /**
     *  @private
     */
    mx_internal function stepDate(deltaY:int, deltaM:int, triggerEvent:Event = null):void
    {
        var oldYear:int = displayedYear;
        var oldMonth:int = displayedMonth;

        var newDate:Object = getNewIncrementDate(oldYear, oldMonth, deltaY, deltaM);

        var newYear:int = newDate.year;
        var newMonth:int = newDate.month;

        _displayedMonth = newMonth;
        _displayedYear = newYear;
        selectedMonthYearChanged = true;
        invalidateProperties();

        var event:DateChooserEvent = new DateChooserEvent(DateChooserEvent.SCROLL);
        event.triggerEvent = triggerEvent;
        if (newYear > oldYear)
            event.detail = DateChooserEventDetail.NEXT_YEAR;
        else if (newYear < oldYear)
            event.detail = DateChooserEventDetail.PREVIOUS_YEAR;
        else if (newMonth > oldMonth)
            event.detail = DateChooserEventDetail.NEXT_MONTH;
        else if (newMonth < oldMonth)
            event.detail = DateChooserEventDetail.PREVIOUS_MONTH;
        dispatchEvent(event);
    }
    
    /**
     *  @private Takes a year and a month as well as an increment year and month value
     *           and returns a new valid year/month.
     */
    static mx_internal function getNewIncrementDate(oldYear:int, oldMonth:int, deltaY:int, deltaM:int):Object
    {
        var newYear:int = oldYear + deltaY;
        var newMonth:int = oldMonth + deltaM;

        while (newMonth < 0)
        {
            newYear--;
            newMonth += 12;
        }

        while (newMonth > 11)
        {
            newYear++;
            newMonth -= 12;
        }

        return {month: newMonth, year: newYear};
    }

    /**
     *  @private
     */
    mx_internal function dispatchChangeEvent(triggerEvent:Event = null):void
    {
        var change:CalendarLayoutChangeEvent =
            new CalendarLayoutChangeEvent(CalendarLayoutChangeEvent.CHANGE);
        change.newDate = lastSelectedDate;
        change.triggerEvent = triggerEvent;
        dispatchEvent(change);
    }

    /**
     *  @private
     * 
     *  Returns true if the date is within the dates specified by the dateRange object. 
     */ 
    mx_internal function isDateInRange(value:Date, dateRange:Object, rangeMode:int, ignoreDay:Boolean = false):Boolean
    {
        var result:Boolean = true;
        
        if (dateRange)
        {
            if (ignoreDay)
            {
                var dateRangeCopy:Object = {};
                if (dateRange.rangeStart)
                {
                    var startDate:Date = dateRange.rangeStart;
                    dateRangeCopy.rangeStart = new Date(startDate.fullYear, startDate.month, 1);
                }
                if (dateRange.rangeEnd)
                {
                    var endDate:Date = dateRange.rangeEnd;
                    dateRangeCopy.rangeEnd = new Date(endDate.fullYear, endDate.month, getNumberOfDaysInMonth(endDate.fullYear, endDate.month));
                }
                dateRange = dateRangeCopy;
            }
            
            switch (rangeMode)
            {	
                case START_END:
                {
                    if (value < dateRange.rangeStart ||
                        value > dateRange.rangeEnd)
                    {
                        result = false;
                    }
                    break;
                }

                case START_ONLY:
                {
                    if (value < dateRange.rangeStart)
                        result = false;
                    break;
                }

                case END_ONLY:
                {
                    if (value > dateRange.rangeEnd)
                        result = false;
                    break;
                }

                case SINGLE_DATE:
                {
                    if (value > dateRange || value < dateRange)
                        result = false;
                    break;
                }

                default:
                {
                    break;
                }
            }
        }
        
        return result;
    }


    /**
     *  @private
     *
     *  Checking for valid dates, months and Years before setting them through API
     *  Returns true is date is disabled. null date is considered enabled,
     *  as one can set date to null.
     */
    mx_internal function checkDateIsDisabled(value:Date):Boolean
    {
        if (!value)
            return false;

        var selectedDateIsDisabled:Boolean = false;

        if (_selectableRange)
        {
            if (!isDateInRange(value, _selectableRange, selRangeMode))
            {
                selectedDateIsDisabled = true;
            }
        }

        if (_disabledRanges.length > 0)
        {
            for (var dRanges:int = 0; dRanges < _disabledRanges.length; dRanges++)
            {
                if (isDateInRange(value, _disabledRanges[dRanges], disabledRangeMode[dRanges]))
                {
                    selectedDateIsDisabled = true;
                }
            }
        }

        if (_disabledDays.length > 0)
        {
            for (var i:int = 0; i < _disabledDays.length; i++)
            {
                if (value.getDay() == _disabledDays[i])
                    selectedDateIsDisabled = true;
            }
        }

        return selectedDateIsDisabled;
    }

    /**
     *  @private
     *  Adds the newDate to the list of selected dates.
     *  If range is true, a range of dates starting from the previous selection is selected.
     */
    mx_internal function addToSelected(newDate:Date, range:Boolean = false):void
    {

        if (selectedRangeCount == 0)
            rangeStartDate = null;

        lastSelectedDate = newDate;

        if (range == false)
        {
            _selectedRanges[selectedRangeCount] = {};
            _selectedRanges[selectedRangeCount].rangeStart =
                new Date(newDate);
            _selectedRanges[selectedRangeCount].rangeEnd =
                _selectedRanges[selectedRangeCount].rangeStart;
            selectedRangeCount++;
        }
        else
        {
            if (selectedRangeCount == 0)
            {
                _selectedRanges[0] = {};
                _selectedRanges[0].rangeStart = new Date(newDate);
            }
            else
            {
                selectedRangeCount = 1;

                if (!rangeStartDate)
                    rangeStartDate = _selectedRanges[0].rangeStart;

                _selectedRanges[0].rangeStart = new Date(rangeStartDate);

                if (newDate < _selectedRanges[0].rangeStart)
                {
                    _selectedRanges[0].rangeEnd = _selectedRanges[0].rangeStart;
                    _selectedRanges[0].rangeStart = new Date(newDate);
                    return;
                }
            }

            _selectedRanges[0].rangeEnd = new Date(newDate);
        }
    }

    /**
     *  @private
     *  Increments/decrements a date by 'No. of days'
     *  specified by amount and returns the new date.
     */
    mx_internal function addSubtractDays(value:Date, amount:int):Date
    {
        var newDate:Date = new Date(value);
		
		if (value)
        	return new Date(newDate.fullYear, newDate.month, newDate.date + amount);
		else
			return null;
    }

    /**
     *  @private
     *  Returns true if newDate is selected.
     */
    mx_internal function isSelected(newDate:Date):Boolean
    {
        for (var i:int = 0; i < selectedRangeCount; i++)
        {
            if (newDate >= _selectedRanges[i].rangeStart &&
                newDate <=_selectedRanges[i].rangeEnd)
            {
                return true;
            }
        }

        return false;
    }

    /**
     *  @private
     *  Removes the range of dates specified by startDate and endDate
     *  from the selected dates.
     */
    mx_internal function removeRangeFromSelection(startDate:Date, endDate:Date):void
	{
		var rangeEnd:Date;
		var rangeStart:Date;
		
		if (endDate < startDate)
			return;
		
		for (var n:int = 0; n < selectedRangeCount; n++)
		{
			rangeStart = _selectedRanges[n].rangeStart;
			rangeEnd = _selectedRanges[n].rangeEnd;
			
			// ignore selection range outsie of date range
			if (endDate < rangeStart || startDate > rangeEnd)
				continue;
			
			// remove selection range inside of date range
			if (startDate <= rangeStart && endDate >= rangeEnd)
			{
				_selectedRanges[n] = null;
			}
			// split selection range if date range inside selection range
			else if (startDate > rangeStart && endDate < rangeEnd)
			{
				var temp:Date = _selectedRanges[n].rangeEnd;
				
				_selectedRanges[n].rangeEnd = addSubtractDays(startDate, -1);
				
				_selectedRanges[selectedRangeCount] = {};
				_selectedRanges[selectedRangeCount].rangeStart = addSubtractDays(endDate, +1);
				_selectedRanges[selectedRangeCount].rangeEnd = temp;
				
				selectedRangeCount++;
			}
			// remove day at start of range
			else if (endDate.time == rangeStart.time) {
				_selectedRanges[n].rangeStart = addSubtractDays(startDate, +1);	
			}
			// remove day at end of range
			else if (startDate.time == rangeEnd.time) {
				_selectedRanges[n].rangeEnd = addSubtractDays(endDate, -1);	
			}
			// move selection start date if end overlaps
			else if (endDate >= rangeStart)
			{
				_selectedRanges[n].rangeStart = addSubtractDays(endDate, +1);	
			}
			// move selection end date if start overlaps
			else if (startDate <= rangeEnd)
			{
				_selectedRanges[n].rangeEnd = addSubtractDays(startDate, -1);	
			}			
		}
		
		// clean up any removed selections
		for (n = selectedRangeCount -1; n >= 0; n--)
		{
			if (_selectedRanges[n] == null)
			{
				_selectedRanges.splice(n,1);
				selectedRangeCount--;
			}
		}
	}
	
	/**
	 *  @private
	 *  Removes a single date specified by singleDate from the selected dates.
	 */
	mx_internal function removeDayFromSelection(singleDate:Date):void
	{
		removeRangeFromSelection(singleDate, singleDate);
	}

    /**
     *  @private
     *  Updates the visible property of all the selected indicators.
     *  Called when a date range has been selected or deselected.
     */
    mx_internal function setSelectedIndicators():void
    {
        var offset:int = getOffsetOfMonth(displayedYear, displayedMonth);
        var daysInMonth:int = getNumberOfDaysInMonth(displayedYear, displayedMonth);

        var columnIndex:int; // 0 - 6
        var rowIndex:int; // 1 - 6
        var i:int;
        for (var dayNumber:int = 1; dayNumber <= daysInMonth; dayNumber++)
        {
            var cellDate:Date = new Date(displayedYear, displayedMonth, dayNumber);
            i = offset + dayNumber - 1;
            columnIndex = i % 7;
            rowIndex = 1 + Math.floor(i / 7);

            if (isSelected(cellDate) && disabledArrays[columnIndex][rowIndex] == false)
                addSelectionIndicator(columnIndex,rowIndex);
            else
                removeSelectionIndicator(columnIndex,rowIndex);
        }

        var today:Date = new Date();
        if (isSelected(today))
            todayIndicator.alpha = 1.0;
    }

    /**
     *  @private
     */
    mx_internal function addSelectionIndicator(columnIndex:int, rowIndex:int):void
    {
        if (!selectionIndicator[columnIndex][rowIndex])
        {

            var selectionIndicatorClass:Class =
                    getStyle("selectionIndicatorSkin");
            if (!selectionIndicatorClass)
                selectionIndicatorClass = DateChooserIndicator;
            selectionIndicator[columnIndex][rowIndex] =
                IFlexDisplayObject(new selectionIndicatorClass());
            
            if (isDateChooserIndicator(selectionIndicator[columnIndex][rowIndex]))
                Object(selectionIndicator[columnIndex][rowIndex]).indicatorColor =
                    "selectionColor";
            if (selectionIndicator[columnIndex][rowIndex] is ISimpleStyleClient)
                ISimpleStyleClient(selectionIndicator[columnIndex][rowIndex]).styleName = this;
            
            addChildAt(DisplayObject(selectionIndicator[columnIndex][rowIndex]), 0);

            var selCell:IUITextField = dayBlocksArray[columnIndex][rowIndex];
            selectionIndicator[columnIndex][rowIndex].move(selCell.x, selCell.y + yOffset);
            selectionIndicator[columnIndex][rowIndex].setActualSize(cellWidth, cellHeight);
        }
        selectionIndicator[columnIndex][rowIndex].visible = true;
    }

    /**
     *  @private
     */
    mx_internal function removeSelectionIndicator(columnIndex:int,
                                                  rowIndex:int):void
    {
        if (selectionIndicator[columnIndex][rowIndex])
        {
            removeChild(selectionIndicator[columnIndex][rowIndex]);
            selectionIndicator[columnIndex][rowIndex] = null;
        }
    }

    /**
     *  @private
     * 
     *  Removes the selection indicators from this component.
     */
    mx_internal function removeSelectionIndicators():void
    {
       for (var columnIndex:int = 0; columnIndex < 7; columnIndex++)
        {
            for (var rowIndex:int = 0; rowIndex < 7; rowIndex++)
            {
                removeSelectionIndicator(columnIndex, rowIndex);
            }
        }
    }

    //--------------------------------------------------------------------------
    //
    //  Overridden event handlers
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     */
    override protected function keyDownHandler(event:KeyboardEvent):void
    {
        /*
             PageUp: Previous Month
             PageDown: Next Month
        */

        var selChanged:Boolean = false;

        var date:int = lastSelectedDate ? lastSelectedDate.getDate() : 1;

        /*
        calculate Days to move will take the following values:

        1: Left
        2: Right
        3: Up
        4: Down
        5. Home
        6. End

        */

        var daysInMonth:int = getNumberOfDaysInMonth(displayedYear, displayedMonth);

        // If rtl layout, need to swap LEFT and RIGHT so correct action
        // is done.
        var keyCode:uint = mapKeycodeForLayoutDirection(event);
                
        for (var i:uint = 0; i < 31; i++)
        {
            if (keyCode == Keyboard.LEFT)
            {
                if (date > 1)
                {
                    date--;
                    selChanged = true;
                }
                else
                    return;
            }
    
            else if (keyCode == Keyboard.RIGHT)
            {
                if (date < daysInMonth)
                {
                    date++;
                    selChanged = true;
                }
                else
                    return;
            }
    
            else if (keyCode == Keyboard.UP)
            {
                if (date > 7)
                {
                    date -= 7;
                    selChanged = true;
                }
                else
                    return;
            }
    
            else if (keyCode == Keyboard.DOWN)
            {
                if (date + 7 <= daysInMonth)
                {
                    date += 7;
                    selChanged = true;
                }
                else
                    return;
            }
    
            else if (keyCode == Keyboard.HOME)
            {
                if (i == 0)
                    date = 1;
                else
                    date++;
                selChanged = true;
            }
    
            else if (keyCode == Keyboard.END)
            {
                if (i == 0)
                    date = daysInMonth;
                else
                    date--;
                selChanged = true;
            }
    
            else if (lastSelectedDate && event.shiftKey &&
                     (keyCode == Keyboard.PAGE_UP ||
                      keyCode == Keyboard.PAGE_DOWN))
            {
                selChanged = true;
            }
            
            else if (lastSelectedDate &&
                     (keyCode == 189 ||
                      keyCode == 187)) // for year - and +
            {
                selChanged = true;
            }
    
            if (keyCode >= Keyboard.PAGE_UP &&
                keyCode <= Keyboard.DOWN)
            {
                event.stopPropagation();
            }
    
            if (selChanged)
            {
                var newDate:Date = new Date(displayedYear, displayedMonth, date);
    
                if (checkDateIsDisabled(newDate) && !event.shiftKey)
                    continue;
    
                if (!(event.shiftKey && _allowMultipleSelection))
                    selectedRangeCount = 0;
    
                addToSelected(newDate, event.shiftKey && _allowMultipleSelection);
    
                setSelectedIndicators();
    
                dispatchChangeEvent(event);
                return;
            }
        }
    }

    //--------------------------------------------------------------------------
    //
    //  Event handlers
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     */
    private function mouseOverHandler(event:MouseEvent):void
    {
        if (event.relatedObject && event.relatedObject.parent != this)
            addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
        else
            event.stopImmediatePropagation();
    }

    /**
     *  @private
     */
    private function mouseOutHandler(event:MouseEvent):void
    {
        if (event.relatedObject && event.relatedObject.parent != this)
        {

            removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
            rollOverIndicator.visible = false;


            // If todayColumn and todayRow exist and today is not disabled
            if (todayColumn != -1 && todayRow != -1 && !disabledArrays[todayColumn][todayRow])
            {
                var today:Date = new Date();
                if (!isSelected(today))
                    todayIndicator.alpha = 1.0;
            }
        }
        else
        {
            event.stopImmediatePropagation();
        }
    }

    /**
     *  @private
     */
    private function mouseMoveHandler(event:MouseEvent):void
    {
        var paddingLeft:Number = getStyle("paddingLeft");
        var paddingTop:Number = getStyle("paddingTop");

        var firstColX:Number = dayBlocksArray[0][0].x;
        var lastColX:Number = dayBlocksArray[6][0].x;
        var firstRowY:Number = dayBlocksArray[6][0].y + cellHeight;

        var mousePoint:Point = new Point(event.stageX, event.stageY);
        mousePoint = globalToLocal(mousePoint);
        var mouseY:Number = mousePoint.y;
        var mouseX:Number = mousePoint.x;

        if (mouseX < firstColX ||
            mouseX > lastColX + cellWidth ||
            mouseY < firstRowY)
            return;

        var rowIndex:int = Math.floor((mouseY-paddingTop) / cellHeight);
        var colIndex:int = Math.floor((mouseX-paddingLeft) / cellWidth);

        colIndex = Math.min(colIndex, 6);
        rowIndex = Math.min(rowIndex, 6);

        var selCell:IUITextField = dayBlocksArray[colIndex][rowIndex];

        // If it is disabled, we're done.
        if (disabledArrays[colIndex][rowIndex] || rowIndex == 0)
            return;

        if (mouseY >= selCell.y &&
            mouseY <= selCell.y + cellHeight &&
            mouseX >= selCell.x &&
            mouseX <= selCell.x + cellWidth)
        {
            rollOverIndicator.move(selCell.x, selCell.y + yOffset); // Don't trigger layout
            rollOverIndicator.visible = true;

            // Don't show rollover if we're over the selected date
            if (selectionIndicator[colIndex][rowIndex])
            {
                rollOverIndicator.visible = false;
            }

            // Set alpha only if today is not disabled
            if (todayColumn != -1 && todayRow != -1 && !disabledArrays[todayColumn][todayRow])
            {
                var today:Date = new Date();
                if (rollOverIndicator.x == todayIndicator.x &&
                    rollOverIndicator.y == todayIndicator.y)
                {
                    todayIndicator.alpha = 0.6;
                }
                else if (!isSelected(today))
                {
                    todayIndicator.alpha = 1.0;
                }
            }
        }
    }

    /**
     *  @private
     */
    private function mouseUpHandler(event:MouseEvent):void
    {
        var paddingLeft:Number = getStyle("paddingLeft");
        var paddingTop:Number = getStyle("paddingTop");

        var firstColX:Number = dayBlocksArray[0][0].x;
        var lastColX:Number = dayBlocksArray[6][0].x;
        var firstRowY:Number = dayBlocksArray[6][0].y + cellHeight;

        var mousePoint:Point = new Point(event.stageX, event.stageY);
        mousePoint = globalToLocal(mousePoint);
        var mouseY:Number = mousePoint.y;
        var mouseX:Number = mousePoint.x;

        if (mouseX < firstColX &&
            mouseX >= lastColX + cellWidth ||
            mouseY < firstRowY)
            return;

        var rowIndex:int = Math.floor((mouseY-paddingTop) / cellHeight);

        if (rowIndex <= 0)
            return;
        rowIndex = Math.min(rowIndex, 6);

        var colIndex:int = Math.floor((mouseX-paddingLeft) / cellWidth);
        colIndex = Math.min(colIndex, 6);
        
        var selCell:IUITextField = dayBlocksArray[colIndex][rowIndex];//this["dayBlock"+colIndex+"label"+rowIndex];
        // If it is disabled, we're done.
        if (disabledArrays[colIndex][rowIndex])
            return;

        if (mouseY >= selCell.y &&
            mouseY <= selCell.y + cellHeight &&
            mouseX >= selCell.x &&
            mouseX <= selCell.x + cellWidth)
        {
            var newDate:Date = new Date(displayedYear, displayedMonth, int(selCell.text));

            if (event.shiftKey && _allowMultipleSelection)
            {
                addToSelected(newDate,true);
                setSelectedIndicators();
            }
            else
            {
                var alreadySelected:Boolean = selectionIndicator[colIndex][rowIndex] ? true : false;

                if (event.ctrlKey && _allowMultipleSelection && _allowDisjointSelection)
                {
                    if (alreadySelected)
                    {
                        removeSelectionIndicator(colIndex, rowIndex);
                        removeDayFromSelection(newDate);
                    }
                    else
                    {
                        addSelectionIndicator(colIndex, rowIndex);
                        addToSelected(newDate);
                    }
                }
                else
                {
                    rangeStartDate = null;

                    if (alreadySelected)
                    {
                        if (selectedRangeCount > 1 || (selectedRangeCount == 1 && _selectedRanges[0].rangeStart != _selectedRanges[0].rangeEnd))
                        {
                            selectedRangeCount = 0;
                            addSelectionIndicator(colIndex,rowIndex);
                            addToSelected(newDate);
                            setSelectedIndicators();
                        }
                        else if (event.ctrlKey)
                        {
                            removeSelectionIndicator(colIndex, rowIndex);
                            removeDayFromSelection(newDate);
                        }
                    }
                    else
                    {
                        selectedRangeCount = 0;
                        addSelectionIndicator(colIndex, rowIndex);
                        addToSelected(newDate);
                        setSelectedIndicators();
                    }
                }
            }

            dispatchChangeEvent(event);

            if (todayColumn != -1 && todayRow != -1 && !disabledArrays[todayColumn][todayRow]) // Set alpha only if today is not disabled
            {
                var todaysDate:Date = new Date();
                todayIndicator.alpha  = isSelected(todaysDate) ? 0.6 : 1.0;
            }

            // Hide the rollover indicator if it is the selected cell
            if (selectionIndicator[colIndex][rowIndex])
                rollOverIndicator.visible = false;
        }
    }

    /**
     *  We don't use 'is' to prevent dependency issues
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    private static var dcis:Object = {};

    private static function isDateChooserIndicator(parent:Object):Boolean
    {
        var s:String = getQualifiedClassName(parent);
        if (dcis[s] == 1)
            return true;

        if (dcis[s] == 0)
            return false;

        if (s == "mx.skins.halo::DateChooserIndicator")
        {
            dcis[s] == 1;
            return true;
        }

        var x:XML = describeType(parent);
        var xmllist:XMLList = x.extendsClass.(@type == "mx.skins.halo::DateChooserIndicator");
        if (xmllist.length() == 0)
        {
            dcis[s] = 0;
            return false;
        }
        
        dcis[s] = 1;
        return true;
    }
}

}
