/**
 * @file Drawer component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import {findDOMNode} from 'react-dom';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import query from 'dom-helpers/query';

import PositionPop from '../_PositionPop';
import Paper from '../Paper';
import Theme from '../Theme';

import Position from '../_statics/Position';

import Dom from '../_vendors/Dom';
import Util from '../_vendors/Util';
import Event from '../_vendors/Event';
import PopManagement from '../_vendors/PopManagement';

class Drawer extends Component {

    static Theme = Theme;
    static Position = Position;

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.closeTimeout = null;

    }

    clearCloseTimeout = () => {
        if (this.closeTimeout) {
            clearTimeout(this.closeTimeout);
            this.closeTimeout = null;
        }
    };

    setBodyLock = (props = this.props) => {

        if (!props) {
            return;
        }

        props.showModal && Dom.toggleClass(document.querySelector('body'), 'drawer-modal-lock', props.visible);

    };

    resetBody = () => {
        Dom.removeClass(document.querySelector('body'), 'drawer-modal-lock');
    };

    triggerHandler = (el, triggerEl, drawerEl, currentVisible, isBlurClose) => {

        // el is missing
        if (el && !query.contains(document, el)) {
            return currentVisible;
        }

        if ((triggerEl && el && query.contains(triggerEl, el))
            || (drawerEl && el && query.contains(drawerEl, el))) {
            return currentVisible;
        }

        return isBlurClose ? false : currentVisible;

    };

    closeHandler = e => {

        const {visible, isBlurClose, triggerEl, triggerHandler, onRequestClose} = this.props,
            drawerEl = findDOMNode(this.refs.drawerContent);

        if (!visible || !triggerEl) {
            return;
        }

        let currVisible;

        if (triggerHandler) {
            currVisible = triggerHandler(e.target, triggerEl, drawerEl, visible, isBlurClose);
        } else if (!Dom.isParent(e.target)) {
            currVisible = this.triggerHandler(e.target, triggerEl, drawerEl, visible, isBlurClose);
        }

        if (currVisible === false) {
            this.clearCloseTimeout();
            this.closeTimeout = setTimeout(() => {
                onRequestClose && onRequestClose(e);
            });
        }

    };

    componentDidMount() {
        this.setBodyLock();
        Event.addEvent(document, 'click', this.closeHandler);
    }

    componentWillReceiveProps(nextProps) {

        const {visible, isEscClose} = nextProps;

        if (visible !== this.props.visible) {
            this.setBodyLock(nextProps);
        }

        if (isEscClose && visible) {
            PopManagement.push(this);
        }

    }

    componentWillUnmount() {

        this.resetBody();
        this.clearCloseTimeout();
        Event.removeEvent(document, 'click', this.closeHandler);

        PopManagement.pop(this);

    }

    render() {

        const {

                className,

                // not passing down these props
                triggerEl, isBlurClose, isEscClose, onRender, onRequestClose,

                ...restProps

            } = this.props,

            drawerClassName = classNames('drawer', {
                [className]: className
            });

        return (
            <PositionPop {...restProps}
                         className={drawerClassName}
                         container={
                             <Paper ref="drawerContent"
                                    depth={6}></Paper>
                         }/>
        );

    }

}

Drawer.propTypes = {

    /**
     * The css class name of the root element.
     */
    className: PropTypes.string,

    /**
     * The css class name of the modal.
     */
    modalClassName: PropTypes.string,

    /**
     * The styles of the root element.
     */
    style: PropTypes.object,

    /**
     * The drawer alignment.
     */
    position: PropTypes.oneOf(Util.enumerateValue(Position)),

    triggerEl: PropTypes.object,

    /**
     * If true,the element will disabled.
     */
    disabled: PropTypes.bool,

    /**
     * If true,drawer box will display.
     */
    visible: PropTypes.bool,

    /**
     * If true,the pop-up box will be displayed in the mask layer, or the pop-up box will appear below the element.
     */
    showModal: PropTypes.bool,

    /**
     * If true,when press down mouse the pop-up box will closed.
     */
    isBlurClose: PropTypes.bool,

    isEscClose: PropTypes.bool,

    /**
     * The function of drawer render.
     */
    onRender: PropTypes.func,

    triggerHandler: PropTypes.func,

    /**
     * The function that trigger when click submit.
     */
    onRequestClose: PropTypes.func

};

Drawer.defaultProps = {

    position: Position.LEFT,
    disabled: false,
    visible: false,
    showModal: true,

    isBlurClose: true,
    isEscClose: true

};

export default Drawer;
@@ -969,337 +969,8 @@
 %7D;%0A%0A
-    setBodyLock = (props = this.props) =%3E %7B%0A%0A        if (!props) %7B%0A            return;%0A        %7D%0A%0A        props.showModal && Dom.toggleClass(document.querySelector('body'), 'drawer-modal-lock', props.visible);%0A%0A    %7D;%0A%0A    resetBody = () =%3E %7B%0A        Dom.removeClass(document.querySelector('body'), 'drawer-modal-lock');%0A    %7D;%0A%0A
     
@@ -2189,66 +2189,83 @@
     
-componentDidMount() %7B%0A        this.setBodyLock(
+renderHandler = (...args) =%3E %7B%0A%0A        PopManagement.push(this
 );%0A
+%0A
         
 Even
@@ -2264,346 +2264,335 @@
     
-Event.addEvent(document, 'click', this.closeHa
+const %7BonRender%7D = this.props;%0A        onRe
 nd
-l
 er
+ && onRender(...args
 );%0A
+%0A
     %7D
+;
 %0A%0A    
-componentWillReceiveProps(nextProps) %7B%0A%0A        const %7Bvisible, isEscClose%7D = nextProps;%0A%0A        if (visible !== this.props.visible) %7B%0A            this.setBodyLock(nextProps);%0A    
+destroyHandler = (...args) =%3E %7B%0A%0A        PopManagement.pop(this);%0A%0A        const %7BonDestroy%7D = this.props;%0A        onDestroy && onDestroy(...args);%0A%0A
     %7D
+;
 %0A%0A    
-    if (isEscClose && visible) %7B%0A            PopManagement.push(this);%0A        %7D%0A
+componentDidMount() %7B%0A        Event.addEvent(document, 'click', this.closeHandler);
 %0A   
@@ -2627,35 +2627,8 @@
 () %7B
-%0A%0A        this.resetBody();
 %0A   
@@ -2727,43 +2727,8 @@
 r);%0A
-%0A        PopManagement.pop(this);%0A%0A
     
@@ -3370,16 +3370,128 @@
        %7D
+%0A                         onRender=%7Bthis.renderHandler%7D%0A                         onDestroy=%7Bthis.destroyHandler%7D
 /%3E%0A     
@@ -4853,8 +4853,9 @@
  Drawer;
+%0A

update Drawer