function ListManagement(){
  var self = this;
  self.init();
}
ListManagement.prototype = {
  init: function()
  {
    var self = this;
    self.$el = $('#listtable');
    self.state;
    self.setState('');
    self.limitWarning();
    //self.handleScrollableLabels();
  },

  isBusy: function()
  {
    var self = this;
    return ( self.state == 'new' || self.state == 'edit' || self.state == 'waiting' );
  },

  updateCapacity: function()
  {
    var self = this;
    var w    = $('#capacity-warning .capacitybar').width();
    var used = parseInt( $('#capacity-warning .used').eq(0).text() );
    var capacity = parseInt( $('#capacity-warning .capacity').eq(0).text() );
    var perc = used / capacity;
    if( perc < .9 ) $('#capacity-warning').remove();
    // adjust the width of the mask
    $('#capacity-warning .capacitybar .mask').width( (perc * w) + 'px' );
  },

  limitWarning: function()
  {
    var self = this;
    // set the width of the mask
    if( $('#capacity-warning').length ) self.updateCapacity();
    $('#loadmore a').live( 'click',
      function()
      {
        if( this.href ){
          $.ajax({
            type: "POST",
            url: this.href,
            data: "renderlist-options="+$('#renderlist-options').val(),
            success: function( result )
            {
              self.$el.find('tbody tr:last').remove();
              self.$el.find('tbody').append( result );
              // loop over the added lists and update the list count for any list in groups
              var groups = {};
              $( result ).each(
                function( i,e )
                {
                  if( $(this).hasClass('grouped') ) groups[ self.getGroupIdFromList( $(this) ) ] = 1;
                }
              );
              for( var g in groups ){
                var $grp = $('#'+g);
                if( $grp.hasClass('expand') ) $grp.click();
                $grp.find('.group-count').text( $('.'+g).length+' List(s)' );
              }
              self.enableDnD();
              tooltip();
              self.setState( self.state );
            }
          });
          $(this).addClass('loading').removeAttr('href').html('&nbsp;');
        }
        return false;
      }
    );
  },

  handleScrollableLabels: function()
  {
    $('.list label a').each(
      function()
      {
        if( $(this).width()>=245 ){
          $(this).addClass('tooltip').addClass('hotlinked');
          this.title = $(this).text();
        }
      }
    );
    tooltip();
  },

  setState: function( str )
  {
    var self = this;
    switch( str ){
      case '':
        self.$el.find('.tools a, .changePub').removeClass('blocked');
        $(".tool-group").fancybox({
          ajax:{
            type: "POST"
          }
        });
        self.$el.find(':checkbox').hide();
        $('#grp-menu').removeClass('blocked');
        break;
      case 'edit':
      case 'new':
        self.$el.find('.tools a, .changePub').addClass('blocked');
        $(".tool-group").unbind('click.fb'); // stop fancybox while in edit mode
        self.$el.find(':checkbox').show();
        //self.$el.find('.expand .icon').click();
        break;
      case 'waiting':
        $('#grp-menu').addClass('blocked');
    }
    self.state = str;
  },

  hijackToolEvents: function()
  {
    var self = this;
    $('.changePub').live( 'click',
      function()
      {
        var el=this;
        if( !$(el).hasClass('blocked') ){
          $.ajax({
            type: "POST",
            url: el.href,
            success: function(data) {
              $(el).html(data);
              var id = $(el).parents('tr').attr('id');
              $('#'+id+'.grouped .changePub').html(data);
            }
          });
        }
        return false;
      }
    );
    $('.confirm').livequery( 'click',
      function( e )
      {
        if( !$(this).hasClass('blocked') ){
          pass = confirm( this.title + '\n\nPlease confirm that you want to proceed.' );
          e.stopImmediatePropagation();
          return pass;
        }
        return false;
      }
    );
    $('.editGroup').live( 'click',
      function()
      {
        //if( !$(this).hasClass('blocked') ){
        if( !self.isBusy() ){
          var $row = $(this).parents('tr');
          var row_id = $row.attr('id');
          $.ajax({
            type: "POST",
            url: this.href,
            success: function(data){
              var restore = $row.html();
              if( $row.hasClass('expand') ) $row.find('.icon').click();
              // turn on all checkboxes for lists in group
              $('.'+row_id+' :checkbox').attr('checked',true);
              self.setState('edit');
              $row.addClass('storedrow').clone().appendTo('body');
              $row.replaceWith( data );
              tooltip();
              //var $nrow = $( '#'+row_id+'-edit' );
              var $nrow = $( '#'+row_id );
              // flash the row so it gets noticed
              var cur_color = $nrow.css('backgroundColor');
              $nrow.css("background-color", "#FFFF9C").animate({ backgroundColor: cur_color }, 800);
              // bind event handling
              $('#save-grp').click(
                function( e )
                {
                  $('#frm-listmanagement input[name="task"]').val('groupManagement');
                  $('#frm-listmanagement input[name="mode"]').val('edit');
                  e.stopImmediatePropagation();
                  return true;
                }
              );
              $('#cancel-grp').click(
                function()
                {
                  if( $nrow.hasClass('expand') ) $('.storedrow').removeClass('collapse').addClass('expand');
                  $nrow.replaceWith( $('.storedrow').removeClass('storedrow') );
                  self.setState('');
                  return false;
                }
              );
              $('#frm-listmanagement').validate({
                ignore: ".ignore",
                rules: {
                  grpName: {
                    required: true,
                    minlength: 2
                  }
                }
              });
              $( '#grpName-noedit' ).click(
                function()
                {
                  $( '#grpName-noedit' ).hide();
                  $( '#grpName-noedit-hint' ).hide();
                  $( '#grpName' ).show();
                  return false;
                }
              );
              $( '#grpName' ).click(
                function( e )
                {
                  e.stopImmediatePropagation();
                }
              );
            }
          });
        }
        self.setState('waiting');
        return false;
      }
    );
    $('.tools .delete').live( 'click',
      function( e )
      {
        var el    = this;
        var $el   = $(el);
        var $par  = $el.parent();
        var $tr   = $el.parents('tr');

        if( !$el.hasClass('blocked') && !self.isBusy() && confirm( el.title + '\n\nPlease confirm that you want to proceed.' ) ){
          e.stopImmediatePropagation();
          $el.css({'textDecoration':'none'});
          var preloader = '<span style="padding:0 12px;text-align:center;text-decoration:none;"><img src="/images/ajaxpreloader-fffeab.gif" /></span>';
          var chtml = $el.html();
          $el.html( preloader );
          $.ajax({
            type: "POST",
            url: el.href,
            success: function( result )
            {
              if( $.trim(result) == 'OK' ){
                $( '.'+$tr.attr('id') ).animate({ opacity:0 }, 300,
                  function()
                  {
                    $(this).remove();
                    // update the group list count
                    if( $(this).hasClass('grouped') ){
                      var id = self.getGroupIdFromList( $(this) );
                      var $grp = $('#'+id);
                      if( $grp.length>0 ){
                        var cc = $grp.find('.group-count').html();
                        var nc = cc.split(' List(s)')[0] -= 1;
                        $grp.find('.group-count').html( nc + ' List(s)' );
                      }
                    }
                  }
                );
                // update the total number of lists used
                var u = parseInt( $('#capacity-warning .used').eq(0).text() ) - 1;  // we delete one list at a time
                $('#capacity-warning .used').text( u );
                self.updateCapacity();
                self.setState('');
              } else {
                var msg = '<div id="modal-msg">' + $.trim(result) + '</div><a id="onload-show-modal" href="#modal-msg"/>';
                $('body').append( msg );
                $el.html( chtml );
                $el.css({'textDecoration':'underline'});
              }
              self.setState('');
            }
          });
          self.setState('waiting');
        }
        return false;
      }
    );
  },

  bindClicks: function()
  {
    var self = this;
    // bind the row
    $('#listtable .group').live( 'click',
      function( e )
      {
        $(this).find('.icon').click();
        return false;
      }
    );
    // bind the group expand/collapse icon
    $('#listtable .group .icon').live( 'click',
      function()
      {
        var $row = $(this).parents('.group');
        if( $row.hasClass( 'expand' ) ){
          $row.removeClass('expand').addClass('collapse');
          var c = $row.attr('id');
          $( '.'+c ).show();
          $( '.'+c ).removeClass('hidden').addClass('visible');
        } else {
          $row.addClass('expand').removeClass('collapse');
          var c = $row.attr('id');
          $( '.'+c ).hide();
          $( '.'+c ).removeClass('visible').addClass('hidden');
        }
        return false;
      }
    );
    // toggle the group open state when clicking the group name
    $('#listtable .group .group-name').live( 'click',
      function()
      {
        $(this).siblings().eq(0).click();
        return false;
      }
    );

    // bind checkboxes
    $('#listtable :checkbox').not('.all').change(
      function()
      {
        // change all versions of the list checkbox
        $('.'+this.id).attr('checked',this.checked);
        self.changed = true;
      }
    );
    $('#listtable .grp:checkbox').not('.blocked')
      .click(
        function()
        {
          $this = $(this);
          var $row = $this.parents('tr');
          var c = $row[0].id;
          // check limits before adding selections
          if( self.options != undefined && self.options.max != undefined ){
            if( this.checked ){
              // count how many lists would be turned on
              //console.log( $('#listtable :checkbox:checked').not('.grp, .all').length +' + '+ self.$el.find('.'+c+' :checkbox').length + ' > ' + self.options.max );
              if( $('#listtable :checkbox:checked').not('.grp, .all').length + self.$el.find('.'+c+' :checkbox').length > self.options.max ){
                alert('You may select a maximum of '+self.options.max+' lists for viewing in the gradebook.');
                return false;
              }
            }
          }
          self.$el.find('.'+c+' :checkbox').each(
            function()
            {
              this.checked = $this[0].checked;
            }
          );
        }
      )
      .each(
        function()
        {
          // check the group box if all its members are selected.
          $this = $(this);
          var $row = $this.parents('tr');
          var c = $row[0].id;
          if( self.$el.find('.'+c+' :checkbox:checked').length == self.$el.find('.'+c+' :checkbox').length ) this.checked = true;
        }
      );
    $('#listtable .grouped :checkbox').click(
      function()
      {
        // should the group box be off?
        $this = $(this);
        $grp = $this.parents('.grouped');
        var id = self.getGroupIdFromList( $grp );
        if( self.$el.find('.'+id+' :checkbox:checked').length == self.$el.find('.'+id+' :checkbox').length ){
          if(self.$el.find('#'+id+' :checkbox').length>0) self.$el.find('#'+id+' :checkbox')[0].checked = true;
        } else {
          if(self.$el.find('#'+id+' :checkbox').length>0) self.$el.find('#'+id+' :checkbox')[0].checked = false;
        }
      }
    );
    $('#listtable .all').click(
      function()
      {
        if( !this.checked ){
          self.$el.find(':checkbox').attr('checked',false);
        } else {
          // check limits before adding selections
          if( self.options != undefined && self.options.max != undefined ){
            if( self.$el.find(':checkbox:visible').not('.grp,.all').length > self.options.max ){
              alert('You may select a maximum of '+self.options.max+' lists for viewing in the gradebook.');
              return false;
            }
          }
          self.$el.find(':checkbox').attr('checked',false);
          self.$el.find(':checkbox:visible').each(
            function()
            {
              if( $(this).hasClass('grp') ){
                // open the group
                var $row = $(this).parents('tr');
                if( $row.hasClass('expand') ){
                  $row.find('.icon').click();
                  //$row.removeClass('expand').addClass('collapse');
                }
                var id = $row[0].id;
                self.$el.find( '.'+id+' :checkbox:visible' ).attr('checked',true);
              }
              this.checked = true;
            }
          );
        }
      }
    );

    $('#listtable .blocked').live( 'click',
      function()
      {
        return false;
      }
    );
  },

  bindSearch: function()
  {
    var self = this;

  },

  bindGrpMenu: function()
  {
    var self = this;
    $("#removelists").fancybox({
      onStart: function()
      {
        $("#msgremovelists").show();
        $("#deleteAllForm").validate({
          rules:{
            confirmDelete: {equalTo: "#confirmDeleteText"}
          },
          messages:{
            confirmDelete: {equalTo: "Please enter \"I understand\" to proceed."}
          }
        });
      },
      onClosed: function()
      {
        $("#msgremovelists").hide();
      }
    });
    $('#grp-menu .hijack').click(
      function()
      {
        if( !self.isBusy() ){
          if( this.id != 'removealllists' ){
            $.ajax({
              type: "POST",
              url: this.href,
              data: 'cols='+$('#listtable thead th'.length), // pass the number of columns
              success: function( result )
              {
                // deactivate the tools
                self.setState('new');
                // prepend the new row to the table
                $('#listtable tbody').prepend( result );
                // flash the row so it gets noticed
                var cur_color = $('#listtable tbody tr:first').css('backgroundColor');
                $('#listtable tbody tr:first').css("background-color", "#FFFF9C").animate({ backgroundColor: cur_color }, 800);
                $('#cancel-grp').click(
                  function()
                  {
                    $('#listtable tbody tr:first').remove();
                    self.setState('');
                    return false;
                  }
                );
                $('#listtable .pmmsg a').click(
                  function()
                  {
                    window.location = this.href;
                    return false;
                  }
                );
                if( $('input#grpName').length>0 ){
                  // bind event handling
                  var restore = $('input#grpName')[0].value;
                  $('#grpName')
                    .focus(
                      function()
                      {
                        if( this.value == restore ) this.value = '';
                      }
                    )
                    .blur(
                      function()
                      {
                        if( this.value == '' ) this.value = restore;
                      }
                    );
                  $('#save-grp').click(
                    function( e )
                    {
                      $('#frm-listmanagement input[name="task"]').val('groupManagement');
                      $('#frm-listmanagement input[name="mode"]').val('new');
                      e.stopImmediatePropagation();
                      return true;
                    }
                  );
                  $.validator.addMethod( "notDefault", function(value, element) {
                    return this.optional(element) || value != 'Enter Group Name';
                  }, "Please enter a valid group name to proceed." );
                  $('#frm-listmanagement').validate({
                    ignore: ".ignore",
                    rules: {
                      grpName: {
                        required: true,
                        minlength: 2,
                        notDefault: true
                      }
                    }
                  });
                }
              }
            });
          } else {
            $.ajax({
              type: "GET",
              url: this.href,
              data: '',
              success: function( result )
              {

              }
            });
            return false;
          }
        }
        self.setState('waiting');
        return false;
      }
    );
  },

  toggleGroup: function( $grp )
  {
    var self = this;
    // hide the group if all its children are hidden
    if( $grp.length ){
      var c = $grp.attr('id');
      var hide = true;
      if( $('#listtable').find('tr.'+c+':visible').length ){
        $grp.removeClass('expand').addClass('collapse');
        $grp.show();
        $grp.removeClass('removed');
      } else {
        $grp.removeClass('collapse').addClass('expand');
        $grp.hide();
        $grp.addClass('removed');
      }
    }
  },

  getGroupIdFromList: function( $row )
  {
    var ret = '';
    $( $row.attr('class').split(' ') ).each(
      function()
      {
        if( this.match(/\group-/) ) ret = this;
      }
    );
    return ret;
  },


  enableDnD: function()
  {
    if( typeof $.tableDnD != 'undefined' ){
      var self = this;
      var orig_pos;
      self.$el.tableDnD({
        onDragClass: "dragging",
        dragHandle: "handle",
        onDrop: function( table, row ){
          var $row = $(row);
          var arr = ['orig_pos='+orig_pos];
          var options = [];
          var data;
          if( $row.hasClass('grouped') ){
            var id = self.getGroupIdFromList( $row ); // returns a string, e.g. 'group-47'
            grp = id.split('-')[1];
            arr.push( 'group='+grp );
            var new_pos = $( '.'+id ).index( $row );
            var list_id = $row.find('input[name^=options]').val();
            arr.push( 'new_pos='+new_pos );
            arr.push( 'id='+list_id );
            $( '.'+id+' input[name^=options]').each(
              function(i)
              {
                options.push( 'o['+i+']=' + this.value );
              }
            );
            arr.push( options.join('&') );
            data = arr.join('&');
          } else {
            var new_pos = $( '.list' ).not('.grouped').index( $row );
            var list_id = $row.find('input[name^=options]').val();
            arr.push( 'new_pos='+new_pos );
            arr.push( 'id='+list_id );
            $( '.list' ).not('.grouped').find('input[name^=options]').each(
              function(i)
              {
                options.push( 'o['+i+']=' + this.value );
              }
            );
            arr.push( options.join('&') );
            data = arr.join('&')
          }

          $.ajax({
              type: "POST",
              url:  "components/com_spellcity/orderListsGroups.php",
              data: data,
              success: function( data )
              {
              }
          });
        },
        onDragStart: function( table, cell ){
          var $row = $(cell).parent();
          if( $row.hasClass('grouped') ){
            var id = self.getGroupIdFromList( $row );
            orig_pos = $( '.'+id).index( $row );
          } else {
            orig_pos = $( '.list' ).not('.grouped').index( $row );
          }
        },
        onAllowDrop: function( drow, row ){
          var $drow = $(drow);
          var $row = $(row);
          if( $row.hasClass('groupless-divider') ) return false;
          if( $row.hasClass('steploader') ) return false;
          if( $row.hasClass('group') ) return false;
          if( $drow.hasClass('grouped') ){
            var id = self.getGroupIdFromList( $drow );
            if( !$row.hasClass(id) ) return false;
          } else {
            if( $row.hasClass('grouped') ) return false;
          }
          return true;
        }
      });
    }
  }

}

var lm;
$().ready(
  function()
  {
    lm = new ListManagement();
  }
);
