#include "ItemSlot.h"


ItemSlot::ItemSlot( int maxSize, int pullPriority, int pushPriority, int allowedPullSide, int allowedPushSides, bool allowHigherStackSize )
    : ReferenceCounter(),
    items( 0 ),
    maxSize( maxSize ),
    allowedPullSide( allowedPullSide ),
    allowedPushSides( allowedPushSides ),
    pullPriority( pullPriority ),
    pushPriority( pushPriority ),
    allowHigherStackSize( allowHigherStackSize )
{}

ItemSlot::~ItemSlot()
{
    if( items )
        items->release();
}

ItemStack* ItemSlot::takeItemsOut( int count, Direction dir )
{
    if( !items )
        return 0;
    if( (dir | allowedPullSide) == allowedPullSide )
    {
        ItemStack* result = items->split( count );
        if( items->getSize() == 0 )
        {
            items->release();
            items = 0;
        }
        return result;
    }
    return 0;
}

void ItemSlot::addItems( ItemStack* zStack, Direction dir )
{
    if( (dir | allowedPushSides) == allowedPushSides )
    {
        if( !items )
        {
            if( allowHigherStackSize )
            {
                items = zStack->split( maxSize );
                items->setMaxSize( maxSize );
            }
            else
            {
                items = zStack->split( MIN( maxSize, items->zItem()->getMaxStackSize() ) );
                items->setMaxSize( MIN( maxSize, items->zItem()->getMaxStackSize() ) );
            }
        }
        else
            items->addItemStack( zStack );
    }
}

int ItemSlot::numberOfAddableItems( const ItemStack* zStack, Direction dir ) const
{
    if( (dir | allowedPushSides) == allowedPushSides )
    {
        if( !items )
        {
            if( allowHigherStackSize )
                return maxSize;
            else
                return MIN( maxSize, zStack->zItem()->getMaxStackSize() );
        }
        else
            return items->getMaxSize() - items->getSize();
    }
    return 0;
}

const ItemStack* ItemSlot::zStack() const
{
    return items;
}

int ItemSlot::getPullPriority() const
{
    return pullPriority;
}

int ItemSlot::getPushPriority() const
{
    return pushPriority;
}

bool ItemSlot::isFull() const
{
    return items ? items->getSize() < items->getMaxSize() : 0;
}

int ItemSlot::getFreeSpace() const
{
    return items ? items->getMaxSize() - items->getSize() : maxSize;
}