# src/LoadingList.js File

    import React,{PropTypes} from 'react';
    import Component from './utils/Component';
    import classnames from 'classnames';
    import {setPhoenixPrefix} from './utils/Tool';

    import Drag from './Drag';
    import Button from './Button';
    import Icon from './Icon';

    /**
     * 加载更多组件<br/>
     * - 通过phMode设置加载更多的模式，有点击按钮加载更多，以及滑到最底端自动加载，可选 [button,auto] 2种参数。
     * - 通过loadingStatus设置当前状态，包括 0加载更多, 1加载中, 2数据加载成功, 3数据加载失败, 4没有更多。
     * - 可通过loadTips设置按钮文字和状态提示语，默认["加载更多","加载中","加载成功","加载失败","没有更多"]，分别对应loadingStatus的状态。
     * - 可通过buttonStyles设置按钮的样式，如果当前phMode为auto设置是看不到效果的，默认["primary","info","success","error","gray"]，分别对应loadingStatus的状态。
     * - 可通过onLoading设置点击按钮加载或滑到底部自动加载的回调函数。
     * - 可通过onLoadingEnd设置每次加载结束的回调函数。
     *
     * 主要属性和接口：
     * - phMode:加载更多的模式，默认auto。
     * - loadingStatus:当前状态:0加载更多, 1加载中, 2数据加载成功, 3数据加载失败, 4没有更多，默认1。
     * - loadTips:按钮文字和状态提示语，默认["加载更多","加载中","加载成功","加载失败","没有更多"]。
     * - buttonStyles:按钮的样式，默认["primary","info","success","error","gray"]。
     * - onLoading:点击按钮加载或滑到底部自动加载的回调函数。
     * - onLoadingEnd:每次加载结束的回调函数。
     *
     * 示例：
     * ```code
     *  <LoadingList phMode="auto" loadingStatus={this.state.loadingStatus}
     *      loadTips={["点击加载更多","加载中...","加载成功！","加载失败！","没有更多"]}
     *      buttonStyles={["primary","gray","success","danger","gray"]}
     *      onLoading={::this.onLoading} onLoadingEnd={::this.onLoadingEnd}>
     *          ...
     *  </LoadingList>
     * ```
     *
     * @class LoadingList
     * @module 操作类组件
     * @extends Component
     * @constructor
     * @since 1.6.0
     * @demo LoadingList|loading-list.js {展示}
     * @show true
     * */

    export default class LoadingList extends Component{
        static propTypes = {
            /**
             * 样式前缀
             * @property classPrefix
             * @type String
             * @default 'loading-list'
             * */
            classPrefix: PropTypes.string,
            /**
             * 加载更多的模式，可选[button,auto], 默认auto
             * @property phStyle
             * @type String
             * @default 'auto'
             **/
            phMode:PropTypes.string,
            /**
             * 加载状态：0加载更多, 1加载中, 2数据加载成功, 3数据加载失败, 4没有更多
             * @property loadingStatus
             * @type Number
             * @default 1
             **/
            loadingStatus: PropTypes.number,
            /**
             * 加载5个状态的文字描述，默认["加载更多","加载中","加载成功","加载失败","没有更多"]
             * @property loadTips
             * @type Array
             * @default ["加载更多","加载中","加载成功","加载失败","没有更多"]
             **/
            loadTips: PropTypes.array,
            /**
             * 加载5个状态的style，默认["primary","info","success","error","gray"]
             * @property buttonStyles
             * @type Array
             * @default ["primary","info","success","error","gray"]
             **/
            buttonStyles: PropTypes.array,
            /**
             * 点击按钮加载或滑到底部自动加载的回调函数，用户在该函数内自定义请求
             * @method onLoading
             * @type Function
             * @default null
             **/
            onLoading: PropTypes.func,
            /**
             * 每次加载结束的回调函数
             * @method onLoadingEnd
             * @type Function
             * @default null
             **/
            onLoadingEnd: PropTypes.func
        };

        static defaultProps ={
            phMode: 'auto',
            loadingStatus: 1, // 0加载更多, 1加载中, 2数据加载成功, 3数据加载失败, 4没有更多
            loadTips : ["加载更多","加载中","加载成功","加载失败","没有更多"],
            buttonStyles: ["primary","info","success","error","gray"],
            classPrefix:'loading-list',
            classMapping : {}
        };

        constructor(props,context){
            super(props,context);

            this.count = 0;
            this.handleWindowScroll = this.handleWindowScroll.bind(this);

            if(props.phMode=="auto") window.addEventListener('scroll', this.handleWindowScroll, false);
        }

        handleWindowScroll(){
            if(document.body.scrollTop >= this.loadingPage.offsetHeight + this.loadingPage.offsetTop - window.screen.height){
                if(this.props.loadingStatus==0) this.onLoading();
            }
        }

        renderButton(){
            let {phMode, loadTips, buttonStyles, loadingStatus} = this.props;
            if(phMode=="button"){
                return (
                    <Button phStyle={buttonStyles[loadingStatus]} block disabled={loadingStatus==4}
                        onClick={::this.onLoading}>
                        {this.renderIcon()}
                        {loadTips[loadingStatus]}
                    </Button>
                );
            }else{
                return (
                    <div className={setPhoenixPrefix('loading-page-tip')}>
                        {this.renderIcon()}
                        {loadTips[loadingStatus]}
                    </div>
                );
            }
        }

        renderIcon(){
            if(this.props.loadingStatus==1){
                return <Icon phIcon="loading" />;
            }else{
                return '';
            }
        }

        onLoading(){
            if(this.props.onLoading) this.props.onLoading();
        }

        onDrag(event, position){
            let {phMode, loadingStatus} = this.props;
            if(phMode=="button") return;

            let startY = position.start.y, moveY = position.move.y;
            let distanceY = moveY-startY;
            if(distanceY>0) return; //只可以上拉

            if(Math.abs(distanceY)>30){
                // 拖拽过程中只执行一次
                if(this.count==0){
                    // 初始状态和错误状态可以上拉重新请求
                    if(loadingStatus==0 || loadingStatus==3) this.onLoading();
                    this.count++;
                }
            }

            if(Math.abs(distanceY)>=200) distanceY = -200;

            this.loadingPageMain.style.transform = "translateY("+distanceY+"px)";
        }

        onDrop(event, position){
            if(this.props.phMode=="button") return;
            this.count = 0;
            this.loadingPageMain.style.transform = "translateY(0px)";
        }

        componentDidMount(){
            // let {loadingStatus, onLoadingEnd} = this.props;
            // if(loadingStatus==2 && onLoadingEnd) onLoadingEnd();
        }

        componentDidUpdate(){
            let {loadingStatus, onLoadingEnd} = this.props;
            if(loadingStatus==2 && onLoadingEnd) onLoadingEnd();
        }

        componentWillUnmount(){
            window.removeEventListener('scroll', this.handleWindowScroll, false);
        }

        render(){
            let {className, children} = this.props;

            return(
                <Drag {...this.props} className={classnames(this.getProperty(true),className,'animated')}
                    onDrag={::this.onDrag} onDrop={::this.onDrop}>
                    <div className={setPhoenixPrefix('loading-page-main')} ref={(loadingPageMain)=>{this.loadingPageMain=loadingPageMain;}}>
                        <div className={setPhoenixPrefix('loading-page-content')} ref={(loadingPage)=>{this.loadingPage=loadingPage;}}>
                            {children}
                        </div>
                        {this.renderButton()}
                    </div>
                </Drag>
            )
        }
    }