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

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import Header from '../_TableHeader';
import Content from '../_TableContent';
import Footer from '../_TableFooter';
import Pagination from '../_TablePagination';

import Theme from '../Theme';
import SelectMode from '../_statics/SelectMode';
import SelectAllMode from '../_statics/SelectAllMode';
import SortingType from '../_statics/SortingType';

import Util from '../_vendors/Util';
import Calculation from '../_vendors/Calculation';

class Table extends Component {

    static SelectMode = SelectMode;
    static SelectAllMode = SelectAllMode;
    static SortingType = SortingType;

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.state = {
            sorting: props.sorting,
            pagination: props.pagination,
            value: Calculation.getInitValue(props)
        };

    }

    /**
     * handle sort change
     */
    handleSortChange = sorting => {
        this.setState({
            sorting
        }, () => {
            const {onSortChange} = this.props;
            onSortChange && onSortChange(sorting);
        });
    };

    /**
     * handle pagination change
     */
    handlePaginationChange = pagination => {
        this.setState({
            pagination
        }, () => {
            const {onPaginationChange} = this.props;
            onPaginationChange && onPaginationChange(pagination);
        });
    };

    render() {

        const {
                className, style,
                isPaginated, pageSizes,
                ...restProps
            } = this.props,
            {sorting, pagination, value} = this.state,

            tableClassName = classNames('table', {
                [className]: className
            });

        return (
            <div className={tableClassName}
                 style={style}>

                {/* table header, display when select */}
                <Header/>

                {/* table area */}
                <Content {...restProps}
                         sorting={sorting}
                         pagination={pagination}
                         value={value}
                         isPaginated={isPaginated}
                         onSortChange={this.handleSortChange}/>

                {/* table footer */}
                <Footer/>

                {/* table pagination */}
                {
                    isPaginated ?
                        <Pagination {...restProps}
                                    pagination={pagination}
                                    pageSizes={pageSizes}
                                    value={value}
                                    onChange={this.handlePaginationChange}/>
                        :
                        null
                }

            </div>
        );

    }
}

Table.propTypes = {

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

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

    /**
     * The theme of the table select radio or checkbox.
     */
    selectTheme: PropTypes.oneOf(Util.enumerateValue(Theme)),

    /**
     * The select mode of table.
     */
    selectMode: PropTypes.oneOf(Util.enumerateValue(SelectMode)),

    /**
     * The select all mode of table, all or current page.
     */
    selectAllMode: PropTypes.oneOf(Util.enumerateValue(SelectAllMode)),

    /**
     * Children passed into table header.
     */
    columns: PropTypes.arrayOf(PropTypes.shape({

        /**
         * The class name of header.
         */
        headerClassName: PropTypes.string,

        /**
         * Override the styles of header.
         */
        headerStyle: PropTypes.object,

        /**
         * The render content in header.
         * (1) string，example： 'id'
         * (2) callback，example：function (colIndex) {return colIndex;}
         */
        headerRenderer: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),

        /**
         * The class name of td.
         */
        cellClassName: PropTypes.string,

        /**
         * Override the styles of td.
         */
        cellStyle: PropTypes.object,

        /**
         * The render content in table.
         * (1) data key，example： 'id'
         * (2) data key tamplate，example：'${id} - ${name}'
         * (3) callback，example：function (rowData, rowIndex, colIndex) {return rowData.id;}
         */
        cellRenderer: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),

        /**
         * The class name of footer.
         */
        footerClassName: PropTypes.string,

        /**
         * Override the styles of footer.
         */
        footerStyle: PropTypes.object,

        /**
         * The render content in footer.
         * (1) string，example： 'id'
         * (2) callback，example：function (colIndex) {return colIndex;}
         */
        footerRenderer: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),

        /**
         * If true,this column can be sorted.
         */
        sortable: PropTypes.bool,

        /**
         * Sorting property.
         */
        sortingProp: PropTypes.string,

        defaultSortingType: PropTypes.oneOf(Util.enumerateValue(SortingType)),

        span: PropTypes.func

    })).isRequired,

    data: PropTypes.array,

    /**
     * sorting
     */
    sorting: PropTypes.shape({
        prop: PropTypes.string,
        type: PropTypes.oneOf(Util.enumerateValue(SortingType))
    }),
    defaultSortingType: PropTypes.oneOf(Util.enumerateValue(SortingType)),
    sortingAscIconCls: PropTypes.string,
    sortingDescIconCls: PropTypes.string,
    sortingFunc: PropTypes.func,

    isPaginated: PropTypes.bool,
    pagination: PropTypes.shape({
        pageSize: PropTypes.number,
        page: PropTypes.number
    }),
    pageSizes: PropTypes.array,
    useFullPagination: PropTypes.bool,

    onSortChange: PropTypes.func,
    onPaginationChange: PropTypes.func

};

Table.defaultProps = {

    selectMode: SelectMode.SINGLE_SELECT,
    selectAllMode: SelectAllMode.CURRENT_PAGE,

    defaultSortingType: SortingType.ASC,
    sortingAscIconCls: 'fas fa-angle-up',
    sortingDescIconCls: 'fas fa-angle-down',

    isPaginated: true,
    pagination: {
        pageSize: 10,
        page: 0
    },
    pageSizes: [5, 10, 15, 20],
    useFullPagination: false

};

export default Table;

@@ -3696,16 +3696,197 @@
 hape(%7B%0A%0A
+        /**%0A         * width of column%0A         */%0A        width: PropTypes.number,%0A%0A        /**%0A         * minimum width of column%0A         */%0A        minWidth: PropTypes.number,%0A%0A
         
@@ -6264,24 +6264,120 @@
 ypes.bool,%0A%0A
+    /**%0A     * fixed%0A     */%0A    isHeadFixed: PropTypes.bool,%0A    isFootFixed: PropTypes.bool,%0A%0A
     onSortCh
@@ -6831,16 +6831,65 @@
 n: false
+,%0A%0A    isHeadFixed: false,%0A    isFootFixed: false
 %0A%0A%7D;%0A%0Aex

update Table