Ext.classroom = Ext.extend(Ext.Panel, {
  hidden: true,
  border: false,
  cls: 'classroom',
    constructor: function(config) {
        Ext.classroom.superclass.constructor.apply(this, arguments);
         this.addEvents('load');
        //this.resetDesks(1,1);
    },
    setRows: function(num) {
        this.changed = true;
        this.prevColumns = this.columns;
        this.prevRows = this.rows;
        this.rows = num;
        this.setDesks();
    },
    setColumns: function(num) {
        this.changed = true;
        this.prevRows = this.rows;
        this.prevColumns = this.columns;
        this.columns = num;
        this.setWidth(num*96 + 210);
        this.setDesks();
    },
    setDesks : function(){
    
      if (this.items != undefined){
        lastDeskNum =  this.items.length - 1;
      }
      
      if(this.prevRows > this.rows){                                    //The teacher specified there are fewer rows in the room, delete rows from the bottom
        numToDelete = this.columns * (this.prevRows - this.rows);
        for(i = 0; i < numToDelete; i++){
          lastDesk = this.items.items[lastDeskNum];
          if (lastDesk.items.items[0].gender != '') {
            Ext.getCmp(this.studentData).addStudent(lastDesk.items.items[0]);
          }
          this.remove(lastDesk);
          lastDeskNum--;  
        }
      } else if (this.prevColumns > this.columns) {                   //The teacher specified there are fewer columns in the room, delete columns from the right
        numColToDelete = this.prevColumns - this.columns;
        numToDelete = this.rows * numColToDelete + numColToDelete;
        for(i = 0; i < numToDelete; i++){
          lastDesk = this.items.items[lastDeskNum];
          if (lastDesk.items != undefined && lastDesk.items.items[0].gender != '') {
            Ext.getCmp(this.studentData).addStudent(lastDesk.items.items[0]);
          }
          this.remove(lastDesk);                      
          lastDeskNum -= this.prevColumns;
          if (lastDeskNum < 0){
            lastDeskNum =  this.items.length - 1;
            this.prevColumns -= 1;
          }  
        } 
      } else if (this.rows > this.prevRows){                          //The teacher specified there are more rows in the room, add rows to the bottom
        num = this.columns * (this.rows - this.prevRows);
        for (i = 0; i < num; i++){
          this.add({xtype: 'desk'});
        }
      } 
      else if (this.columns > this. prevColumns){                    //The teacher specified there are more columns in the room, add columns to the right
        
        while (this.prevColumns < this.columns){
          this.insert(this.prevColumns,{xtype: 'label', text: 'Row ' + ('A B C D E F G H I'.split(' '))[this.prevColumns],cls: 'deskCol'});
          this.prevColumns++;
          for(i = 0; i < this.rows; i++){
            this.insert(this.prevColumns * (i+2) - 1,{xtype: 'desk'});
          }
        }
      }
      var myTree = Ext.getCmp(this.studentData);
      var myTreeSorter = new Ext.tree.TreeSorter(myTree, {property: 'lname'});
      myTreeSorter.doSort(myTree.getRootNode());             
      this.doLayout();
      this.doConfig();      
    },
    resetDesks : function(numRows,numCols, reset){
      if (this.items != undefined) {this.clearDesks(reset);}
      this.removeAll();
      this.prevRows = numRows;
      this.rows = numRows;
      this.prevColums = numCols;
      this.columns = numCols;
      num = numRows * numCols;
      for(i=0; i < numCols; i++){
        this.add({xtype: 'label', text: 'Row ' + ('A B C D E F G H I'.split(' '))[i],cls: 'deskCol'});
      }
      for(i = 0; i < num; i++){
        this.add({xtype: 'desk'});
      }
        this.setWidth(numCols*96 + 210);
      this.doLayout();  
    },
    //Setting reset to true will prevent cleardesks from putting students back into the grid
    clearDesks : function(reset){
      this.changed = true;
      myTree = Ext.getCmp(this.studentData);
      numDesks = this.items.length -  this.columns;
      for (i = 0; i < numDesks; i++){
        desk = this.items.items[i + this.columns];
        if (desk.items.items[0].gender != '' && (reset == undefined || !reset)) {
          myTree.addStudent(desk.items.items[0]);
        }
         desk.items.items[0].clear();
      }
      var myTreeSorter = new Ext.tree.TreeSorter(myTree, {property: 'lname'});
      myTreeSorter.doSort(myTree.getRootNode());  
    },
    fillH : function(){
      this.changed = true;
      this.clearDesks();
      numDesks = this.items.length -  this.columns;
      root = Ext.getCmp(this.studentData).getRootNode();
      numStudents = root.childNodes.length;
      for (i = 0; i < numDesks && i < numStudents; i++){
        selectedNode = root.childNodes[0];
        desk = this.items.items[i + this.columns];
        if (desk.items.items[1].iconCls == "delete"){
          desk.items.items[0].addToDesk(selectedNode);
          selectedNode.remove();
        } else {
          numStudents++;
        }
      }
    },
    fillV : function() {
      this.changed = true;
      this.clearDesks();
      numDesks = this.items.length - this.columns;
      root = Ext.getCmp(this.studentData).getRootNode();
      numStudents = root.childNodes.length;
      deskIndex = 0;
      for (i = 0; i < numDesks && i < numStudents; i++){
        selectedNode = root.childNodes[0];
        desk = this.items.items[deskIndex + this.columns];
        if (desk.items.items[1].iconCls == "delete"){
          desk.items.items[0].addToDesk(selectedNode);
          selectedNode.remove();
        } else {
          numStudents++;
        }
        deskIndex += this.columns;
        if(deskIndex > numDesks - 1){
          deskIndex = deskIndex - (numDesks - 1);
        }
      }
    },
    fillR : function(){
      this.changed = true;
      this.clearDesks();
      numDesks = this.items.length -  this.columns;
      root = Ext.getCmp(this.studentData).getRootNode();
      numStudents = root.childNodes.length;
      for (i = 0; i < numDesks && i < numStudents; i++){
        selectedNode = root.childNodes[Math.floor(Math.random()*root.childNodes.length)];
        desk = this.items.items[i + this.columns];
        if (desk.items.items[1].iconCls == "delete"){
          desk.items.items[0].addToDesk(selectedNode);
          selectedNode.remove();
        } else {
          numStudents++;
        }
      }
    },
    getDeskLocation : function(deskIndex){
      return (('A B C D E F G H I'.split(' '))[(deskIndex % this.columns)] + (Math.floor(deskIndex / this.columns)+1));    
    },
    getDeskIndex : function(deskLocation){
      letters = {'A':1, 'B':2, 'C':3, 'D':4, 'E':5, 'F':6, 'G':7, 'H':8};
      column = letters[deskLocation.substring(0,1)];
      row = deskLocation.substring(1);
      return ((this.columns * row) - (this.columns - column)) - 1; 
        
    },
    getStuLocations : function() {
      stuLocations=new Array();
      numDesks = this.items.length -  this.columns;
      for (i = 0; i < numDesks; i++){
        desk = this.items.items[i + this.columns];
        if (desk.items.items[0].gender != '') {
          stuLocation = new Object;
          stuLocation.stuID = desk.items.items[0].stuID;
          stuLocation.deskLocation = this.getDeskLocation(i);
          stuLocations.push(stuLocation);
        }
      }
      return stuLocations;
    },
    setStuLocations : function(stuLocations){
      stuTree = Ext.getCmp(this.studentData);
      Ext.each(stuLocations,function(stuLocation, index){
        node = stuTree.getStudent(stuLocation.stuID);
        if (node != null) {
          deskIndex = parseInt(this.getDeskIndex(stuLocation.deskLocation),10) + parseInt(this.columns,10);
          if (this.items.items[deskIndex] != undefined){
            this.items.items[deskIndex].items.items[0].addToDesk(node);
            node.remove();
          }
        } else {
           Ext.Msg.alert('Error', 'StuID ' + stuLocation.stuID + ' not found in student selection');
        }
        
      }, this);

    },
    getHiddenDesks : function(){
      hiddenDesks=new Array()
      numDesks = this.items.length -  this.columns;
      for (i = 0; i < numDesks; i++){
        desk = this.items.items[i + this.columns];
        if (desk.items.items[0].hidden) {
          hiddenDesks.push(this.getDeskLocation(i));
        }
      }
      return hiddenDesks;
    },
    setHiddenDesks : function(hiddenDesks){
      for (i = 0; i < hiddenDesks.length; i++){
         desk = this.items.items[this.getDeskIndex(hiddenDesks[i])+this.columns];
         if (desk != undefined && desk.items.items[1].iconCls == 'delete'){
          desk.items.items[1].handler();
         }  
      }
    },
    setCourseID : function(id){
      this.courseID = id;
    },
    doConfig : function(){
      if (this.config == 3 || this.config == 4) {
        evenCols = (this.columns % 2 == 0);            
        for (i = 0; i < this.items.length; i++){
          classItem = this.items.items[i];
          classItem.removeClass('config1');
          classItem.removeClass('config3');
          classItem.addClass('config3Left');
          if (((i < this.columns || evenCols) && i % 2 != 0) || (i > this.columns && !evenCols && ((i+1) % this.columns) % 2 == 0 && ((i+1) % this.columns) != 0)){
            classItem.addClass('config3');
          }
        }
      }
      else if (this.config == 1 || this.config == 2 || this.config == 0) {      
        for (i = 0; i < this.items.length; i++){
          classItem = this.items.items[i];
          classItem.removeClass('config3');
          classItem.removeClass('config3Left');
          classItem.addClass('config1');
        }
      }      
    },
    setConfig : function(num){
      this.config = num;
      this.doConfig();
      this.changed = true;
    },
    setOmitted  : function(omittedNum){
        if (omittedNum > this.columns) {
          omittedNum = this.columns;
        }    
        middle = Math.ceil(this.columns / 2);
        if (middle == this.columns / 2) {
          middle++;
        }
        curIndex = this.columns + middle - Math.ceil(omittedNum / 2);
        while (omittedNum > 0) {
            desk = this.items.items[curIndex];
            if (desk != undefined){
               if (desk.items.items[1].iconCls == 'delete'){
                desk.items.items[1].handler();
               } 
            }
            /*
            if (this.columns % 2 == 0){
              ((curIndex + 1) % 2 == 0)? curIndex-- : curIndex += this.columns + 1;
            } else {
              (((curIndex + 1) % this.columns) % 2 == 0)? curIndex++ : curIndex += this.columns - 1;
            }              */
            
            curIndex++;           

            omittedNum--;
        } 
      
    },
    save : function(){
      if (this.changed) 
      {
        if(this.baseParams != undefined && this.url != undefined && this.courseID != undefined){
          myParams = this.baseParams;  
          classroomData = new Object;
          classroomData.hidden = this.getHiddenDesks();
          classroomData.stuLocs = this.getStuLocations();
          classroomData.courseID = this.courseID;
          classroomData.rows = this.rows;
          classroomData.columns = this.columns;
          classroomData.config = this.config;
          classroomData.omitdesks = 0;        
          
          myParams.classroomData = Ext.util.JSON.encode(classroomData);
          myParams.action = 'save';
           
          Ext.Ajax.request({
             url: this.url,
             method: 'POST',
             success: function(){
             
             
             },
             failure: function(){
               Ext.Msg.alert('Error', 'Unable to save classroom.');
             },
             params: myParams
          });
        }
      }
   
    },
    load : function(){
      if(this.baseParams != undefined && this.url != undefined && this.courseID != undefined){
          myParams = this.baseParams;
          myParams.courseID = this.courseID;
          myParams.action = 'load';  
          Ext.Ajax.request({
            url: this.url,
            method: 'POST',
            classroom: this,
            params: myParams,
            scope: this,
            success: function(responseObject) {
                 this.resetDesks(1,1,true);
                 classroomData = Ext.util.JSON.decode(responseObject.responseText);
                 this.setRows(parseInt(classroomData.rows,10));
                 this.setColumns(parseInt(classroomData.columns,10));
                 this.setStuLocations(classroomData.stuLocs);
                 this.setHiddenDesks(classroomData.hidden);
                 this.courseID = classroomData.courseID;
                 this.config = classroomData.config;
                 this.doConfig();
                 this.setOmitted(classroomData.omitdesks);
                 this.changed = false;
                 this.loaded = true;
                 if (classroomData.omitdesks > 0){
                    this.changed = true;
                    if (this.config == 2 || this.config == 4){
                      this.config--;
                    } 
                    
                 }
                 this.fireEvent('load');                 
            },
            failure: function() {
                Ext.Msg.alert('Error', 'Unable to load classroom.');
            }
          });
        
      }
    }
});
Ext.ComponentMgr.registerType('classroom', Ext.classroom);
