<!DOCTYPE html>
<html>

  <head>
    <script data-require="angular.js@1.3.0-rc2" data-semver="1.3.0-rc2" src="https://code.angularjs.org/1.3.0-rc.2/angular.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="app.js"></script>
    <script src="appController.js"></script>
    <script src="gridManager.js"></script>
    <script src="baseGrid.js"></script>
    <script src="grid.js"></script>
  </head>

  <body ng-app="GridApp" ng-controller="AppController">
      <div wm-data-grid grid-options="gridOptions1"></div>
      <!-- <div wm-data-grid grid-options="gridOptions2"></div> -->
  </body>
</html>
/* Styles go here */

.grid {
    display: table;
    border-collapse: collapse;
}

.grid-head {
    display: table-header-group;
}

.grid-header-row {
    display: table-row;
    background-color: #dedede;
}

.grid-body {
    display: table-row-group;
}

.grid-row {
    display: table-row;
}

.grid-cell {
    display: table-cell;
    border: 1px solid #ededed;
}

.content-container {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.selected {
    background-color: #efefef;
}
var gridTemplate = '' +
    '<div ng-if="!gridOptions.data">Loading...</div>' +
    '<div ng-if="gridManager.rows.length" wm-data-grid-search></div>' +
    '<div class="grid" ng-if="gridManager.rows.length">' +
    '    <wm-data-grid-header></wm-data-grid-header>' +
    '  <div class="grid-body">' +
    '    <div class="grid-row" ng-class="{\'selected\': row.checked}" ng-repeat="row in gridManager.rows | filter: gridManager.searchText" wm-data-grid-row></div>' +
    '  </div>' +
    '</div>' +
    '<div ng-if="gridManager.allowAdd"><button ng-click="gridManager.addRow()">Add Row</button>' +
    '<div ng-if="gridOptions.data && !gridOptions.data.length">No data found.</div>',

    gridRowTemplate = '<div wm-data-grid-cell="checkboxCell"></div><div class="grid-cell" ng-repeat="col in gridManager.columnDefs"><wm-data-grid-cell></wm-data-grid-cell></div><div wm-data-grid-cell="deleteRowCell"></div>',
    
    gridCellTemplate = '<div class="content-container" ng-style="{width:col.width}">{{row[col.field]}}</div>',

    gridHeaderTemplate = '<div class="grid-head" ng-if="!gridManager.hideHeader"><div class="grid-header-row"><div wm-data-grid-cell="checkboxHeader"></div><div class="grid-cell" ng-repeat="col in gridManager.columnDefs"><div class="content-container" ng-style="{width: col.width}">{{col.displayName}}</div></div></div></div>',

    gridSearchTemplate = '<div>Search: <input type="text" ng-if="gridManager.allowSearch" ng-model="gridManager.searchText"></div>',
    
    gridFooterTemplate = '<div ng-show="gridOptions.showFooter">Grid Footer</div>',

    gridCheckboxTemplate = '<div ng-show="gridOptions.showCheckboxes"><input type="checkbox" ng-checked="row.checked" ng-click="gridManager.toggleRowSelection($event, row)"></div>',

    gridCheckboxHeaderTemplate = '<div ng-show="gridOptions.showCheckboxes"><input type="checkbox" ng-if="gridManager.multiselect" ng-checked="gridManager.allRowsChecked()" ng-click="gridManager.toggleSelectAll($event)"></div>',

    editRowCellTemplate = '<div ng-if="gridManager.allowEdit" class="grid-cell" title="Edit Row">Edit</div>',

    deleteRowCellTemplate = '<div ng-if="gridManager.allowDelete" class="grid-cell" title="Delete Row" ng-click="gridManager.deleteRow($index, row)">X</div>';


angular.module('GridApp').directive('wmDataGrid', function () {
    return {
        template: gridTemplate,
        scope: {
            gridOptions: '='
        },
        controller: function ($scope) {
            this.scope_ = $scope;
            this.scope_.gridManager = new GridManager();
            this.scope_.rows = this.scope_.gridManager.rows;
            this.scope_.columnDefs = this.scope_.gridManager.columnDefs;
            this.templates = {};
            this.scope_.$watch('gridOptions.data', angular.bind(this, function (newVal) {
                if (angular.isDefined(newVal)) {
                    this.scope_.gridManager.init(this.scope_.gridOptions);
                    // Expose grid manager instance to controller.
                    this.scope_.gridOptions.gridManager = this.scope_.gridManager;
                    this.setTemplates();
                }
            }));
            this.setTemplates = function () {
              var options = this.scope_.gridOptions;
              this.templates.header = options.headerTemplate || gridHeaderTemplate;
              this.templates.row = options.rowTemplate || gridRowTemplate;
              this.templates.cell = options.cellTemplate || gridCellTemplate;
              this.templates.editRowCell = options.editRowCellTemplate || editRowCellTemplate;
              this.templates.deleteRowCell = options.deleteRowCellTemplate || deleteRowCellTemplate;
              this.templates.footer = options.footerTemplate || gridFooterTemplate;
              this.templates.checkboxCell = options.checkboxTemplate || gridCheckboxTemplate;
              this.templates.checkboxHeader = options.checkboxHeaderTemplate || gridCheckboxHeaderTemplate;
              this.templates.search = options.searchTemplate || gridSearchTemplate;
            };
            this.scope_.getTemplate = function (type) {
              return this.templates[type];
            }.bind(this);
        },
        compile: function (element, attrs) {
          return {
            'pre': function (scope, element) {
              console.log('grid pre compile...', element.scope());
            },
            'post': function (scope, element, attrs) {
              window.console.log('grid linking function..');
            }
          };
        }
    };
});


angular.module('GridApp').directive('wmDataGridRow', function () {
    return {
        template: gridRowTemplate,
        require: '^wmDataGrid',
        scope: true,
        link: function (scope, element, attrs, gridController) {
          scope.xx = function() {
            //Dummy function on grid row scope.
          };
        }
    };
});


angular.module('GridApp').directive('wmDataGridHeader', ['$compile', function ($compile) {
    return {
        restrict: 'E',
        require: '^wmDataGrid',
        scope: true,
        link: function (scope, element, attrs, gridController) {
          var headerTemplate = gridController.scope_.getTemplate('header');
          element.replaceWith($compile(headerTemplate)(scope));
        }
    };
}]);


angular.module('GridApp').directive('wmDataGridCell', ['$compile', function ($compile) {
    var CELL_TYPES = [
      'cell',
      'editRowCell',
      'deleteRowCell',
      'checkboxCell',
      'checkboxHeader'
    ];
    return {
        restrict: 'EA',
        require: '^wmDataGrid',
        scope: true,
        link: function (scope, element, attrs, gridController) {
          var cellType = attrs.wmDataGridCell && CELL_TYPES.indexOf(attrs.wmDataGridCell) != -1 ? attrs.wmDataGridCell : 'cell';
          var cellTemplate = gridController.scope_.getTemplate(cellType);
          element.replaceWith($compile(cellTemplate)(scope));
        }
    };
}]);


// angular.module('GridApp').directive('wmDataGridDeleteRow', ['$compile', function ($compile) {
//     return {
//         //restrict: 'E',
//         require: '^wmDataGrid',
//         scope: true,
//         link: function (scope, element, attrs, gridController) {
//           console.log('scope.. ', scope);
//           if (gridController.scope_.gridManager.allowDelete) {
//             var deleteRowCellTemplate = gridController.scope_.getTemplate('deleteRowCell');
//             element.replaceWith($compile(deleteRowCellTemplate)(scope.$parent));
//           }
//         }
//     };
// }]);


angular.module('GridApp').directive('wmDataGridSearch', function () {
    return {
        template: gridSearchTemplate,
        require: '^wmDataGrid',
        scope: true,
        link: function (scope, element, attrs, gridController) {}
    };
});
var GridManager = function () {
    this.rows = [];
    this.columnDefs = [];
    this.templates = {};
};


GridManager.prototype.init = function (gridOptions) {
    this.rows = gridOptions.data;
    this.columnDefs = gridOptions.columnDefs;
    if (gridOptions.showCheckboxes) {
        // Maintain the selected row count in order to avoid iterating over
        // all rows whenever we need to find checked rows.
        this.selectedRowCount = this.getSelectedRowCount();
        this.multiselect = gridOptions.multiselect || true;
        // If multiselect is not allowed, maintain the current selected row.
        if (!this.multiselect) {
            // Will always hold one element - the currently selected row.
            this.currentlySelectedRow = [];
        }
    }
    this.allowEdit = gridOptions.allowEdit || false;
    this.allowDelete = gridOptions.allowDelete || false;
    // TODO(shubhangi): Make templates dynamic.
    //if (this.allowDelete) {
        //this.columnDefs.push({
            //field: 'deleteRow',
            //displayName: '',
            //width: '10px',
            //template: deleteRowCellTemplate
        //});
    //}
    this.allowAdd = gridOptions.allowAdd || false;
    this.allowSearch = gridOptions.allowSearch || false;
    this.hideHeader = gridOptions.hideHeader || false;
};


GridManager.prototype.updateSelectedRowCount = function (selected) {
    if (selected) {
        this.selectedRowCount++;
    } else {
        this.selectedRowCount--;
    }
};


GridManager.prototype.toggleRowSelection = function (e, row) {
    row.checked = e.target.checked;
    if (this.currentlySelectedRow && this.currentlySelectedRow.length) {
        var previousSelection = this.currentlySelectedRow.pop();
        previousSelection.checked = false;
        this.currentlySelectedRow.push(row);
    }
    this.updateSelectedRowCount(row.checked);
};


GridManager.prototype.deleteRow = function (index, row) {
    //TODO(shubhangi): Show a modal asking for confirmation before deleting.
    this.rows.splice(index, 1);
    // If the row was checked then decrement the rowSelectionCount when deleting it.
    if (row.checked) {
        this.updateSelectedRowCount(false);
        console.log('row selection count.. ', this.selectedRowCount);
    }
};


GridManager.prototype.addRow = function (index, row) {
    this.rows.push({});
};


GridManager.prototype.toggleSelectAll = function (e) {
    var selected = e.target.checked;
    angular.forEach(this.rows, function (row) {
        row.checked = selected;
    }.bind(this));
    // Update selected row count.
    if (selected) {
        this.selectedRowCount = this.getSelectedRowCount();
    } else {
        this.selectedRowCount = 0;
    }
};


GridManager.prototype.getSelectedRows = function () {
    var selectedRows = [];
    angular.forEach(this.rows, function (row) {
        if (row.checked) {
            selectedRows.push(row);
        }
    });
    return selectedRows;
};


GridManager.prototype.getSelectedRowCount = function () {
    return this.getSelectedRows().length;
};


GridManager.prototype.allRowsChecked = function () {
    return this.selectedRowCount == this.rows.length;
};
var app = angular.module('GridApp', []);
angular.module('GridApp').controller('AppController', ['$scope', '$timeout', function ($scope, $timeout) {
    $scope.gridData1 = [{
        name: "Moroni",
        age: 50
    }, {
        name: "Tiancum",
        age: 43
    }, {
        name: "Jacob",
        age: 27
    }, {
        name: "Nephi",
        age: 29
    }, {
        name: "Enos",
        age: 34
    }];
    $scope.fieldDefs = [{
        field: 'name',
        displayName: 'Display Name',
        width: '80px'
    }, {
        field: 'age',
        displayName: 'Age',
        width: '50px'
    }];
    
    $scope.gridData2 = [{
        name: "Moroni",
        age: 50
    }, {
        name: "Tiancum",
        age: 43
    }, {
        name: "Jacob",
        age: 27
    }, {
        name: "Nephi",
        age: 29
    }, {
        name: "Enos",
        age: 34
    }];
    $scope.fieldDefs = [{
        field: 'name',
        displayName: 'Display Name',
        width: '80px'
    }, {
        field: 'age',
        displayName: 'Age',
        width: '50px'
    }];
    deleteRowCellTemp = '<div ng-if="gridManager.allowDelete" class="grid-cell" title="Delete Row" ng-click="removeRow($index, row)">xx</div>';
    $scope.gridOptions1 = {};
    $scope.gridOptions2 = {};
    $scope.removeRow = function (index, row) {
      console.log('Remove Row...');
    };
    $scope.removeRow = function (index, row) {
          console.log('Remove Row...');
        };
    $timeout(function () {
        $scope.removeRow = function (index, row) {
          console.log('Remove Row...');
        };
        $scope.gridOptions1.data = $scope.gridData1;
        $scope.gridOptions1.columnDefs = $scope.fieldDefs;
        $scope.gridOptions1.showCheckboxes = true;
        $scope.gridOptions1.allowEdit = true;
        $scope.gridOptions1.allowDelete = true;
        $scope.gridOptions1.allowAdd = true;
        $scope.gridOptions1.allowSearch = true;
        $scope.gridOptions1.searchableFields = [];
        //$scope.gridOptions1.deleteRowCellTemplate = deleteRowCellTemp;
        //$scope.gridOptions1.headerTemplate = '<div>Header...</div>';
        
        $scope.gridOptions2.data = $scope.gridData2;
        $scope.gridOptions2.columnDefs = $scope.fieldDefs;
        $scope.gridOptions2.showCheckboxes = true;
        $scope.gridOptions2.allowEdit = true;
        $scope.gridOptions2.allowDelete = true;
        $scope.gridOptions2.allowAdd = true;
        $scope.gridOptions2.allowSearch = true;
        $scope.gridOptions2.searchableFields = [];
        //$scope.gridOptions2.deleteRowCellTemplate = deleteRowCellTemplate;
    }, 2000, true);

}]);