package roycurtis.signshopexport.signshop;

import org.bukkit.Location;
import org.bukkit.block.Sign;
import org.bukkit.inventory.ItemStack;
import org.wargamer2010.signshop.Seller;
import org.wargamer2010.signshop.configuration.Storage;
import org.wargamer2010.signshop.util.economyUtil;
import org.wargamer2010.signshop.util.itemUtil;
import roycurtis.signshopexport.DataSource;
import roycurtis.signshopexport.json.Record;

public class SSDataSource implements DataSource
{
    private Seller[] signs;

    public int prepare()
    {
        int total = Storage.get().shopCount();

        signs = Storage.get().getSellers().toArray(new Seller[total]);

        return total;
    }

    /** Creates a record from a SignShop "seller", using SignShop's utility functions for data */
    public Record createRecordForIndex(int idx)
    {
        Seller   seller = signs[idx];
        Record   rec    = new Record();
        Location loc    = seller.getSignLocation();
        Sign     sign   = (Sign) seller.getSign().getState();

        rec.locWorld = loc.getWorld().getName();
        rec.locX     = loc.getBlockX();
        rec.locY     = loc.getBlockY();
        rec.locZ     = loc.getBlockZ();

        rec.ownerName = seller.getOwner().getName();
        rec.ownerUuid = seller.getOwner().GetIdentifier().getStringIdentifier();

        rec.signType  = seller.getOperation();
        rec.signPrice = economyUtil.parsePrice(sign.getLine(3));
        rec.signText  = new String[] { sign.getLine(1), sign.getLine(2) };

        rec.invItems = seller.getItems();

        // This is necessary as the event's items are sometimes CraftItemStack type. That type does
        // not populate its private fields, thus it is useless to Gson's serializer.
        ItemStack[] plainStack = new ItemStack[rec.invItems.length];
        for (int i = 0; i < rec.invItems.length; i++)
        {
            ItemStack oldItem = rec.invItems[i];

            plainStack[i] = new ItemStack(
                oldItem.getType(), oldItem.getAmount(), oldItem.getDurability());

            plainStack[i].setData(oldItem.getData());
            plainStack[i].setItemMeta(oldItem.getItemMeta());
        }

        rec.invItems = plainStack;

        switch(rec.signType)
        {
            case "buy":
            case "ibuy":
                rec.invInStock = checkStock(seller, true, 0);
                break;
            case "sell":
            case "isell":
                rec.invInStock = checkStock(seller, false, rec.signPrice);
                break;
            default:
                rec.invInStock = true;
                break;
        }

        return rec;
    }

    private boolean checkStock(Seller seller, boolean take, double price)
    {
        // Check balance of shop owner if sell sign
        if ( !take && !seller.getOwner().hasMoney(price) )
            return false;

        // For both signs, check stock space/availability
        return itemUtil.stockOKForContainables(seller.getContainables(), seller.getItems(), take);
    }

    public void free()
    {
        signs = null;
    }
}

@@ -420,16 +420,43 @@
 ecord;%0A%0A
+import java.util.HashMap;%0A%0A
 public c
@@ -1571,682 +1571,42 @@
 s = 
-seller.getItems();%0A%0A        // This is necessary as the event's items are sometimes CraftItemStack type. That type does%0A        // not populate its private fields, thus it is useless to Gson's serializer.%0A        ItemStack%5B%5D plainStack = new ItemStack%5Brec.invItems.length%5D;%0A        for (int i = 0; i %3C rec.invItems.length; i++)%0A        %7B%0A            ItemStack oldItem = rec.invItems%5Bi%5D;%0A%0A            plainStack%5Bi%5D = new ItemStack(%0A                oldItem.getType(), oldItem.getAmount(), oldItem.getDurability());%0A%0A            plainStack%5Bi%5D.setData(oldItem.getData());%0A            plainStack%5Bi%5D.setItemMeta(oldItem.getItemMeta());%0A        %7D%0A%0A        rec.invItems = plainStack
+processStacks( seller.getItems() )
 ;%0A%0A 
@@ -2323,16 +2323,16 @@
 ability%0A
-
         
@@ -2425,24 +2425,1366 @@
 ke);%0A    %7D%0A%0A
+    /**%0A     * Processes a sign's item stacks by:%0A     * * Properly filling in all their private fields%0A     * * Combining stacks of same type into one, with proper quantity%0A     * @param stacks ItemStacks to process%0A     * @return Processed array of ItemStacks%0A     */%0A    private ItemStack%5B%5D processStacks(ItemStack%5B%5D stacks)%0A    %7B%0A        // Copied from SignShop's itemUtil.itemStackToString()%0A        HashMap%3CItemStack, Integer%3E items = new HashMap%3C%3E(stacks.length);%0A%0A        for (ItemStack stack : stacks)%0A        %7B%0A            if (stack == null) continue;%0A%0A            // This is necessary as the sign's items are sometimes CraftItemStack type. That type%0A            // does not populate its private fields, thus it is useless to Gson's serializer.%0A            ItemStack isBackup = new ItemStack( stack.getType(), 1, stack.getDurability() );%0A%0A            isBackup.setData( stack.getData() );%0A            isBackup.setItemMeta( stack.getItemMeta() );%0A%0A            int amount = items.containsKey(isBackup)%0A                ? items.get(isBackup) + stack.getAmount()%0A                : stack.getAmount();%0A%0A            items.put(isBackup, amount);%0A        %7D%0A%0A        // Feeds each integer into the item stack's setAmount%0A        items.forEach(ItemStack::setAmount);%0A%0A        return items.keySet().toArray(new ItemStack%5B items.size() %5D);%0A    %7D%0A%0A
     public v

Make SignShop similar stacks combine quantities