<mt:setvarblock name="page_title"><__trans phrase="Manage [_1]" params="<mt:var name="object_label_plural">"></mt:setvarblock>

<mt:setvarblock name="system_msg">
<div id="msg-block"></div>
</mt:setvarblock>

<mt:loop name="list_headers">
  <mt:include name="$filename" component="$component">
</mt:loop>

<mt:setvarblock name="list_actions">
        <div class="button-actions actions">
          <button type="button" class="save action primary button disabled" disabled="disabled"><__trans phrase="Save Changes"></button>
        </div>
        <div class="indicator"><img alt="<__trans phrase="Loading...">" src="<mt:var name="static_uri">images/indicator.white.gif" /> <__trans phrase="Loading..."></div>
</mt:setvarblock>

<mt:include name="include/header.tmpl">
<mt:include name="include/basic_filter_forms.tmpl">

<div class="listing line">
  <div class="unit size1of1">
    <form id="<mt:var name="object_type">-listing-form" method="POST" action="<mt:var name="script_url">">
      <input type="hidden" name="__mode" value="" />
      <input type="hidden" name="_type" value="<mt:var name="object_type">" />
      <input type="hidden" name="action_name" value="" />
      <input type="hidden" name="itemset_action_input" value="" />
      <input type="hidden" name="items" value="" />
      <input type="hidden" name="magic_token" value="<mt:var name="magic_token">" />
      <mt:if name="return_args"><input type="hidden" name="return_args" value="<mt:var name="return_args">" /></mt:if>
      <mt:if name="blog_id"><input type="hidden" name="blog_id" value="<mt:var name="blog_id">" /></mt:if>

      <div id="actions-bar-top" class="actions-bar actions-bar-top line">
        <mt:var name="list_actions">
      </div>

      <div id="area-action" class="mod sortable-header">
        <select id="itemlist" name="itemlist" class="disabled" disabled="disabled">
          <option id="opt-0" value="0"><__trans phrase="Top Level"></option>
        </select>
        <input type="text" name="<mt:var name="object_type" lower_case="1">_label" class="text short disabled" disabled="disabled" placeholder="<__trans phrase="[_1] label" params="<mt:var name="object_label">">">
        <button type="submit" class="add button disabled" disabled="disabled"><__trans phrase="Add"></button>
      </div>

      <div id="root" class="sortable"></div>

      <div id="actions-bar-bottom" class="actions-bar actions-bar-bottom line">
        <mt:var name="list_actions">
      </div>

    </form>
  </div>
</div>

<div id="dialog-change-basename" class="dialog" style="display: none;">
  <div class="dialog-msg-block"></div>
<mt:if name="object_type" eq="category">
  <mtapp:setting
     id="new-label"
     label="<__trans phrase="Label">"
     label_class="top-label">
    <input type="text" id="new-label" class="text full required">
  </mtapp:setting>
</mt:if>
  <mtapp:setting
     id="new-basename"
     label="<__trans phrase="_CATEGORY_BASENAME">"
     label_class="top-label">
    <input type="text" id="new-basename" class="text full required">
  </mtapp:setting>
  <div class="dialog actions-bar">
    <button
       type="submit"
       id="change-and-move"
       class="action primary button">
      <__trans phrase="Change and move">
    </button>
    <button
       type="button"
       id="cancel-move"
       class="action button">
      <__trans phrase="Cancel">
    </button>
  </div>
</div>

<mt:setvarblock name="jq_js_include" append="1">
jQuery('div.indicator')
  .hide()
  .bind('ajaxStart', function() {
    jQuery(this).show();
  })
  .bind('ajaxStop', function() {
    jQuery(this).hide();
  });

var dummy = 1;
var checksum = '';
var isdirty = false;
var indent = 35;
var root_pos = jQuery('#root').position();

function setDirty( dirty ) {
    isdirty = dirty;
    if ( isdirty ) {
        jQuery('button.save').removeAttr('disabled').removeClass('disabled');
    }
    else {
        jQuery('button.save').attr('disabled', 'disabled').addClass('disabled');
    }
}

function loginAgain(fn) {
  jQuery(window)
    .unbind('dialogReady.loginAgain')
    .bind('dialogReady.loginAgain', function(){
      var dialog = jQuery('#mt-dialog-iframe').contents();
      dialog
        .find('#sign-in-button')
          .text('<__trans phrase="Continue" escape="js">')
          .unbind()
          .click(function(){
            dialog.find('#msg-block').empty();
            jQuery.ajax({
              type: 'POST',
              contentType: 'application/x-www-form-urlencoded; charset=utf-8',
              async: false,
              url: '<mt:var name="script_url">',
              dataType: 'json',
              data: {
                __mode: 'login_json',
                username: dialog.find('#username').val(),
                password: dialog.find('#password').val()
              },
              success: function(data) {
                var token = data.result['magic_token'];
                if (token) {
                  jQuery('input[name="magic_token"]').val(token);
                  jQuery('a[href*="magic_token="]').each(function() {
                    var replace = jQuery(this)
                      .attr('href')
                      .replace(/magic_token=[\d\w]+/, 'magic_token=' + token);
                    jQuery(this).attr('href', replace);
                  });
                }
                jQuery.fn.mtDialog.close();
                fn(data);
                return false;
              },
              error: function(data) {
                dialog.find('#password').val('');
                dialog
                  .find('#msg-block')
                  .append('<div class="msg msg-error"><__trans phrase="Invalid login." escape="js"></div>');
              }
            });
            return false;
          });
    });
  jQuery.fn.mtDialog.open('<mt:var name="script_url">?__mode=dashboard');
}

function handleMessages( data ) {
  jQuery('#msg-block').empty();
  if ( data.error ) {
    jQuery('#msg-block').append(
      '<div class="msg msg-error"><p class="msg-text">'
      + data.error
      + '</p>'
      + '<span class="mt-close-msg close-link clickable icon-remove icon16 action-icon"><__trans phrase="Close" escape="js"></span>'
      + '</div>');
    return false;
  }
  if ( !data.result ) return false;
  var messages = data.result.messages;
  if ( !data.result.messages ) return true;
  for ( var i=0; i < messages.length; i++ ) {
    var msg   = messages[i];
    var text  = msg.msg;
    var cls   = msg.cls;
    jQuery('#msg-block').append(
      '<div class="msg msg-' + cls + '"><p class="msg-text">'
      + text
      + '</p>'
      + '<span class="mt-close-msg close-link clickable icon-remove icon16 action-icon"><__trans phrase="Close" escape="js"></span>'
      + '</div>');
  }
  return true;
}

function fixInteractions( options ) {
  var defaults = {
    sortable: true,
    closeInlineForms: true
  };
  var opts = jQuery.extend(defaults, options);
  if ( opts.closeInlineForms ) {
    jQuery('div.edit-form button.cancel').click();
    jQuery('div.add-form button.cancel').click();
  }

  if ( opts.sortable ) {
    jQuery('.sort-tab').show();
  }
  else {
    jQuery('.sort-tab').hide();
  }
}

jQuery('div#area-action input[name=category_label]').focus( function() {
  fixInteractions();
});

// id and parent should be numbers
function createItem(id, parent, label, basename, number) {
  var line = '<span class="sort-tab"></span>';
  line += '<span class="item-label">'+label+'</span>';
  if ( basename )
    line += '<span class="item-basename"><span class="item-basename-text">'+basename+'</span></span>';
  line += ' <span class="item-ctrl"></span>';
  line += ' <span class="count">'+number+'</span>';
  var $item = jQuery('<div id="cat-'+id+'" class="pcat-'+parent+'" />').append(line);
  return $item;
}

function initItem($item) {
  var id = $item.attr('id');
  var catid = id.slice(4);
  $item.attr('class').match(/\bpcat-(\w+)\b/);
  var parent = RegExp.$1;
  var nest = countNested(parent, []);
  $item.css('margin-left', nest.length*indent)
    .addClass(jQuery.map(nest, function (a){ return 'pcat-'+a; }).join(' '))
    .addClass('lv-'+nest.length)
    .addClass('sortable-item');
  $item.find('.item-ctrl, .edit-form').remove();
  $item.append('<span class="item-ctrl" />');

  jQuery('<a href="#" class="item-action edit-link clickable"><__trans phrase="Rename" escape="js"></a>')
    .appendTo($item.find('.item-ctrl'))
    .bind('click', function() {
      fixInteractions({
        sortable: false
      });
      var $element = jQuery(this).parent('.item-ctrl').parent('div');
      var $label = $element.find('.item-label a').length ? $element.find('.item-label a') : $element.find('.item-label');
      var $basename = $element.find('.item-basename-text');
      var $children = $element.children().hide();
      var $form = jQuery('<div class="edit-form"/>')
        .append(jQuery('<input type="text" name="<mt:var name="object_type" lower_case="1">_label" class="text short label" placeholder="<__trans phrase="Label" escape="js">" />'));
      $form.find('.label').val($label.text());
      $form.append(jQuery('<input type="text" name="<mt:var name="object_type" lower_case="1">_basename" class="text short basename" placeholder="<__trans phrase="Basename" escape="js">" />'));
      $form.find('.basename').val($basename.text());
<mt:if name="object_type" eq="category">
      jQuery.mtValidateRules['.label'] = function ($e) {
        if ( !$e.val().length ) return this.raise('<__trans phrase="Label is required." escape="js">');
        return hasDupe(parent, catid, $e.val()) ? this.raise('<__trans phrase="Duplicated label on this level." escape="js">') : true;
      };
<mt:else>
      jQuery.mtValidateRules['.label'] = function ($e) {
        if ( !$e.val().length ) return this.raise('<__trans phrase="Label is required." escape="js">');
        return true;
      };
</mt:if>
      jQuery.mtValidateRules['.basename'] = function ($e) {
        if ( !$e.val().length ) return this.raise('<__trans phrase="Basename is required." escape="js">');
        if ( $e.val().match(/[^\w\-]/) ) return this.raise('<__trans phrase="Invalid Basename." escape="js">');
        return hasDupe(parent, catid, null, $e.val()) ? this.raise('<__trans phrase="Duplicated basename on this level." escape="js">') : true;
      };

      jQuery('<button type="submit" class="rename button"><__trans phrase="Rename" escape="js"></button>')
        .bind('click', function() {
          if ( !$element.find('input.label, input.basename').mtValidate() ) return false;
          fixInteractions({ closeInlineForms: false });
          $basename.text( $element.find('input.basename').val() );
          $label.text( $element.find('input.label').val() );
          $children.show();
          initItem($item);
          setItemList();
          setDirty(true);
        })
        .appendTo($form);
      jQuery('<button type="button" class="cancel button"><__trans phrase="Cancel" escape="js"></button>')
        .bind('click', function() {
          fixInteractions({ closeInlineForms: false });
          $children.show();
          initItem($item);
        })
        .appendTo($form);
      $form.appendTo($element);
      $form.find('.label, .basename').bind('keypress', function (e) {
        if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
          $form.find('button.rename').click();
          return false;
        }
      });
      $form.find('.label').focus();
      return false;
    });

  jQuery('<span class="item-action plus clickable icon-plus icon16 action-icon"><__trans phrase="Add child [_1]" params="<mt:var name="object_label">" escape="js"></span>')
    .appendTo($item.find('.item-ctrl'))
    .bind('click', function() {
      fixInteractions({ sortable: false });
      var $element = jQuery(this).parent('.item-ctrl').parent('div');
      var parent = $element.attr('id').slice(4);
      var $form = jQuery('<div class="mod add-form"><input type="text" name="<mt:var name="object_type" lower_case="1">_label" class="text short" placeholder="<__trans phrase="[_1] label" params="<mt:var name="object_label">" escape="js">" />\n</div>');
      $form.css('margin-left', (nest.length+1)*indent).insertAfter($element).find('input[name=<mt:var name="object_label" lower_case="1">_label]').focus();
      jQuery('<button type="button" class="add button"><__trans phrase="Add" escape="js"></button>')
        .bind('click', function() {
          var label = jQuery(this).parent('.add-form').find('input').val();
          // sort of hack to do HTML escape.
          label = jQuery('<div />').text(label).html();
          if ( addItem(parent, label) ) {
              jQuery(this).parent('.add-form').remove();
              fixInteractions({ closeInlineForms: false });
          }
        })
        .appendTo($form);
      jQuery('<button type="button" class="cancel button"><__trans phrase="Cancel" escape="js"></button>')
        .bind('click', function() {
            fixInteractions({ closeInlineForms: false });
            jQuery('#msg-block').empty();
            jQuery(this).parent('.add-form').remove();
        })
        .appendTo($form);
      jQuery('.button').button();
    });

  jQuery('<span class="item-action delete clickable icon-delete icon16 action-icon"><__trans phrase="Remove [_1]" params="<mt:var name="object_label_plural">" escape="js"></span>')
    .appendTo($item.find('.item-ctrl'))
    .bind('click', function() {
      fixInteractions();
      var id = jQuery(this).parents('.sortable-item').attr('id').slice(4);
      removeItems(id);
    });
  setHoverAction($item);
}

// parent and id should be numbers
function hasDupe( parent, id, label, basename ) {
  var $parent = jQuery('#cat-' + parent);
  $parent.attr('class').match(/lv-(\w+)/);
  var parent_level = parseInt(RegExp.$1);
  if ( isNaN(parent_level) ) parent_level = -1;
  var level = parent_level + 1;
  var dupe = false;
  jQuery('.pcat-' + parent + '.lv-' + level).each( function () {
      if ( id && ( ('cat-'+id) == jQuery(this).attr('id') ) ) return true;
<mt:if name="object_type" eq="category">
      var sibling_label = jQuery(this).find('.item-label').text();
      if ( ( label && sibling_label == label ) ) {
        dupe = true;
        return false;
      }
</mt:if>
      var sibling_basename = jQuery(this).find('.item-basename-text').text();
      if ( ( basename && sibling_basename == basename ) ) {
        dupe = true;
        return false;
      }
  });
  return dupe;
}

function makeBasename( parent, id, label ) {
  var limit = <mt:var name="basename_limit" />;
  var basename = dirify( label ).substr( 0, limit );
  if ( !basename.length ) basename = '<mt:var name="basename_prefix">';
  var $parent = jQuery('#cat-' + parent);
  $parent.attr('class').match(/lv-(\w+)/);
  var parent_level = parseInt(RegExp.$1);
  if ( isNaN(parent_level) ) parent_level = -1;
  var level = parent_level + 1;

  var max = -1;
  var re = new RegExp( '^' + basename + '(<mt:unless name="config.CategoryNameNodash">\\-</mt:unless>([1-9][0-9]*))?$' );
  jQuery('.pcat-' + parent + '.lv-' + level).each( function () {
    if ( id && id == jQuery(this).attr('id') ) return true;
    var sibling_basename = jQuery(this).find('.item-basename-text').text();
    if ( sibling_basename.match(re) ) {
      var num = parseInt(RegExp.$2) || 0;
      if ( max < num ) max = num;
    }
    return true;
  });
  max++;
  return max > 0 ? basename <mt:unless name="config.CategoryNameNodash">+ '-' </mt:unless>+ max : basename;
}

// parent should be a number
function addItem(parent, label) {
  jQuery('#msg-block .additem-error').remove();
  if ( hasDupe( parent, 0, label) ) {
    jQuery('#msg-block').append('<div class="msg msg-error additem-error">'+trans("[_1] '[_2]' already exists.", '<mt:var name="object_label">', label)+'</div>');
    return false;
  }
  if ( !label.length ) {
    jQuery('#msg-block').append('<div class="msg msg-error additem-error">'+trans("Label is required.")+'</div>');
    return false;
  }
  var id = 'x'+dummy;
  var basename = makeBasename(parent, id, label);
  var $item = createItem(id, parent, label, basename, '');
  initItem($item);
  $item.insertAfter(jQuery('#cat-'+parent));

  var nest = countNested(parent, []);
  var nestLevel = nest.length;
  jQuery('#opt-'+parent).after('<option id="opt-'+id+'" value="'+id+'">'+nestedLabel(nestLevel, label)+'</option>');

  dummy++;
  setDirty(true);
  fixZeroStateMessage();
  return true;
}

jQuery('input[name=<mt:var name="object_type">_label]').live('keypress', function (e) {
    if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
        jQuery(this).siblings('button.add').click();
        return false;
    }
});

// id should be numeric / x1
function removeItems(id) {
  var singlar = '<mt:var name="object_label" lower_case="1" escape="js">';
  var plural = '<mt:var name="object_label_plural" lower_case="1" escape="js">';
  var $items = jQuery('.pcat-'+id);
  var count = $items.length + 1;
  var label = jQuery('#cat-'+id).find('.item-label').text();
  var message = (count == 1)
    ? trans('Are you sure you want to remove [_1] [_2]?', singlar, label)
    : trans('Are you sure you want to remove [_1] [_2] with [_3] sub [_4]?', singlar, label, count - 1, (count > 2 ? plural : singlar));
  if (!confirm(message)) {
      return;
  }
  $items.remove();
  jQuery('#cat-'+id).next('.add-form').remove().end().remove();
  jQuery('.sort-tab').show();
  setItemList();
  setDirty(true);
  fixZeroStateMessage();
}

function setItemList() {
  jQuery('#itemlist option').not(':first').remove();
  jQuery('.sortable-item:visible').each(function() {
    var $item = jQuery(this);
    var id = $item.attr('id');
    var catid = id.slice(4);
    var label = $item.find('.item-label').html();
    var nest = countNested(catid, []);
    var nestLevel = nest.length - 1;
    jQuery('#itemlist').append('<option id="opt-'+catid+'" value="'+catid+'">'+nestedLabel(nestLevel, label)+'</option>');
  });
}

// id should be a number, nest a list
function countNested(id, nest) {
  if (id == 0) {
    return nest;
  }
  jQuery('#cat-'+id).attr('class').match(/\bpcat-(\w+)\b/);
  var parent = RegExp.$1;
  nest.push(parent);
  return countNested(parent, nest);
}

function nestedLabel( level, label ) {
  ret = '';
  for( i = 0; i < level; i++ ) {
    ret = '-&nbsp;'+ret;
  }
  return ret + label;
}

function initMoving() {
  var place;
  var original_class;
  jQuery('.sortable').sortable({
    distance: 3,
    opacity: 0.8,
    placeholder: 'ui-state-highlight',
    handle: 'span.sort-tab',
    start: function(event, ui) {
      var $item = jQuery(ui.item);
      original_class = $item.attr('class');
      var id = $item.attr('id').slice(4);
      var count = jQuery('.pcat-'+id).hide().length;
      if (count) {
        var label = (count == 1)
          ? '<mt:var name="object_label" lower_case="1" escape="js">'
          : '<mt:var name="object_label_plural" lower_case="1" escape="js">';
        jQuery('<span class="with"> + '+count+' '+label+' </span>').insertAfter($item.find('.item-basename'));
      }
      $item.find('.item-ctrl').hide();
    },
    stop: function(event, ui) {
      var $item = jQuery(ui.item);
      var id = $item.attr('id');
      var catid = id.slice(4);
      if (!place) place = 0;
      if (catid == place) {
        jQuery('.pcat-'+catid).show();
        return;
      }
      function _stop() {
        $item.find('.with').remove();
        $item.find('.item-basename, .plus, .delete').show();
        $item.attr('class', ('pcat-'+place));
        initItem($item);
        var $last = $item;
        jQuery('.pcat-'+catid).each(function() {
          var $this = jQuery(this).clone();
          jQuery(this).remove();
          $this.attr('class').match(/\bpcat-(\w+)\b/);
          var parent = RegExp.$1;
          $this.attr('class', ('pcat-'+parent));
          initItem($this);
          $this.insertAfter($last).show();
          $last = $this;
        });
        setHoverAction(jQuery('.pcat-'+catid));
        setItemList();
        setDirty(true);
      }

      if (
<mt:if name="object_type" eq="category">
        hasDupe( place, catid, $item.find('.item-label').text() )
        || hasDupe( place, catid, null, $item.find('.item-basename-text').text() )
<mt:else>
        hasDupe(place, catid, null, $item.find('.item-basename-text').text() )
</mt:if>
      ) {

        $item.attr('class', ('pcat-'+place));
        initItem($item);
<mt:if name="object_type" eq="category">
        jQuery.mtValidateRules['#new-label'] = function ($e) {
          return hasDupe(place, catid, $e.val()) ? this.raise('<__trans phrase="Duplicated label on this level." escape="js">') : true;
        };
</mt:if>
        jQuery.mtValidateRules['#new-basename'] = function ($e) {
          return hasDupe(place, catid, null, $e.val()) ? this.raise('<__trans phrase="Duplicated basename on this level." escape="js">') : true;
        };
        jQuery('#new-label').val($item.find('.item-label').text())
        jQuery('#new-basename').val($item.find('.item-basename-text').text())
        jQuery('#change-and-move')
          .unbind('click')
          .bind( 'click', function(){
<mt:if name="object_type" eq="category">
            if ( jQuery('#new-label').mtValidate('simple') && jQuery('#new-basename').mtValidate('simple') ) {
              var $label = $item.find('.item-label a').length ? $item.find('.item-label a') : $item.find('.item-label');
              $label.text( jQuery('#new-label').val() );
              var $basename = $item.find('.item-basename-text');
              $basename.text( jQuery('#new-basename').val() );
              _stop();
              jQuery('#dialog-change-basename').dialog('close');

            }
<mt:else>
            if ( jQuery('#new-basename').mtValidate('simple') ) {
              var $basename = $item.find('.item-basename-text');
              $basename.text( jQuery('#new-basename').val() );
              _stop();
              jQuery('#dialog-change-basename').dialog('close');
            }
</mt:if>
            return false;
          });
        jQuery('#cancel-move')
          .unbind('click')
          .bind('click', function () {
            jQuery('.sortable').sortable('cancel');
            $item.attr('class', original_class);
            jQuery('.pcat-'+catid).show();
            $item.find('.with').remove();
            $item.find('.plus, .delete').show();
            initItem($item);
            setHoverAction(jQuery('.pcat-'+catid));
            setItemList();
            jQuery('#dialog-change-basename').dialog('close');
          });
        jQuery('#dialog-change-basename').dialog({
          title: trans('Alert'),
          dialogClass: 'alert',
          autoOpen: true,
          width: 450,
          modal: true,
          resizable: false,
          draggable: false,
          closeOnEscape: false
        });
<mt:if name="object_type" eq="category">
        jQuery('#new-label, #new-basename').mtValidate('simple');
<mt:else>
        jQuery('#new-basename').mtValidate('simple');
</mt:if>
      }
      else {
        _stop();
      }
    },
    sort: function(event, ui) {
      var $item = jQuery(ui.item);
      $item.attr('class').match(/\bpcat-(\w+)\b/);
      var parent = RegExp.$1;
      $item.attr('class').match(/lv-(\w+)/);
      var level = parseInt(RegExp.$1);

      var $place = jQuery(ui.placeholder);
      var $prev = $place.prevAll().not($item).not(':hidden').filter(':first');
      var prev_id = 0;
      var prev_parent = 0;
      var prev_level = 0;
      if ($prev.length) {
        var prev_id = $prev.attr('id').slice(4);
        $prev.attr('class').match(/\bpcat-(\w+)\b/);
        prev_parent = RegExp.$1;
        $prev.attr('class').match(/lv-(\w+)/);
        prev_level = parseInt(RegExp.$1);
      }
      var nest = countNested(prev_parent, []);
      nest.pop();
      nest.unshift(prev_parent);

      var $next = $place.nextAll().not($item).not(':hidden').filter(':first');
      var next_parent = 0;
      var next_level = 0;
      if ($next.length) {
        $next.attr('class').match(/\bpcat-(\w+)\b/);
        next_parent = RegExp.$1;
        $next.attr('class').match(/lv-(\w+)/);
        next_level = parseInt(RegExp.$1);
      }

      var left = ui.offset.left - root_pos.left;
      var idx = parseInt(Math.abs(left)/indent);
      var d = prev_level < level ? 0 : prev_level - level + 1;
      var pos = 0;

      if (prev_level < next_level) {
        place = prev_id;
        pos = prev_level + 1;
      } else if (prev_level == next_level) {
        if (left > 0) {
          place = prev_id;
          pos = prev_level + 1;
        } else {
          place = prev_parent;
          pos = prev_level;
        }
        if (prev_id == 0) {
          place = prev_parent;
          pos = prev_level;
        }
      } else {
        if (left > 0) {
          if (idx < d) {
            place = nest[d - idx - 1];
            pos = nest.length - (d - idx -1);
          } else {
            place = prev_id;
            pos = nest.length + 1;
          }
        } else if (left < 0) {
          if (idx + d < nest.length) {
            place = nest[idx + d];
            pos = nest.length - (idx + d);
          } else {
            place = next_parent;
            pos = next_level;
          }
        } else {
          place = parent;
          pos = level;
        }
      }
      jQuery('<div class="target"><span class="marker"></span></div>').css('width', pos*indent).appendTo($place.empty());
    }
  });
}

function setHoverAction($elements) {
  $elements.hover(function() {
    var parent = jQuery(this).addClass('highlight on').attr('id').slice(4);
    jQuery('.pcat-'+parent).addClass('highlight');
  }, function() {
    var parent = jQuery(this).removeClass('highlight on').attr('id').slice(4);
    jQuery('.pcat-'+parent).removeClass('highlight');
  });
}

function renderItems(data) {
  jQuery('#root').empty();
  jQuery('#itemlist option').not(':first').remove();
  jQuery('<div id="cat-0" class="pcat-0 sortable-item" />').hide().appendTo('#root');
  var objs = data.result.objects;
  var count = objs.length;
  for (var i = 0; i < count; i++) {
    var id = parseInt(objs[i][0]);
    var parent = parseInt(objs[i][1]);
    var label = objs[i][2];
    var basename = objs[i][3];
    var number = objs[i][4]
    var $item = createItem(id, parent, label, basename, number);
    initItem($item);
    $item.appendTo('#root');
    var nest = countNested(parent, []);
    var nestLevel = nest.length;
    jQuery('#itemlist').append('<option id="opt-'+id+'" value="'+id+'">'+nestedLabel(nestLevel, label)+'</option>');
  }
  fixZeroStateMessage();
  checksum = data.result.checksum;
  setHoverAction(jQuery('.sortable-item'));

  jQuery('#area-action').children().removeClass('disabled').removeAttr('disabled');
}

function fixZeroStateMessage () {
  if ( jQuery('#root div.sortable-item').length <= 1 ) {
    var message = trans('No [_1] could be found.', '<mt:var name="object_label" lower_case="1" escape="js">');
    jQuery('<p id="zero-state-message">'+message+'</p>').appendTo('#root');
  }
  else
    jQuery('#zero-state-message').remove();
}

function renderNestedList() {
  var params = {
    __mode: 'filtered_list',
    datasource: '<mt:var name="list_type">',
    blog_id: <mt:var name="blog_id">
  };
  jQuery.ajax({
    type: 'POST',
    contentType: 'application/x-www-form-urlencoded; charset=utf-8',
    url: '<mt:var name="script_url">',
    dataType: 'json',
    data: params,
    success: function(data) {
      if ( !handleMessages(data) ) return;
<mt:if name="config.debugmode">
      if (data.result.debug) {
        jQuery('#listing-debug-block').text(data.result.debug);
      }
</mt:if>
      renderItems(data);
    },
    complete: function() {
      jQuery(window).trigger('listReady');
      initMoving();
    },
    error: function(xhr, status) {
      if ( xhr.status == 401 ) {
        loginAgain(function(){
          renderNestedList();
        });
      }
      else if ( xhr.status == 0 ) {
        // Maybe this is user abort. do nothing.
      }
      else {
        alert('Ajax error: ' + xhr.status + ': ' + status);
      }
    }
  });
}

jQuery('.add').click(function() {
  var parent = jQuery(this).parent('#area-action').find('select').val();
  var label = jQuery(this).parent('#area-action').find('input').val();
  // sort of hack to do HTML escape.
  label = jQuery('<div />').text(label).html();
  if ( addItem(parent, label) ) {
    fixInteractions();
    jQuery(this).parent('#area-action').find('input').val('');
  }
  return false;
});

jQuery('.save').click( bulkUpdateCategories );

function bulkUpdateCategories() {
  jQuery('#area-action').children().addClass('disabled').attr('disabled', 'disabled');
  var items = [];
  jQuery('.sortable-item:visible').each(function() {
    var $item = jQuery(this);
    var myid = $item.attr('id').slice(4);
    $item.attr('class').match(/\bpcat-(\w+)\b/);
    var parentid = RegExp.$1;
    items.push({id: myid, parent: parentid, label: $item.find('.item-label').text(), basename: $item.find('.item-basename-text').text() });
  });
  jQuery.ajax({
    type: 'POST',
    contentType: 'application/x-www-form-urlencoded; charset=utf-8',
    url: '<mt:var name="script_url">',
    dataType: 'json',
    data: {
      __mode: 'bulk_update_<mt:var name="object_type">',
      datasource: '<mt:var name="list_type">',
      blog_id: <mt:var name="blog_id">,
      checksum: checksum,
      objects: jQuery.toJSON(items),
      magic_token: jQuery('input[name="magic_token"]').val()
    },
    success: function(data) {
      if ( !handleMessages(data) ) return;
      renderItems(data);
      setDirty(false);
    },
    complete: function() {
      initMoving();
    },
    error: function(xhr, status) {
      if ( xhr.status == 401 ) {
        loginAgain(function(){
          bulkUpdateCategories();
        });
      }
      else
        alert('Ajax error: ' + status);
    }
  });
  return false;
}

jQuery(window).bind('beforeunload', function() {
  if (isdirty) {
    return trans('You have unsaved changes to this page that will be lost.');
  }
});

jQuery(window).bind('listReady', function() {
  jQuery('#area-action').children().removeClass('disabled').removeAttr('disabled');
});
renderNestedList();
</mt:setvarblock>
<mt:include name="include/footer.tmpl">
