/**
 * @ignore
 * KISSY.Dialog
 * @author yiminghe@gmail.com
 */
KISSY.add('overlay/dialog', function (S, Overlay, DialogRender, Node) {

    /**
     * @class KISSY.Overlay.Dialog
     * KISSY Dialog Component. xclass: 'dialog'.
     * @extends KISSY.Overlay
     */
    var Dialog = Overlay.extend({
            // also simplify body
            __afterCreateEffectGhost: function (ghost) {
                var self = this,
                    body,
                    elBody = self.get("body");

                ghost.all('.' + self.get('prefixCls') + 'stdmod-body')
                    .css({
                        height: elBody.height(),
                        width: elBody.width()
                    })
                    .html('');

                return ghost;
            },

            handleKeyDownInternal: function (e) {
                if (this.get('escapeToClose') &&
                    e.keyCode === Node.KeyCode.ESC) {
                    if (e.target.nodeName.toLowerCase() == 'select' &&
                        !e.target.disabled) {
                        // escape at select
                    } else {
                        this.close();
                        e.halt();
                    }
                    return;
                }
                trapFocus.call(this, e);
            },

            _onSetVisible: function (v,e) {
                var self = this,
                    el = self.el;
                if (v) {
                    self.__lastActive = el.ownerDocument.activeElement;
                    self.focus();
                    // if d.show(); d.hide();
                    // async -> focus event -> handleFocusInternal
                    // -> set('focused') -> el.focus() -> ie error
                    // el[0].focus && el[0].focus();
                    el.setAttribute("aria-hidden", "false");
                } else {
                    el.setAttribute("aria-hidden", "true");
                    try {
                        self.__lastActive && self.__lastActive.focus();
                    } catch (e) {
                        // ie can not be focused if lastActive is invisible
                    }
                }
                // prevent display none for effect
                self.callSuper(v,e);
            }
        },

        {
            ATTRS: {

                /**
                 * Header element of dialog.
                 * @type {KISSY.NodeList}
                 * @property header
                 * @readonly
                 */
                /**
                 * @ignore
                 */
                header:{
                    view:1
                },
                /**
                 * Body element of dialog.
                 * @type {KISSY.NodeList}
                 * @property body
                 * @readonly
                 */
                /**
                 * @ignore
                 */
                body:{
                    view:1
                },
                /**
                 * Footer element of dialog.
                 * @type {KISSY.NodeList}
                 * @property footer
                 * @readonly
                 */
                /**
                 * @ignore
                 */
                footer:{
                    view:1
                },
                /**
                 * Key-value map of body element's style.
                 * @cfg {Object} bodyStyle
                 */
                /**
                 * @ignore
                 */
                bodyStyle:{
                    value:{},
                    view:1
                },
                /**
                 * Key-value map of footer element's style.
                 * @cfg {Object} footerStyle
                 */
                /**
                 * @ignore
                 */
                footerStyle:{
                    value:{},
                    view:1
                },
                /**
                 * Key-value map of header element's style.
                 * @cfg {Object} headerStyle
                 */
                /**
                 * @ignore
                 */
                headerStyle:{
                    value:{},
                    view:1
                },
                /**
                 * html content of header element.
                 * @cfg {KISSY.NodeList|String} headerContent
                 */
                /**
                 * @ignore
                 */
                headerContent:{
                    value:'',
                    view:1
                },
                /**
                 * html content of body element.
                 * @cfg {KISSY.NodeList|String} bodyContent
                 */
                /**
                 * @ignore
                 */
                bodyContent:{
                    value:'',
                    view:1
                },
                /**
                 * html content of footer element.
                 * @cfg {KISSY.NodeList|String} footerContent
                 */
                /**
                 * @ignore
                 */
                footerContent:{
                    value:'',
                    view:1
                },

                /**
                 * whether this component can be closed.
                 *
                 * Defaults to: true
                 *
                 * @cfg {Boolean} closable
                 * @protected
                 */
                /**
                 * @ignore
                 */
                closable: {
                    value: true
                },

                xrender: {
                    value: DialogRender
                },

                /**
                 * whether this component can be focused.
                 *
                 * Defaults to: true
                 *
                 * @cfg {Boolean} focusable
                 * @protected
                 */
                /**
                 * @ignore
                 */
                focusable: {
                    value: true
                },


                /**
                 * whether this component can be closed by press escape key.
                 *
                 * Defaults to: true
                 *
                 * @cfg {Boolean} escapeToClose
                 * @since 1.3.0
                 */
                /**
                 * @ignore
                 */
                escapeToClose: {
                    value: true
                }
            },
            xclass: 'dialog'
        });


    var KEY_TAB = Node.KeyCode.TAB;

    // 不完美的方案,窗体末尾空白 tab 占位符,多了 tab 操作一次
    function trapFocus(e) {

        var self = this,
            keyCode = e.keyCode;

        if (keyCode != KEY_TAB) {
            return;
        }
        var $el = self.$el;
        // summary:
        // Handles the keyboard events for accessibility reasons

        var node = Node.all(e.target); // get the target node of the keypress event

        // find the first and last tab focusable items in the hierarchy of the dialog container node
        // do this every time if the items may be added / removed from the the dialog may change visibility or state

        var lastFocusItem = $el.last();

        // assumes el and lastFocusItem maintained by dialog object

        // see if we are shift-tabbing from first focusable item on dialog
        if (node.equals(el) && e.shiftKey) {
            lastFocusItem[0].focus(); // send focus to last item in dialog
            e.halt(); //stop the tab keypress event
        }
        // see if we are tabbing from the last focusable item
        else if (node.equals(lastFocusItem) && !e.shiftKey) {
            self.focus(); // send focus to first item in dialog
            e.halt(); //stop the tab keypress event
        }
        else {
            // see if the key is for the dialog
            if (node.equals($el) || $el.contains(node)) {
                return;
            }
        }
        // this key is for the document window
        // allow tabbing into the dialog
        e.halt();//stop the event if not a tab keypress
    } // end of function
    return Dialog;

}, {
    requires: [
        "./control",
        './dialog-render',
        'node'
    ]
});

/**
 * @ignore
 *
 * 2012-09-06 yiminghe@gmail.com
 *  merge aria with dialog
 *  http://www.w3.org/TR/wai-aria-practices/#trap_focus
 *
 * 2010-11-10 yiminghe@gmail.com
 *  重构,使用扩展类
 */