text: /*
   * Copyright (C) 2005 - 2013 MaNGOS <http://www.getmangos.com/>
   *
   * Copyright (C) 2008 - 2013 Trinity <http://www.trinitycore.org/>
   *
   * Copyright (C) 2010 - 2013 ProjectSkyfire <http://www.projectskyfire.org/>
   *
   * Copyright (C) 2011 - 2013 ArkCORE <http://www.arkania.net/>
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
   */
  
  #ifndef _AUCTION_HOUSE_MGR_H
  #define _AUCTION_HOUSE_MGR_H
  
  #include <ace/Singleton.h>
  
  #include "Common.h"
  #include "DatabaseEnv.h"
  #include "DBCStructure.h"
  
  class Item;
  class Player;
  class WorldPacket;
  
  #define MIN_AUCTION_TIME (12*HOUR)
  
  enum AuctionError
  {
      AUCTION_OK = 0, AUCTION_INTERNAL_ERROR = 2, AUCTION_NOT_ENOUGHT_MONEY = 3, AUCTION_ITEM_NOT_FOUND = 4, CANNOT_BID_YOUR_AUCTION_ERROR = 10
  };
  
  enum AuctionAction
  {
      AUCTION_SELL_ITEM = 0, AUCTION_CANCEL = 1, AUCTION_PLACE_BID = 2
  };
  
  struct AuctionEntry
  {
      uint32 Id;
      uint32 auctioneer;          // creature low guid
      uint32 item_guidlow;
      uint32 item_template;
      uint64 owner;
      uint64 startbid;          //maybe useless
      uint64 bid;
      uint32 buyout;
      time_t expire_time;
      uint64 bidder;
      uint32 deposit;          //deposit can be calculated only when creating auction
      AuctionHouseEntry const* auctionHouseEntry;          // in AuctionHouse.dbc
      uint32 factionTemplateId;
  
      // helpers
      uint32 GetHouseId () const
      {
          return auctionHouseEntry->houseId;
      }
      uint32 GetHouseFaction () const
      {
          return auctionHouseEntry->faction;
      }
      uint32 GetAuctionCut () const;
      uint64 GetAuctionOutBid () const;
      bool BuildAuctionInfo (WorldPacket & data) const;
      void DeleteFromDB (SQLTransaction& trans) const;
      void SaveToDB (SQLTransaction& trans) const;
      bool LoadFromDB (Field* fields);
  };
  
  //this class is used as auctionhouse instance
  class AuctionHouseObject
  {
  public:
      // Initialize storage
      AuctionHouseObject ()
      {
          next = AuctionsMap.begin();
      }
      ~AuctionHouseObject ()
      {
          for (AuctionEntryMap::iterator itr = AuctionsMap.begin(); itr != AuctionsMap.end(); ++itr)
              delete itr->second;
      }
  
      typedef std::map<uint32, AuctionEntry*> AuctionEntryMap;
  
      uint32 Getcount ()
      {
          return AuctionsMap.size();
      }
  
      AuctionEntryMap::iterator GetAuctionsBegin ()
      {
          return AuctionsMap.begin();
      }
      AuctionEntryMap::iterator GetAuctionsEnd ()
      {
          return AuctionsMap.end();
      }
  
      AuctionEntry* GetAuction (uint32 id) const
      {
          AuctionEntryMap::const_iterator itr = AuctionsMap.find(id);
          return itr != AuctionsMap.end() ? itr->second : NULL;
      }
  
      void AddAuction (AuctionEntry *auction);
  
      bool RemoveAuction (AuctionEntry *auction, uint32 item_template);
  
      void Update ();
  
      void BuildListBidderItems (WorldPacket& data, Player* player, uint32& count, uint32& totalcount);
      void BuildListOwnerItems (WorldPacket& data, Player* player, uint32& count, uint32& totalcount);
      void BuildListAuctionItems (WorldPacket& data, Player* player, std::wstring const& searchedname, uint32 listfrom, uint8 levelmin, uint8 levelmax, uint8 usable, uint32 inventoryType, uint32 itemClass, uint32 itemSubClass, uint32 quality, uint32& count, uint32& totalcount);
  
  private:
      AuctionEntryMap AuctionsMap;
  
      // storage for "next" auction item for next Update()
      AuctionEntryMap::const_iterator next;
  };
  
  class AuctionHouseMgr
  {
      friend class ACE_Singleton<AuctionHouseMgr, ACE_Null_Mutex> ;
      AuctionHouseMgr ();
      ~AuctionHouseMgr ();
  
  public:
  
      typedef UNORDERED_MAP<uint32, Item*> ItemMap;
  
      AuctionHouseObject* GetAuctionsMap(uint32 factionTemplateId);
      AuctionHouseObject* GetBidsMap(uint32 factionTemplateId);
  
      Item* GetAItem(uint32 id)
      {
          ItemMap::const_iterator itr = mAitems.find(id);
          if (itr != mAitems.end())
          return itr->second;
  
          return NULL;
      }
  
      //auction messages
      void SendAuctionWonMail(AuctionEntry * auction, SQLTransaction& trans);
      void SendAuctionSalePendingMail(AuctionEntry * auction, SQLTransaction& trans);
      void SendAuctionSuccessfulMail(AuctionEntry * auction, SQLTransaction& trans);
      void SendAuctionExpiredMail(AuctionEntry * auction, SQLTransaction& trans);
  
      void SendAuctionRemovedMail(AuctionEntry * auction, SQLTransaction& trans);
      void SendAuctionOutbiddedMail(AuctionEntry * auction, uint64 newPrice, Player* newBidder, SQLTransaction& trans);
      void SendAuctionCancelledToBidderMail(AuctionEntry* auction, SQLTransaction& trans);
  
      static uint32 GetAuctionDeposit(AuctionHouseEntry const* entry, uint32 time, Item *pItem, uint32 count);
      static AuctionHouseEntry const* GetAuctionHouseEntry(uint32 factionTemplateId);
  
  public:
  
      //load first auction items, because of check if item exists, when loading
      void LoadAuctionItems();
      void LoadAuctions();
  
      void AddAItem(Item* it);
      bool RemoveAItem(uint32 id);
  
      void Update();
  
  private:
  
      AuctionHouseObject mHordeAuctions;
      AuctionHouseObject mAllianceAuctions;
      AuctionHouseObject mNeutralAuctions;
  
      ItemMap mAitems;
  };
  
  #define sAuctionMgr ACE_Singleton<AuctionHouseMgr, ACE_Null_Mutex>::instance()
  
  #endif
  