
var gradebookGrid = function(){

   var isDroppedRenderer = function(value, metaData, record, rowIndex, colIndex, store) {
      var droppedCol = record.fields.items[colIndex*2].name+'_dropped';
      if (record.data[droppedCol]) {
         metaData.css = 'notEditable';
      }
      return value;
   }
   
   var calcQtrAvg = function(value, metadata, record, rowIndex, colIndex, store) {
      //record: student and their task grades
      var scoreAchieved=0, scoreAvailable=0;
      var course = Ext.getCmp('gradebookcourseid').store.getById(Ext.getCmp('gradebookcourseid').getValue()).data;
      var grid = Ext.getCmp('gradebookGrid');
      
      //loop through tasks
      record.fields.each(function(taskid) {
         taskid = taskid.name;
         if (isnum(taskid)) { //an actual task

            var task = record.data[taskid];
            var dropped = record.data[taskid+'_dropped'];
            
            if (!dropped) {
               var assignment = grid.assignments.getById(taskid).data; //global properties of the current task
               
               if (course.ispoints) { //points course
               
                  if (task != null) {
                     scoreAchieved += task;
                     scoreAvailable += assignment.points;
                  }
                  
               } else { //percent course (NOTE: DOES NOT ACCOUNT FOR UNUSED WEIGHTS YET)
               
                  var weightAmt = ( task == null ? 0 : assignment.weight ); //does assignment.makeup need to be considered? 
                  var weightVal = parseInt(task||0) * weightAmt;
                  
                  
               	scoreAvailable += (weightVal || 0);
               	scoreAchieved += (weightAmt || 0);
               }	
            }
         }
      }, record);	    
   
      //return result
      var grade;
      if (course.ispoints) { //points course
      	grade = parseFloat( (scoreAvailable != null ? ((scoreAchieved / scoreAvailable) * 100) : 0) ).toFixed(2);
      } else {
         grade = parseFloat( (scoreAvailable == null || scoreAchieved == 0) ? null : (scoreAvailable / scoreAchieved) ).toFixed(2);
      }

      var gradescale = Ext.getCmp('gradebookGrid').gradescale;
      if (course.gradetype && grade != 'NaN') {
         gradescale.each(function(scale) {
            if (scale.data.lowvalue <= grade && grade <= scale.data.highvalue) grade = scale.data.lettergrade;
         });
      }
      return ( parseFloat(grade) ? (Math.round((parseFloat(grade) + .000001)*100)/100 ).toFixed(2) : (grade=='NaN'?null:grade) );
   } 

   
   var cm = new Ext.grid.ColumnModel({
      defaults: { sortable: false },
      columns: [
         {
            header: 'Student Name',
            dataIndex: 'StudentName',
            width: 150,
            menuDisabled: true,
            sortable: true
         },
         {
            header: "<img src='functions/image.php?text=Qtr Average' />",
            dataIndex: 'QtrAvg',
            width: 45,
            align: 'right',
            menuDisabled: true,
            sortable: true,
            renderer: calcQtrAvg
         }
      ]
   });     
   
   gradebookGrid.superclass.constructor.call(this, {
      id: 'gradebookGrid',
      store: new Ext.data.Store({  
         storeId: 'gradebookGrid_store',
         url : 'teacher_tools/gradebook_data.json.php',  
         baseParams: {command: 'getGrades'},     
         reader: new Ext.data.JsonReader({
            root: 'grades',
            idProperty: 'gradebookid'
         }, [
            {name: 'gradebookid'},
            {name: 'orderno', type:'int'},
            {name: 'studentid'}, 
            {name: 'StudentName'}, 
            {name: 'QtrAvg'}
         ]),
         autoLoad : false,
         autoSave: false,
         writer: new Ext.data.JsonWriter({}),
         listeners: {
            load: function(store, records, options) {
               var hasOrder;
               for (var i=0, len=store.data.items.length; i<len; i++) {
                  var record = store.data.items[i];
                  if(record.data.orderno != null) hasOrder = true;
               }
               store.sort( (hasOrder?'orderno':'StudentName'), 'ASC');
            }
         }
      }),               
      //custom functions and properties
      loadGrid : function() {
         
         if (!this.store.baseParams.courseid || !this.store.baseParams.quarter) {
            return false;
         }
         
         this.store.save();
         Ext.getCmp('gb_add').enable();
         Ext.getCmp('gb_course_summary').enable();
         
         //clear any pre-loaded tasks
         for(i=this.colModel.columns.length-1; i>0; i--) {
            var col = this.colModel.columns[i];
            if (parseInt(col.dataIndex)) { //all taskid's are integers
               this.removeColumn(col.dataIndex);
            }
            if (col.dataIndex.toString().match('_dropped')) {
               this.store.removeField(col.dataIndex);
            }
         }
         
         //load the current gradescale
         this.gradescale.baseParams.courseid = this.store.baseParams.courseid;
         this.gradescale.load();
         
         //load the tasks for the current course
         this.assignments.baseParams.courseid = this.store.baseParams.courseid;
         this.assignments.baseParams.quarter = this.store.baseParams.quarter;
         this.assignments.load();
      },
      createColumn: function(title, dataIndex, index, markDirty) {
      
         if (dataIndex == undefined) {
            var i=1, name = 'newtask';
            while (this.store.fields.containsKey(name+i)) {
               i++;
            }
            dataIndex = name+i;
         }
         
         var colConfig = {                
            header: verticalText(title),
            dataIndex: dataIndex ,
            width: 30,
            align: 'right',
            id: dataIndex,
            menuDisabled: true,
            editor: new Ext.form.NumberField({ allowBlank: true, allowNegative: false, maxValue: 120 }),
            renderer: isDroppedRenderer
         };
         
         if (index != undefined) {
            this.addColumn(dataIndex, colConfig,index);
         } else {
            this.addColumn(dataIndex, colConfig);
         }
         
         if (markDirty != undefined && markDirty) {
            //mark dirty, so the new column will get saved
            this.store.each(function(rec) {
                rec.set(dataIndex,null);
            });
         }
      },
      gradescale: new Ext.data.Store({  
         url : 'teacher_tools/gradebook_data.json.php',  
         baseParams: {command: 'getGradeScale'},     
         reader: new Ext.data.JsonReader({root: 'scale'}, [
            {name: 'scaleid'}, 
            {name: 'lettergrade'}, 
            {name: 'highvalue', type: 'float'}, 
            {name: 'lowvalue', type: 'float'}
         ]),
         autoLoad: false
      }),
      assignments: new Ext.data.Store({  
         url : 'teacher_tools/gradebook_data.json.php',  
         baseParams: {command: 'getAssignments'},     
         reader: new Ext.data.JsonReader({
            root: 'assignments',
            idProperty: 'taskid'
         }, [
            {name: 'taskid'}, 
            {name: 'task'}, 
            {name: 'taskdate'}, 
            {name: 'makeup', type:'bool'}, 
            {name: 'points', type:'float'}, 
            {name: 'weight', type:'float'}, 
            {name: 'category'}
         ]),
         autoLoad: false,
         autoSave: false,
         writer: new Ext.data.JsonWriter({
            writeAllFields: true
         }),
         listeners: {
            load: function (assignments, records, options) {
               var grid = Ext.getCmp('gradebookGrid');
               for (var i=0, len=records.length; i<len; i++) {
                  grid.createColumn(records[i].data.task, records[i].data.taskid,i+2);
                  grid.store.addField({name:records[i].data.taskid+'_dropped', type: 'bool'});
               }
               grid.store.load();
            },
            add: function (assignments, records, index) {
               Ext.getCmp('gradebookGrid').assignments.save();
            },
            write: function (assignments, action, result, res, records) {
               if (action == 'create') {
                  var grid = Ext.getCmp('gradebookGrid');
                  for (var i=0, len=result.length; i<len; i++) {
                     console.log(result[i], result[i].taskid);
                     grid.createColumn(result[i].task, result[i].taskid);
                     grid.store.addField({name:result[i].taskid+'_dropped', type: 'bool'});
                  }
                  console.log(records, grid.store);
               }
            },
            update: function (assignments, record, index) {
               var grid = Ext.getCmp('gradebookGrid');
               var column = grid.colModel.getColumnById(record.id);
               if (column != undefined) {
                  column.header = verticalText(record.data.task);
                  grid.view.refresh(true);
               }
            },
            remove: function (assignments, record, index) {
               var grid = Ext.getCmp('gradebookGrid');
               grid.removeColumn(record.id);
               grid.store.removeField(record.id+'_dropped');
            }
         }
      }),
      // end: custom functions and properties
      cm: cm,
      ltrTab: false, //tab key scrolls up/down (true=left/right). default=true
      width: 600,
      height: 300,
      title: 'Gradebook',
      frame: false,
      tbar: {
        xtype: 'toolbar',
        items: [
            {
                xtype: 'label',
                text: 'Course:',
                style: 'margin-left: 5px;'
            },
           new SchoolDynamics.coursesCombo({
               id:'gradebookcourseid',
               listeners: {
                  setValue: function(combo, newvalue, oldvalue) {
                        myGrid = Ext.getCmp('gradebookGrid');
                        myGrid.store.baseParams.courseid = SchoolDynamics.currentCourseID = newvalue;
                        myGrid.loadGrid();
                  }
               }
            }),
            {
                xtype: 'tbseparator',
                style: 'margin-left: 5px; padding-left: 15px;'
            },
            {
                xtype: 'label',
                text: 'Grade period:',
                style: 'margin-left: 5px;'
            },
            new SchoolDynamics.quarterCombo({
                id:'gradebookquarter',
                listeners: {
                   setValue: function(combo, newvalue, oldvalue) {
                        myGrid = Ext.getCmp('gradebookGrid');
                        myGrid.store.baseParams.quarter = SchoolDynamics.currentQtr = newvalue;
                        myGrid.loadGrid();
                    }
                }
            }),
            {
                xtype: 'tbseparator',
                style: 'margin-left: 5px; padding-left: 15px;'
            },
            {
                xtype: 'tbsplit',
                text: 'Add Task',
                iconCls: 'add',
                id: 'gb_add',
                style: 'margin-left: 5px;',
                menu: new Ext.menu.Menu({
                  items: [{
                     text: 'Mid-term exam', 
                     iconCls: 'table_add',
                     listeners: {
                        click: function(btn) {
                           addAssignmentPopup.showWithArgs(true, 'midterm');
                        }
                     } 
                  },{
                     text: 'Final exam', 
                     iconCls: 'table_add',
                     listeners: {
                        click: function(btn) {
                           addAssignmentPopup.showWithArgs(true, 'final');
                        }
                     } 
                  }]
                }),
                listeners: {
                  click: function(btn) {
                     addAssignmentPopup.showWithArgs(true);
                  }
                } 
            },
            {
                xtype: 'tbseparator',
                style: 'margin-left: 5px;'
            },
            {
                xtype: 'button',
                text: 'Course Summary',
                id: 'gb_course_summary',
                iconCls: 'chart_bar',
                style: 'margin-left: 5px;',
                handler: function() {
                  var popup = new gradebookSummary.window({
                     title:'Course Summary',
                     fieldHeader:'Task',
                     limitColumns: [0,1,2,3,4],
                     baseParams: { command: 'courseSummary' },
                     requiredBaseParams: new Array('courseid', 'quarter')
                  });
                  popup.show();
                }
            }
        ]
      },
      listeners: {
         activate: function(tab) { //the grid IS the tab
            Ext.getCmp('gradebookcourseid').setValue(SchoolDynamics.currentCourseID);
            Ext.getCmp('gradebookquarter').setValue(SchoolDynamics.currentQtr);
            
            if (tab.gradescale.totalLength == undefined) tab.gradescale.load();
         },
         
         cellcontextmenu: function (grid, rowIndex, columnIndex, e) {
            if (2 <= columnIndex) {
               
               //highlight the field
               var r = grid.view.getRow(rowIndex);
               var cell = Ext.get( r ? r.getElementsByTagName('td')[columnIndex] : false );
               cell.addClass('highlight');
               
               var task = grid.assignments.getAt(columnIndex-2);
      			var student = grid.store.getAt(rowIndex);
      			var taskdropped = student.data[task.id+'_dropped'];
               var grade = student.data[task.id];
            
         		this.contextMenu = new Ext.menu.Menu({
         			id: 'gradebook_contextmenu',
         			items: [{ //task actions
         				id: 'task',
         				text: 'Task: '+task.data.task,
         				menu: [{
            				text: 'Assign "'+grade+'" to all students',
            				handler: function(){
            				   var courseStore = Ext.getCmp('gradebookcourseid').store;
                           var course = courseStore.getAt(courseStore.find(courseStore.reader.meta.idProperty, SchoolDynamics.currentCourseID));
                           grid.store.each( function(record) {
                              record.set(task.id, grade);
                           }, this);
                        }
                     },{
            				text: 'Edit Task',
            				handler: function(btn) {
                           addAssignmentPopup.showWithArgs(false, null, task);
                        }
                     },{
            				text: 'Task Summary',
            				handler: function(btn) {
                           
                           var popup = new gradebookSummary.window({
                              title:'Task Summary',
                              fieldHeader:'Student',
                              limitColumns: [0,5],
                              baseParams: { command: 'taskSummary', taskid:task.id, courseid:SchoolDynamics.currentCourseID},
                              requiredBaseParams: new Array('courseid', 'quarter', 'taskid')
                           });
                           popup.show();
                        }
                     }]
      			   },{ //student actions
                     id: 'student',
         				text: 'Student: '+student.data.StudentName,
         				menu:[{
                        text: (taskdropped?'Und':'D')+'rop this grade',
            				handler: function(){
                           Ext.Ajax.request({
                              url: 'teacher_tools/gradebook_data.json.php',
                              params: { command: (taskdropped?'undropGrade':'dropGrade'), taskid:task.id, studentid: student.id },
                              success: function(r){
                                 eval("var results = "+r.responseText.trim());
                                 student.set(task.id+'_dropped', !taskdropped);
                              }
                           });
                        }
                     },{
                        text: 'Add memo',
                        handler: function(button) {
                        
                           var memobox = Ext.MessageBox.getDialog('Memo');
                           memobox.saveMemo = function(text) {
                              Ext.Ajax.request({
                                 url: 'teacher_tools/gradebook_data.json.php',
                                 params: { command: 'saveMemo', taskid:task.id, studentid: student.id, memo: Ext.util.JSON.encode(text) },
                                 success: function(r){
                                    eval("var results = "+r.responseText.trim());
                                    if (results.success) Ext.MessageBox.hide();
                                 }
                              });
                           };
                           var memofield = memobox.body.child('textarea');
                           memofield.dom.onkeypress = function(e) {   //maxLength: 50
                              var maxLength = 50;
                              if (e.charCode == 0) {
                                 if (e.keyCode==13) {
                                    memobox.saveMemo(memofield.dom.value);
                                    return false;
                                 }
                                 return true;
                              }
                              return (parseInt(Ext.get(e.target).dom.textLength)+1) <= maxLength; 
                           }
                           Ext.Ajax.request({
                              url: 'teacher_tools/gradebook_data.json.php',
                              params: { command: 'getMemo', taskid:task.id, studentid: student.id},
                              success: function(r){
                                 eval("var results = "+r.responseText.trim());
                                 
                                 Ext.Msg.prompt('Memo', "<b>Student:</b> "+student.data.StudentName+"<br /><b>Assignment:</b> "+task.data.task+"<br /><b>Grade:</b> "+student.data[task.id], 
                                       function(btn, text){
                                       if (btn == 'ok'){
                                          memobox.saveMemo(text);
                                       }
                                    },
                                 grid, true, results[0].memo);
                              }
                           });
                        }
                     }]
                  }],
         			listeners: {
         			   hide: function(menu) {
                        var r = grid.view.getRow(rowIndex);
                        var cell = Ext.get( r ? r.getElementsByTagName('td')[columnIndex] : false );
                        cell.removeClass('highlight');
                  	   grid.contextMenu.destroy();
         			   }
         			}
         		});
         		
               
               e.stopEvent();
            	var xy = e.getXY();
            	this.contextMenu.showAt(xy);
            }
         }
      }
   });
};
Ext.extend(gradebookGrid, Ext.grid.EditorGridPanel);


