void CartSupplier::onDestination()
{
  Walker::onDestination();
  CityHelper helper( _d->city );
  
  if( _getPathway().isReverse() )
  {
    // walker is back in the market
    deleteLater();
    // put the content of the stock to receiver
    BuildingPtr building = helper.getBuilding<Building>( _d->baseBuildingPos );

    GoodStore* storage = 0;
    if( building.is<Factory>() )
    {
      storage = &building.as<Factory>()->getGoodStore();
    }
    else if( building.is<Granary>() )
    {
      storage = &building.as<Granary>()->getGoodStore();
    }
    else if( building.is<Warehouse>() )
    {
      storage = &building.as<Warehouse>()->getGoodStore();
    }

    if( storage )
    {
      storage->applyStorageReservation( _d->stock, _d->rcvReservationID );
      storage->store( _d->stock, _d->stock._currentQty );
    }
  }
  else
  {
    // walker is near the granary/warehouse
    _getPathway().rbegin();
    _setAction( WA_MOVE );
    computeDirection();

    // get goods from destination building
    
    BuildingPtr building = helper.getBuilding<Building>( _d->storageBuildingPos );

    if( building.is<Granary>() )
    {
      GranaryPtr granary = building.as<Granary>();
      // this is a granary!
      // std::cout << "MarketBuyer arrives at granary, res=" << _reservationID << std::endl;
      granary->getGoodStore().applyRetrieveReservation( _d->stock, _d->reservationID );      
    }
    else if( building.is<Warehouse>() )
    {
      WarehousePtr warehouse = building.as<Warehouse>();
      // this is a warehouse!
      // std::cout << "Market buyer takes IRON from warehouse" << std::endl;
      // warehouse->retrieveGoods(_basket.getStock(G_IRON));
      warehouse->getGoodStore().applyRetrieveReservation(_d->stock, _d->reservationID);
    }
  }
}
void MarketLady::onDestination()
{
   Walker::onDestination();
   if( _getPathway().isReverse() )
   {
      // walker is back in the market
      deleteLater();
      // put the content of the basket in the market
      _d->market->getGoodStore().storeAll( _d->basket );
   }
   else
   {
      // walker is near the granary/warehouse
      _getPathway().rbegin();
      _setAction( WA_MOVE );
      computeDirection();

      // get goods from destination building
      LandOverlayPtr building = _d->city->getTilemap().at( _d->destBuildingPos ).getTerrain().getOverlay();
      
      if( building.is<Granary>() )
      {
        GranaryPtr granary = building.as<Granary>();
        // this is a granary!
        // std::cout << "MarketLady arrives at granary, res=" << _reservationID << std::endl;
        granary->getGoodStore().applyRetrieveReservation(_d->basket, _d->reservationID);

        // take other goods if possible
        for (int n = 1; n<G_MAX; ++n)
        {
           // for all types of good (except G_NONE)
           GoodType goodType = (GoodType) n;
           int qty = _d->market->getGoodDemand(goodType) - _d->basket.getCurrentQty(goodType);
           if (qty != 0)
           {
              qty = std::min(qty, granary->getGoodStore().getMaxRetrieve(goodType));
              qty = std::min(qty, _d->basket.getMaxQty(_d->priorityGood) - _d->basket.getCurrentQty(_d->priorityGood));
              if (qty != 0)
              {
                 // std::cout << "extra retrieve qty=" << qty << " basket=" << _basket.getStock(goodType)._currentQty << std::endl;
                 GoodStock& stock = _d->basket.getStock(goodType);
                 granary->getGoodStore().retrieve(stock, qty);
              }
           }
        }
      }
      else if( building.is<Warehouse>() )
      {
        WarehousePtr warehouse = building.as<Warehouse>();
        // this is a warehouse!
        // std::cout << "Market buyer takes IRON from warehouse" << std::endl;
        // warehouse->retrieveGoods(_basket.getStock(G_IRON));
        warehouse->getGoodStore().applyRetrieveReservation(_d->basket, _d->reservationID);

        // take other goods if possible
        for (int n = 1; n<G_MAX; ++n)
        {
           // for all types of good (except G_NONE)
           GoodType goodType = (GoodType) n;
           int qty = _d->market->getGoodDemand(goodType) - _d->basket.getCurrentQty(goodType);
           if (qty != 0)
           {
              qty = std::min(qty, warehouse->getGoodStore().getMaxRetrieve(goodType));
              qty = std::min(qty, _d->basket.getMaxQty(_d->priorityGood) - _d->basket.getCurrentQty(_d->priorityGood));
              if (qty != 0)
              {
                 // std::cout << "extra retrieve qty=" << qty << " basket=" << _basket.getStock(goodType)._currentQty << std::endl;
                 GoodStock& stock = _d->basket.getStock(goodType);
                 warehouse->getGoodStore().retrieve(stock, qty);
              }
           }
        }
      }

      unsigned long delay = 20;

      while( _d->basket.getCurrentQty() > 100 )
      {
        for( int gtype=G_WHEAT; gtype <= G_WINE; gtype++ )
        {
          GoodStock& currentStock = _d->basket.getStock( (GoodType)gtype );
          if( currentStock._currentQty > 0 )
          {
            MarketLadyHelperPtr boy = MarketLadyHelper::create( this );
            GoodStock& boyBasket =  boy->getBasket();
            boyBasket._goodType = (GoodType)gtype;
            boyBasket._maxQty = 100;
            _d->basket.retrieve( boyBasket, math::clamp( currentStock._currentQty, 0, 100 ) );
            boy->setDelay( delay );
            delay += 20;
            boy->send2City( _d->city, _d->market );
          }
        }
      }
   }
}