/** Basically handles when a user dropes a label onto a written disc. */
  public void onInventoryClick(InventoryClickEvent event) {
    // only on right click.
    if (!event.isLeftClick()) {
      // only if a Label is on the cursor. is it even a custom item?
      if (event.getCursor() != null && new SpoutItemStack(event.getCursor()).isCustomItem()) {

        CustomItem itemOnCursor = (CustomItem) new SpoutItemStack(event.getCursor()).getMaterial();
        if (itemOnCursor instanceof ItemLabel) {

          // yep, its a label. let see what were clicking on.
          if (new SpoutItemStack(event.getItem()).isCustomItem()) {

            // its custom could be a disc...
            CustomItem itemClickedOn =
                (CustomItem) new SpoutItemStack(event.getItem()).getMaterial();
            if (itemClickedOn instanceof ItemBurnedObsidyisc) {
              // its a burned disc! we can do stuff to it.
              String label = plugin.getLabelManager().get(itemOnCursor.getCustomId());

              plugin.getDiscsManager().setTitle(itemClickedOn.getCustomId(), label);
              plugin.getDiscsManager().save();

              itemClickedOn.setName(label);

              // remove the item on the cursor.
              event.setResult(Result.ALLOW);
              event.setCursor(null);

              event.setCancelled(true);
              // return true;
            }
          }
        }
      }
    }
  }
  public boolean handleInventoryClick(
      Packet102WindowClick packet,
      InventorySlotType type,
      SpoutCraftItemStack slot,
      SpoutCraftItemStack cursor,
      Inventory inventory) {
    InventoryClickEvent event = null;
    Result result = Result.DEFAULT;
    boolean success = false;
    final int LEFT_CLICK = 0;
    final int RIGHT_CLICK = 1;
    int click = packet.c;

    // clicked on bottom player inventory
    if (!(this.player.activeContainer instanceof ContainerPlayer)
        && this.player.defaultContainer instanceof ContainerPlayer
        && packet.b >= inventory.getSize()) {
      int activeSlot = packet.b - inventory.getSize() + 9;
      if (activeSlot >= this.getPlayer().getInventory().getSize()) {
        activeSlot -= this.getPlayer().getInventory().getSize();
      }
      type = getInventorySlotType(activeSlot);
      event =
          new InventoryPlayerClickEvent(
              this.getPlayer(),
              this.getPlayer().getInventory(),
              type,
              slot,
              cursor,
              activeSlot,
              click == LEFT_CLICK,
              packet.f,
              activeLocation);
    } else {
      event =
          new InventoryClickEvent(
              this.getPlayer(),
              inventory,
              type,
              slot,
              cursor,
              packet.b,
              click == LEFT_CLICK,
              packet.f,
              activeLocation);
    }

    if (event != null) {
      Bukkit.getServer().getPluginManager().callEvent(event);
      result = event.getResult();
      cursor = SpoutCraftItemStack.getCraftItemStack(event.getCursor());
      slot = SpoutCraftItemStack.getCraftItemStack(event.getItem());
    }

    // initialize setup
    ItemStack itemstack = slot != null ? slot.getHandle() : null;
    ItemStack cursorstack = cursor != null ? cursor.getHandle() : null;

    // NOTE: Successful means that its successful as-is; thus, only becomes true for default
    // behaviour

    switch (result) {
      case DEFAULT:
        itemstack = this.player.activeContainer.a(packet.b, packet.c, packet.f, this.player);
        success = ItemStack.equals(packet.e, itemstack);
        break;
      case DENY:
        if (packet.b != -999) { // Only swap if target is not OUTSIDE
          if (itemstack != null) {
            setActiveSlot(packet.b, itemstack);
            setCursorSlot((ItemStack) null);
          }
          if (event.getCursor() != null) {
            setActiveSlot(packet.b, itemstack);
            setCursorSlot(cursorstack);
          }
        }

        break;
      case ALLOW: // Allow the placement unconditionally
        if (packet.b == -999) { // Clicked outside, just defer to default
          itemstack = this.player.activeContainer.a(packet.b, packet.c, packet.f, this.player);
        } else {
          if (click == LEFT_CLICK
              && (itemstack != null
                  && cursorstack != null
                  && itemstack.doMaterialsMatch(cursorstack))) {
            // Left-click full slot with full cursor of same item; merge stacks
            itemstack.count += cursorstack.count;
            cursorstack = null;
          } else if (click == LEFT_CLICK
              || (itemstack != null
                  && cursorstack != null
                  && !itemstack.doMaterialsMatch(cursorstack))) {
            // Either left-click, or right-click full slot with full cursor of different item; just
            // swap contents
            ItemStack temp = itemstack;
            itemstack = cursorstack;
            cursorstack = temp;
          } else if (click == RIGHT_CLICK) { // Right-click with either slot or cursor empty
            if (itemstack == null) { // Slot empty; drop one
              if (cursorstack != null) {
                itemstack = cursorstack.a(1);
                if (cursorstack.count == 0) {
                  cursorstack = null;
                }
              }
            } else if (cursorstack == null) { // Cursor empty; take half
              cursorstack = itemstack.a((itemstack.count + 1) / 2);
            } else { // Neither empty, but same item; drop one
              ItemStack drop = cursorstack.a(1);
              itemstack.count += drop.count;
              if (cursorstack.count == 0) {
                cursorstack = null;
              }
            }
          }
          // update the stacks
          setActiveSlot(packet.b, itemstack);
          setCursorSlot(cursorstack);
        }
        break;
    }
    return success;
  }