void Health::drawTile(Engine& engine, Tile& tile, const Point& offset)
{
  Point screenPos = tile.mappos() + offset;

  if( tile.overlay().isNull() )
  {
    //draw background
    //engine.draw( tile.picture(), screenPos );

    drawPass( engine, tile, offset, Renderer::ground );
    drawPass( engine, tile, offset, Renderer::groundAnimation );
  }
  else
  {
    bool needDrawAnimations = false;
    OverlayPtr overlay = tile.overlay();

    int healthLevel = -1;
    if( _isVisibleObject( overlay->type() ) )
    {
      // Base set of visible objects
      needDrawAnimations = true;
    }
    else if( _flags.count( overlay->type() ) )
    {
      needDrawAnimations = true;
      //city::Helper helper( _city() );
      //drawArea( engine, helper.getArea( overlay ), offset, ResourceGroup::foodOverlay, OverlayPic::base );
    }
    else if( overlay->type() == object::house )
    {
      HousePtr house = ptr_cast<House>( overlay );
      healthLevel = _getLevelValue( house );

      needDrawAnimations = (house->spec().level() == 1) && (house->habitants().empty());

      if( !needDrawAnimations )
      {
        drawArea( engine, overlay->area(), offset, ResourceGroup::foodOverlay, OverlayPic::inHouseBase );
      }
    }
    else  //other buildings
    {
      drawArea( engine, overlay->area(), offset, ResourceGroup::foodOverlay, OverlayPic::base );
    }

    if( needDrawAnimations )
    {
      Layer::drawTile( engine, tile, offset );
      registerTileForRendering( tile );
    }
    else if( healthLevel > 0 )
    {
      drawColumn( engine, screenPos, healthLevel );
    }
  }

  tile.setWasDrawn();
}
void Health::handleEvent(NEvent& event)
{
  if( event.EventType == sEventMouse )
  {
    switch( event.mouse.type  )
    {
    case mouseMoved:
    {
      Tile* tile = _camera()->at( event.mouse.pos(), false );  // tile under the cursor (or NULL)
      std::string text = "";
      if( tile != 0 )
      {
        HousePtr house = ptr_cast<House>( tile->overlay() );
        if( house != 0 )
        {
          std::string typeName;
          switch( _type )
          {
          case citylayer::health: typeName = "health"; break;
          case citylayer::doctor: typeName = "doctor"; break;
          case citylayer::hospital: typeName = "hospital"; break;
          case citylayer::barber: typeName = "barber"; break;
          case citylayer::baths: typeName = "baths"; break;
          }

          int lvlValue = _getLevelValue( house );
          std::string levelName;
          if( lvlValue > 0 )
          {
            if( lvlValue < 20 ) { levelName = "##warning_"; }
            else if( lvlValue < 40 ) { levelName = "##bad_"; }
            else if( lvlValue < 60 ) { levelName = "##simple_"; }
            else if( lvlValue < 80 ) { levelName = "##good_"; }
            else { levelName = "##awesome_"; }

            text = levelName + typeName + "_access##";
          }
        }
      }

      _setTooltipText( _(text) );
    }
    break;

    default: break;
    }
  }

  Layer::handleEvent( event );
}
void Entertainment::drawTile(Engine& engine, Tile& tile, const Point& offset)
{
  Point screenPos = tile.mappos() + offset;

  if( tile.overlay().isNull() )
  {
    drawPass( engine, tile, offset, Renderer::ground );
    drawPass( engine, tile, offset, Renderer::groundAnimation );
  }
  else
  {
    bool needDrawAnimations = false;
    OverlayPtr overlay = tile.overlay();

    int entertainmentLevel = -1;
    if( _isVisibleObject( overlay->type() ) )
    {
      // Base set of visible objects
      needDrawAnimations = true;
    }
    else if( _flags.count( overlay->type() ) > 0 )
    {
      needDrawAnimations = true;
    }
    else if( overlay->type() == object::house )
    {
      auto house = overlay.as<House>();
      entertainmentLevel = _getLevelValue( house );

      needDrawAnimations = (house->level() <= HouseLevel::hovel) && (house->habitants().empty());
      drawArea( engine, overlay->area(), offset, ResourceGroup::foodOverlay, OverlayPic::inHouseBase );
    }
    else
    {
      drawArea( engine, overlay->area(), offset, ResourceGroup::foodOverlay, OverlayPic::base );
    }

    if( needDrawAnimations )
    {
      Layer::drawTile( engine, tile, offset );
      registerTileForRendering( tile );
    }
    else if( entertainmentLevel > 0 )
    {
      drawColumn( engine, screenPos, entertainmentLevel );
    }
  }

  tile.setRendered();
}
void Entertainment::handleEvent(NEvent& event)
{
  if( event.EventType == sEventMouse )
  {
    switch( event.mouse.type  )
    {
    case mouseMoved:
    {
      Tile* tile = _camera()->at( event.mouse.pos(), false );  // tile under the cursor (or NULL)
      std::string text = "";
      if( tile != 0 )
      {
        HousePtr house = tile->overlay<House>();
        if( house != 0 )
        {
          std::string typeName;
          switch( _type )
          {
          case citylayer::entertainment: typeName = "entertainment"; break;
          case citylayer::theater: typeName = "theater"; break;
          case citylayer::amphitheater: typeName = "amphitheater"; break;
          case citylayer::colloseum: typeName = "colloseum"; break;
          case citylayer::hippodrome: typeName = "hippodrome"; break;
          }

          int lvlValue = _getLevelValue( house );
          if( _type == citylayer::entertainment )
          {
            text = utils::format( 0xff, "##%d_entertainment_access##", lvlValue / 10 );
          }
          else
          {
            std::string levelName;

            if( lvlValue > 0 )
            {
              if( lvlValue < 20 ) { levelName = "##warning_"; }
              else if( lvlValue < 40 ) { levelName = "##bad_"; }
              else if( lvlValue < 60 ) { levelName = "##simple_"; }
              else if( lvlValue < 80 ) { levelName = "##good_"; }
              else { levelName = "##awesome_"; }

              text = levelName + typeName + "_access##";
            }
            else
            {
              text = levelName + "_no_access";
            }
          }
        }
      }

      _setTooltipText( _(text) );
    }
    break;

    default: break;
    }
  }

  Layer::handleEvent( event );
}
void Education::handleEvent(NEvent& event)
{
    if( event.EventType == sEventMouse )
    {
        switch( event.mouse.type  )
        {
        case mouseMoved:
        {
            Tile* tile = _camera()->at( event.mouse.pos(), false );  // tile under the cursor (or NULL)
            std::string text = "";
            std::string levelName = "";
            if( tile != 0 )
            {
                auto house = tile->overlay<House>();
                if( house != 0 )
                {
                    std::string typeName;
                    int lvlValue = _getLevelValue( house );
                    switch( _type )
                    {
                    case citylayer::education:
                    {
                        bool schoolAccess = house->hasServiceAccess( Service::school );
                        bool libraryAccess = house->hasServiceAccess( Service::library );
                        bool academyAccess = house->hasServiceAccess( Service::academy );

                        if( schoolAccess && libraryAccess && academyAccess )
                        {
                            text = "##education_full_access##";
                        }
                        else
                        {
                            if( schoolAccess && libraryAccess ) {
                                text = "##education_have_school_library_access##";
                            }
                            else if( schoolAccess || libraryAccess ) {
                                text = "##education_have_school_or_library_access##";
                            }
                            else if( academyAccess ) {
                                text = "##education_have_academy_access##";
                            }
                            else {
                                text = "##education_have_no_access##";
                            }
                        }
                    }
                    break;
                    case citylayer::school:
                        typeName = "school";
                        break;
                    case citylayer::library:
                        typeName = "library";
                        break;
                    case citylayer::academy:
                        typeName = "academy";
                        break;
                    }

                    if( text.empty() )
                    {
                        levelName = _getAccessLevel( lvlValue );
                        text = levelName + typeName + "_access##";
                    }
                }
            }

            _setTooltipText( _(text) );
        }
        break;

        default:
            break;
        }
    }

    Layer::handleEvent( event );
}
void LayerEntertainment::drawTile(Engine& engine, Tile& tile, const Point& offset)
{
  Point screenPos = tile.mappos() + offset;

  if( tile.overlay().isNull() )
  {
    //draw background
    engine.draw( tile.picture(), screenPos );
  }
  else
  {
    bool needDrawAnimations = false;
    TileOverlayPtr overlay = tile.overlay();

    int entertainmentLevel = -1;
    switch( overlay->type() )
    {
    // Base set of visible objects
    case construction::road:
    case construction::plaza:
    case construction::garden:

    case building::burnedRuins:
    case building::collapsedRuins:

    case building::lowBridge:
    case building::highBridge:

    case building::elevation:
    case building::rift:
      needDrawAnimations = true;
    break;

    case building::theater:
    case building::amphitheater:
    case building::colloseum:
    case building::hippodrome:
    case building::lionsNursery:
    case building::actorColony:
    case building::gladiatorSchool:
      needDrawAnimations = _flags.count( overlay->type() ) > 0;
      if( !needDrawAnimations )
      {
        city::Helper helper( _city() );
        drawArea( engine, helper.getArea( overlay ), offset, ResourceGroup::foodOverlay, OverlayPic::base );
      }
    break;

      //houses
    case building::house:
      {
        HousePtr house = ptr_cast<House>( overlay );
        entertainmentLevel = _getLevelValue( house );

        needDrawAnimations = (house->spec().level() == 1) && (house->habitants().empty());
        city::Helper helper( _city() );
        drawArea( engine, helper.getArea( overlay ), offset, ResourceGroup::foodOverlay, OverlayPic::inHouseBase );
      }
    break;

      //other buildings
    default:
      {
        city::Helper helper( _city() );
        drawArea( engine, helper.getArea( overlay ), offset, ResourceGroup::foodOverlay, OverlayPic::base );
      }
    break;
    }

    if( needDrawAnimations )
    {
      Layer::drawTile( engine, tile, offset );
      registerTileForRendering( tile );
    }
    else if( entertainmentLevel > 0 )
    {
      _addColumn( screenPos, entertainmentLevel );
    }
  }

  tile.setWasDrawn();
}