//React
import * as React from 'react';
import * as ReactDOM from 'react-dom';
//Wijmo
import * as wjcCore from 'wijmo/wijmo';
import * as wjGridSheet from 'wijmo/wijmo.react.grid.sheet';
import * as wjcGridSheet from 'wijmo/wijmo.grid.sheet';
import * as wjcGrid from 'wijmo/wijmo.grid';
//Application
import { DataService } from '../services/DataSvc';

export class Sorting extends React.Component<any, any> {
    data = DataService.default.data;
    sortManager: wjcGridSheet.SortManager;
    columns: string[];

    constructor(props) {
        super(props);
        this.state = {
            rows: []
        }
    }

    flexSheetInit(sortSheet: wjcGridSheet.FlexSheet) {
        let sheet1 = new wjcGridSheet.Sheet(sortSheet, null, 'Country', null, null);
        sortSheet.sheets.push(sheet1);

        if (sortSheet) {
            sortSheet.deferUpdate(() => {
                sortSheet.selectedSheetIndex = 0;
                sortSheet.selectedSheet.itemsSource = this.data;
                DataService.default.initDataMapForBindingSheet(sortSheet);
                this.sortManager = sortSheet.sortManager;
                this.columns = this._getColumns(sortSheet);
            });

            sortSheet.selectedSheetChanged.addHandler(() => {
                this.columns = this._getColumns(sortSheet);
                if (!this.sortManager) {
                    this.sortManager = sortSheet.sortManager;
                }
            });

            this._updateRows();
        }
    }


    // commit the sorts
    commitSort() {
        this.sortManager.commitSort();
    };

    // cancel the sorts
    cancelSort() {
        this.sortManager.cancelSort();
        this._updateRows();
    };

    // add new sort level
    addSortLevel() {
        this.sortManager.addSortLevel();
        this._updateRows();
    };

    // delete current sort level
    deleteSortLevel() {
        this.sortManager.deleteSortLevel();
        window.setTimeout(() => {
            this._updateRows(true);
        }, 10);  
    };

    // copy a new sort level by current sort level setting.
    copySortLevel() {
        this.sortManager.copySortLevel();
        this._updateRows(); 
    };

    // move the sort level
    moveSortLevel(offset) {
        this.sortManager.moveSortLevel(offset);
        
        window.setTimeout(() => {
           this._updateRows(true);
        }, 10);         
    };

    // apply column index property for sort item
    applySortColumnIndex(e, sortItem) {       
        sortItem.columnIndex = +e.target.value;
    }

    // apply asceding property for sort item
    applySortAscending(e, sortItem) {
        if (e.target.value === 'true') {
            sortItem.ascending = true;
        } else {
            sortItem.ascending = false;
        }
    }

    changedCurrentRow(sortItem) {
        this.sortManager.sortDescriptions.moveCurrentTo(sortItem);
        this._updateRows();
    }

    private _updateRows(needClearRows?:boolean) {
        let selectColumn = (sortItem) => {
            return <select className="form-control" onChange={(e) => { this.applySortColumnIndex(e, sortItem) }} defaultValue={sortItem.columnIndex}>
                <option value={-1} ></option>
                {this.columns.map((column, index) => {
                    return <option key={index} value={index}>
                        {column}
                    </option>
                })}
            </select>;
        };
        
        if (this.sortManager) {
            let rows = [];

            this.sortManager.sortDescriptions.items.map((sortItem, idx) => {
                rows.push(
                    <tr className={sortItem === this.sortManager.sortDescriptions.currentItem ? 'success' : ''} key={idx} onClick={this.changedCurrentRow.bind(this, sortItem) }>
                        <td>
                            {selectColumn(sortItem)}
                        </td>
                        <td>
                            <select className="form-control" onChange={(e) => { this.applySortAscending(e, sortItem) }} defaultValue ={sortItem.ascending+''}>
                                <option value={'true'} >Ascending</option>
                                <option value={'false'} >Descending</option>
                            </select>
                        </td>
                    </tr>);
            });
            if (needClearRows) {
                this.setState({
                    rows: []
                });
            }
            this.setState({
                rows: rows
            });
        }
    }

    private _getColumns(flexSheet: wjcGridSheet.FlexSheet): string[] {
        let columns = [],
            i = 0;
        if (flexSheet) {
            for (; i < flexSheet.columns.length; i++) {
                columns.push('Column ' + wjcGridSheet.FlexSheet.convertNumberToAlpha(i));
            }
        }
        return columns;
    }

    render() {

        return <div>
             <h2 id="sort">
                 Sorting
             </h2>
             <p>
                 FlexSheet can be sorted by any of its columns.
             </p>
             <p>
                 The <b>SortManager</b> helps FlexSheet to manage the sort process. The following example uses SortManager to specify the order of the sorting, add or remove sort columns, and change the order of the sort columns.
             </p>

            <div className="row">
                <div className="col-md-5">
                    <ul className="nav nav-tabs" role="tablist">
                        <li className="active"><a href="#stJsx" role="tab" data-toggle="tab">JSX</a></li>
                        <li><a href="#stJs" role="tab" data-toggle="tab">TS</a></li>
                    </ul>
                    <div className="tab-content">
                        <div className="tab-pane active pane-content" id="stJsx">
                            {'   <wjGridSheet.FlexSheet\n'}
                            {'       initialized={this.flexSheetInit.bind(this)} />\n'}
                            {'   <table className="table table-bordered">\n'}
                            {'       <thead>\n'}
                            {'           <tr>\n'}
                            {'               <th className="text-center">Column</th>\n'}
                            {'               <th className="text-center">Order</th>\n'}
                            {'           </tr>\n'}
                            {'       </thead>\n'}
                            {'       <tbody>\n'}
                            {'           {this.state.rows}\n'}
                            {'       </tbody>\n'}
                            {'   </table>\n'}
                            {'   <div className="btn-group">\n'}
                            {'       <button type="button" className="btn btn-default" onClick={this.addSortLevel.bind(this)}>\n'}
                            {'           Add Level\n'}
                            {'   </button>\n'}
                            {'       <button type="button" className="btn btn-default" onClick={this.deleteSortLevel.bind(this)}>\n'}
                            {'           Delete Level\n'}
                            {'   </button>\n'}
                            {'       <button type="button" className="btn btn-default" onClick={this.copySortLevel.bind(this)}>\n'}
                            {'           Copy Level\n'}
                            {'   </button>\n'}
                            {'   </div>\n'}
                            {'   <div className="btn-group">\n'}
                            {'       <button id="moveup" type="button"\n'}
                            {'           className="btn btn-default"\n'}
                            {'           disabled={this.sortManager && this.sortManager.sortDescriptions.currentPosition <= 0 ? true : false}\n'}
                            {'           onClick={this.moveSortLevel.bind(this, -1)}>\n'}
                            {'           <span className="glyphicon glyphicon-arrow-up"></span>\n'}
                            {'       </button>\n'}
                            {'       <button id="movedown" type="button"\n'}
                            {'           className="btn btn-default"\n'}
                            {'           disabled={this.sortManager && (this.sortManager.sortDescriptions.currentPosition >= this.sortManager.sortDescriptions.itemCount - 1) ? true : false}\n'}
                            {'           onClick={this.moveSortLevel.bind(this, 1)}>\n'}
                            {'           <span className="glyphicon glyphicon-arrow-down"></span>\n'}
                            {'       </button>\n'}
                            {'   </div>\n'}
                            {'   <div className="btn-group">\n'}
                            {'       <button type="button" className="btn btn-default" onClick={this.commitSort.bind(this)}>OK</button>\n'}
                            {'       <button type="button" className="btn btn-default" onClick={this.cancelSort.bind(this)}>Cancel</button>\n'}
                            {'   </div>\n'}
                        </div>
                        <div className="tab-pane pane-content" id="stJs">
                            {'   data = DataService.default.data;\n'}
                            {'   sortManager: wjcGridSheet.SortManager;\n'}
                            {'   columns: string[];\n'}
                            {'\n'}
                            {'   constructor(props) {\n'}
                            {'       super(props);\n'}
                            {'       this.state = {\n'}
                            {'           rows: []\n'}
                            {'       }\n'}
                            {'   }\n'}
                            {'\n'}
                            {'   flexSheetInit(sortSheet: wjcGridSheet.FlexSheet) {\n'}
                            {'       let sheet1 = new wjcGridSheet.Sheet(sortSheet, null, \'Country\', null, null);\n'}
                            {'       sortSheet.sheets.push(sheet1);\n'}
                            {'\n'}
                            {'       if (sortSheet) {\n'}
                            {'           sortSheet.deferUpdate(() => {\n'}
                            {'               sortSheet.selectedSheetIndex = 0;\n'}
                            {'               sortSheet.selectedSheet.itemsSource = this.data;\n'}
                            {'               DataService.default.initDataMapForBindingSheet(sortSheet);\n'}
                            {'               this.sortManager = sortSheet.sortManager;\n'}
                            {'               this.columns = this._getColumns(sortSheet);\n'}
                            {'           });\n'}
                            {'\n'}
                            {'           sortSheet.selectedSheetChanged.addHandler(() => {\n'}
                            {'               this.columns = this._getColumns(sortSheet);\n'}
                            {'               if (!this.sortManager) {\n'}
                            {'                   this.sortManager = sortSheet.sortManager;\n'}
                            {'               }\n'}
                            {'           });\n'}
                            {'\n'}
                            {'           this._updateRows();\n'}
                            {'       }\n'}
                            {'   }\n'}
                            {'\n'}
                            {'\n'}
                            {'   // commit the sorts\n'}
                            {'   commitSort() {\n'}
                            {'       this.sortManager.commitSort();\n'}
                            {'   };\n'}
                            {'\n'}
                            {'   // cancel the sorts\n'}
                            {'   cancelSort() {\n'}
                            {'       this.sortManager.cancelSort();\n'}
                            {'       this._updateRows();\n'}
                            {'   };\n'}
                            {'\n'}
                            {'   // add new sort level\n'}
                            {'   addSortLevel() {\n'}
                            {'       this.sortManager.addSortLevel();\n'}
                            {'       this._updateRows();\n'}
                            {'   };\n'}
                            {'\n'}
                            {'   // delete current sort level\n'}
                            {'   deleteSortLevel() {\n'}
                            {'       this.sortManager.deleteSortLevel();\n'}
                            {'        window.setTimeout(() => {\n'}
                            {'             this._updateRows(true);\n'}
                            {'         }, 10); \n'}
                            {'   };\n'}
                            {'\n'}
                            {'   // copy a new sort level by current sort level setting.\n'}
                            {'   copySortLevel() {\n'}
                            {'       this.sortManager.copySortLevel();\n'}
                            {'       this._updateRows();\n'} 
                            {'   };\n'}   
                            {'\n'}   
                            {'   // move the sort level\n'}   
                            {'   moveSortLevel(offset) {\n'}   
                            {'       this.sortManager.moveSortLevel(offset);\n'}   
                            {'        window.setTimeout(() => {\n'}
                            {'             this._updateRows(true);\n'}
                            {'         }, 10); \n'} 
                            {'   };\n'}   
                            {'\n'}   
                            {'   // apply column index property for sort item\n'}   
                            {'   applySortColumnIndex(e, sortItem) {    \n'}      
                            {'       sortItem.columnIndex = +e.target.value;\n'}   
                            {'   }\n'}   
                            {'\n'}   
                            {'   // apply asceding property for sort item\n'}   
                            {'   applySortAscending(e, sortItem) {\n'}   
                            {'       if (e.target.value ===\'true\') {\n'}   
                            {'           sortItem.ascending = true;\n'}   
                            {'       } else { \n'}  
                            {'           sortItem.ascending = false;\n'}  
                            {'       }\n'}  
                            {'   }\n'}  
                            {'\n'}  
                            {'   changedCurrentRow(e, sortItem, idx) {\n'}  
                            {'       this.sortManager.sortDescriptions.moveCurrentTo(sortItem);\n'}  
                            {'       this._updateRows();\n'}
                            {'   }\n'} 
                            {'\n'} 
                            {'\n'} 
                            {'   private _updateRows(needClearRows?:boolean) {\n'} 
                            {'       let selectColumn = (sortItem) => {\n'} 
                            {'           return <select className="form-control" onChange={(e) => { this.applySortColumnIndex(e, sortItem) }} defaultValue={sortItem.columnIndex}>\n'} 
                            {'               <option value={-1} ></option>\n'} 
                            {'               {this.columns.map((column, index) => {\n'} 
                            {'                   return <option key={index} value={index}>\n'} 
                            {'                       {column}\n'} 
                            {'                   </option>\n'} 
                            {'               })}\n'} 
                            {'           </select>;\n'} 
                            {'       };\n'} 
                            {'       if (this.sortManager) {\n'} 
                            {'           let rows = [];\n'} 
                            {'           this.sortManager.sortDescriptions.items.map((sortItem, idx) => {\n'} 
                            {'               rows.push(\n'} 
                            {'                   <tr className={sortItem === this.sortManager.sortDescriptions.currentItem ? "success" : ""}  key={idx} onClick={ this.changedCurrentRow.bind(this.sortItem) }>\n'} 
                            {'                       <td>\n'} 
                            {'                           {selectColumn(sortItem)}\n'} 
                            {'                       </td>\n'} 
                            {'                       <td>\n'} 
                            {'                           <select className="form-control" onChange={(e) => { this.applySortAscending(e, sortItem) }} defaultValue ={sortItem.ascending+\'\'}>\n'} 
                            {'                               <option value={\'true\'} >Ascending</option>\n'} 
                            {'                               <option value={\'false\'} >Descending</option>\n'} 
                            {'                           </select>\n'} 
                            {'                       </td>\n'} 
                            {'                   </tr>);\n'} 
                            {'           });\n'} 
                            {'           if (needClearRows) {\n'} 
                            {'               this.setState({\n'} 
                            {'                   rows: []\n'} 
                            {'               });\n'} 
                            {'           }\n'} 
                            {'\n'} 
                            {'           this.setState({\n'} 
                            {'               rows: rows\n'} 
                            {'           });\n'} 
                            {'       }\n'} 
                            {'   }\n'} 
                            {'\n'} 
                            {'   private _getColumns(flexSheet: wjcGridSheet.FlexSheet): string[] {\n'} 
                            {'       let columns = [],\n'} 
                            {'           i = 0;\n'} 
                            {'       if (flexSheet) {\n'} 
                            {'           for (; i < flexSheet.columns.length; i++) {\n'} 
                            {'               columns.push(\'Column \' + wjcGridSheet.FlexSheet.convertNumberToAlpha(i));\n'} 
                            {'           }\n'} 
                            {'       }\n'} 
                            {'       return columns;\n'} 
                            {'   }\n'} 
                            {'\n'} 
                        </div>
                    </div>
                </div>
                <div className="col-md-7">
                    <h4>Result (live):</h4>
                    <wjGridSheet.FlexSheet
                        initialized={this.flexSheetInit.bind(this)} />
                    <table className="table table-bordered">
                        <thead>
                            <tr>
                                <th className="text-center">Column</th>
                                <th className="text-center">Order</th>
                            </tr>
                        </thead>
                        <tbody>
                            {this.state.rows}
                        </tbody>
                    </table>
                    <div className="btn-group">
                        <button type="button" className="btn btn-default" onClick={this.addSortLevel.bind(this)}>
                            Add Level
                    </button>
                        <button type="button" className="btn btn-default" onClick={this.deleteSortLevel.bind(this)}>
                            Delete Level
                    </button>
                        <button type="button" className="btn btn-default" onClick={this.copySortLevel.bind(this)}>
                            Copy Level
                    </button>
                    </div>
                    <div className="btn-group">
                        <button id="moveup" type="button"
                            className="btn btn-default"
                            disabled={this.sortManager && this.sortManager.sortDescriptions.currentPosition <= 0 ? true : false}
                            onClick={this.moveSortLevel.bind(this, -1)}>
                            <span className="glyphicon glyphicon-arrow-up"></span>
                        </button>
                        <button id="movedown" type="button"
                            className="btn btn-default"
                            disabled={this.sortManager && (this.sortManager.sortDescriptions.currentPosition >= this.sortManager.sortDescriptions.itemCount - 1) ? true : false}
                            onClick={this.moveSortLevel.bind(this, 1)}>
                            <span className="glyphicon glyphicon-arrow-down"></span>
                        </button>
                    </div>
                    <div className="btn-group">
                        <button type="button" className="btn btn-default" onClick={this.commitSort.bind(this)}>OK</button>
                        <button type="button" className="btn btn-default" onClick={this.cancelSort.bind(this)}>Cancel</button>
                    </div>
                </div>
            </div>
        </div>;
    }
}

