#include "AsyncAuctionListing.h"
#include "Player.h"
#include "Creature.h"
#include "AuctionHouseMgr.h"
#include "ObjectAccessor.h"

uint32 AsyncAuctionListingMgr::auctionListingDiff = 0;
bool AsyncAuctionListingMgr::auctionListingAllowed = false;
std::list<AuctionListItemsDelayEvent> AsyncAuctionListingMgr::auctionListingList;
std::list<AuctionListItemsDelayEvent> AsyncAuctionListingMgr::auctionListingListTemp;
ACE_Thread_Mutex AsyncAuctionListingMgr::auctionListingLock;
ACE_Thread_Mutex AsyncAuctionListingMgr::auctionListingTempLock;

bool AuctionListOwnerItemsDelayEvent::Execute(uint64 e_time, uint32 p_time)
{
    if (Player* plr = ObjectAccessor::FindPlayer(playerguid))
        plr->GetSession()->HandleAuctionListOwnerItemsEvent(data);
    return true;
}

bool AuctionListItemsDelayEvent::Execute()
{
    Player* plr = ObjectAccessor::FindPlayer(_playerguid);
    if (!plr || !plr->IsInWorld() || plr->IsDuringRemoveFromWorld() || plr->IsBeingTeleported())
        return true;

    Creature* creature = plr->GetNPCIfCanInteractWith(_creatureguid, UNIT_NPC_FLAG_AUCTIONEER);
    if (!creature)
        return true;

    AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->getFaction());

    //sLog->outDebug("Auctionhouse search (GUID: %u TypeId: %u)",, list from: %u, searchedname: %s, levelmin: %u, levelmax: %u, auctionSlotID: %u, auctionMainCategory: %u, auctionSubCategory: %u, quality: %u, usable: %u",
    //  GUID_LOPART(guid), GuidHigh2TypeId(GUID_HIPART(guid)), listfrom, searchedname.c_str(), levelmin, levelmax, auctionSlotID, auctionMainCategory, auctionSubCategory, quality, usable);

    WorldPacket data(SMSG_AUCTION_LIST_RESULT, (4+4+4)+50*((16+MAX_INSPECTED_ENCHANTMENT_SLOT*3)*4));
    uint32 count = 0;
    uint32 totalcount = 0;
    data << (uint32) 0;

    // converting string that we try to find to lower case
    std::wstring wsearchedname;
    if (!Utf8toWStr(_searchedname, wsearchedname))
        return true;

    wstrToLower(wsearchedname);

    bool result = auctionHouse->BuildListAuctionItems(data, plr,
        wsearchedname, _listfrom, _levelmin, _levelmax, _usable,
        _auctionSlotID, _auctionMainCategory, _auctionSubCategory, _quality,
        count, totalcount, _getAll);

    if (!result)
        return false;

    data.put<uint32>(0, count);
    data << (uint32) totalcount;
    data << (uint32) 300; // clientside search cooldown [ms] (gray search button)
    plr->GetSession()->SendPacket(&data);

    return true;
}
