YUI.add('aui-datepicker-base-deprecated', function (A, NAME) {

var Lang = A.Lang,
    isArray = Lang.isArray,
    isBoolean = Lang.isBoolean,
    isFunction = Lang.isFunction,
    isString = Lang.isString,

    AArray = A.Array,
    DataType = A.DataType,

    CALENDAR = 'calendar',
    CONTENT_BOX = 'contentBox',
    CURRENT_NODE = 'currentNode',
    DATE_FORMAT = 'dateFormat',
    DATEPICKER = 'date-picker',
    ESCAPE_KEY = 27,
    FOCUS = 'focus',
    FORMATTER = 'formatter',
    KEY_DOWN = 'keydown',
    KEY_PRESS = 'keypress',
    LOCALE = 'locale',
    SELECT_MODE = 'selectionMode',
    SET_VALUE = 'setValue',
    TRIGGER = 'trigger',
    TYPE = 'type';

var DatePickerDeprecated = A.Component.create({
    NAME: DATEPICKER,

    ATTRS: {
        /**
         * <a href="Calendar.html">Calendar</a> configuration Object.</a>
         *
         * @attribute calendar
         * @default {}
         * @type Object
         */
        calendar: {
            setter: '_setCalendar',
            value: {}
        },

        /**
         * Function to format the array of the selected dates before set the
         * value of the input.
         *
         * @attribute formatter
         * @default function(dates) { return dates.formatted.join(','); }
         * @type function
         */
        formatter: {
            value: function(dates) {
                var instance = this,
                    formattedDates = [];

                if (isArray(dates)) {
                    AArray.each(dates, function(date, index) {
                        formattedDates[index] = instance.calendar.formatDate(date);
                    });

                    return formattedDates.join(',');
                }
                else {
                    return instance.calendar.formatDate(dates);
                }
            },

            validator: isFunction
        },

        /**
         * If true set the selected date with the correct
         * dateFormat to the value of the input field
         * which is hosting the Calendar.
         *
         * @attribute setValue
         * @default true
         * @type boolean
         */
        setValue: {
            value: true,
            validator: isBoolean
        },

        /**
         * If true is able to do stacking with another overlays.
         *
         * @attribute stack
         * @default true
         * @type boolean
         */
        stack: {
            lazyAdd: false,
            value: true,
            setter: '_setStack',
            validator: isBoolean
        },

        showOn: {
            value: 'mousedown'
        },

        hideOn: {
            value: 'mousedown'
        }
    },

    EXTENDS: A.OverlayContext,

    prototype: {
        /**
         * Construction logic executed during Datepicker instantiation. Lifecycle.
         *
         * @method initializer
         * @protected
         */
        initializer: function() {
            var instance = this,
                calendarConfig = instance.get(CALENDAR),
                calendar = new A.Calendar(calendarConfig);

            instance.calendar = calendar;

            instance.after('calendar:selectionChange', instance._afterSelectionChange);

            instance.after(instance._afterShow, instance, 'show');

            instance._hideOnEscapeEvent();

            if (calendarConfig.hasOwnProperty('selectedDates')) {
                calendar.set('selectedDates', calendarConfig.selectedDates);
            }
        },

        /**
         * Bind the events on the Datepicker UI. Lifecycle.
         *
         * @method bindUI
         * @protected
         */
        bindUI: function() {
            var instance = this;

            DatePickerDeprecated.superclass.bindUI.apply(this, arguments);

            instance.on('show', instance._onShowOverlay);

            instance._bindTriggerEvents();
        },

        /**
         * Destructor lifecycle implementation for the Datepicker class.
         * Purges events attached to the node (and all child nodes).
         *
         * @method destructor
         * @protected
         */
        destructor: function() {
            var instance = this;

            instance.calendar.destroy();

            instance.escapeEventHandler.detach();
        },

        /**
         * Fires when a date is selected on the Calendar.
         *
         * @method _afterSelectionChange
         * @param {Event} event
         * @protected
         */
        _afterSelectionChange: function(event) {
            var instance = this;

            instance._uiSetSelectedDates(event.newSelection);
        },

        /**
         * Fires after show method executes
         *
         * @method _afterShow
         * @param {Event} event
         * @protected
         */
        _afterShow: function(event) {
            var instance = this;

            instance.calendar.focus();
        },

        /**
         * Bind some events on datepicker trigger
         *
         * @method _bindTriggerEvents
         * @protected
         */
        _bindTriggerEvents: function() {
            var instance = this,
                trigger = instance.get(TRIGGER),
                type = trigger.get(TYPE);

            trigger.after(FOCUS, function() {
                if (/^(text|textarea)$/i.test(type)) {
                    instance.show();
                }
            });

            trigger.after(KEY_PRESS, function() {
                instance.show();
            });
        },

        _hideOnEscapeEvent: function() {
            var instance = this;

            instance.escapeEventHandler = A.on(KEY_DOWN, function(event) {
                if (event.keyCode === ESCAPE_KEY) {
                    instance.hide();
                }
            });
        },

        /**
         * Fires before the DatePicker overlay show. Responsible to invoke the
         * render phase of the Calendar.
         *
         * @method _onShowOverlay
         * @param {Event} event
         * @protected
         */
        _onShowOverlay: function(event) {
            var instance = this;

            instance._renderCalendar();
        },

        /**
         * Render the Calendar used inside the DatePicker.
         *
         * @method _renderCalendar
         * @protected
         */
        _renderCalendar: function() {
            var instance = this;

            instance.calendar.render(
                instance.get(CONTENT_BOX)
            );
        },

        /**
         * Setter for the <a href="DatePicker.html#calendar">calendar</a>
         * attribute.
         *
         * @method _setCalendar
         * @param {String} eventType Event type
         * @protected
         * @return {}
         */
        _setCalendar: function(val) {
            var instance = this;

            A.mix(val, {
                bubbleTargets: instance
            });

            return val;
        },

        /**
         * Setter for the <a href="Calendar.html#config_stack">stack</a> attribute.
         *
         * @method _setStack
         * @param {boolean} value
         * @protected
         * @return {boolean}
         */
        _setStack: function(value) {
            var instance = this;

            if (value) {
                A.DatepickerManager.register(instance);
            }
            else {
                A.DatepickerManager.remove(instance);
            }

            return value;
        },

        /**
         * Set the value of the trigger input with the date information.
         *
         * @method _setTriggerValue
         * @param {Object} dateObj Object containing date information
         * @protected
         */
        _setTriggerValue: function(dateObj) {
            var instance = this;

            var value = instance.get(FORMATTER).apply(instance, [dateObj]);

            instance.get(CURRENT_NODE).val(value);
        },

        _uiSetSelectedDates: function(val) {
            var instance = this;

            if (instance.calendar.get(SELECT_MODE) !== 'multiple') {
                instance.hide();
            }

            if (instance.get(SET_VALUE)) {
                instance._setTriggerValue(val);
            }

            if (val.length) {
                instance.calendar.set('date', val[val.length - 1]);
            }
        }
    }
});

A.DatePickerDeprecated = DatePickerDeprecated;

/**
 * A base class for DatepickerManager:
 *
 * @param config {Object} Object literal specifying widget configuration properties.
 *
 * @class DatepickerManager
 * @constructor
 * @extends OverlayManager
 * @static
 */
A.DatepickerManager = new A.OverlayManager({
    /**
     * ZIndex default value passed to the
     * <a href="OverlayManager.html#config_zIndexBase">zIndexBase</a> of
     * <a href="OverlayManager.html">OverlayManager</a>.
     *
     * @attribute zIndexBase
     * @default 1000
     * @type Number
     */
    zIndexBase: 1000
});

var Calendar = function() {};

Calendar.ATTRS = {
    /**
     * The default date format string which can be overriden for
     * localization support. The format must be valid according to
     * <a href="DataType.Date.html">A.DataType.Date.format</a>.
     *
     * @attribute dateFormat
     * @default %m/%d/%Y
     * @type String
     */
    dateFormat: {
        value: '%m/%d/%Y',
        validator: isString
    },

    selectedDates: {
        readOnly: false,
        setter: function(val) {
            var instance = this;

            instance._clearSelection();

            instance.selectDates(val);
        }
    }
};

Calendar.prototype = {
    formatDate: function(date) {
        var instance = this,
            dateFormat = instance.get(DATE_FORMAT),
            locale = instance.get(LOCALE);

        return DataType.Date.format(date, {
            format: dateFormat,
            locale: locale
        });
    }
};

A.Base.mix(A.Calendar, [Calendar]);


}, '3.1.0-deprecated.95', {"requires": ["calendar", "aui-datatype", "aui-overlay-context-deprecated"], "skinnable": true});
