text: #include "AppHdr.h"
  
  #ifdef USE_TILE_LOCAL
  
  #include "tilereg-mem.h"
  
  #include "cio.h"
  #include "describe.h"
  #include "macro.h"
  #include "output.h"
  #include "religion.h"
  #include "spl-book.h"
  #include "spl-cast.h"
  #include "spl-util.h"
  #include "stringutil.h"
  #include "tile-inventory-flags.h"
  #include "tilepick.h"
  #include "tilereg-cmd.h"
  #include "tiles-build-specific.h"
  
  MemoriseRegion::MemoriseRegion(const TileRegionInit &init) : SpellRegion(init)
  {
  }
  
  void MemoriseRegion::activate()
  {
      // Print a fitting message if we can't memorise anything.
      has_spells_to_memorise(false);
  }
  
  int MemoriseRegion::get_max_slots()
  {
      return m_items.size();
  }
  
  void MemoriseRegion::draw_tag()
  {
      if (m_cursor == NO_CURSOR)
          return;
      int curs_index = cursor_index();
      if (curs_index >= (int)m_items.size())
          return;
      int idx = m_items[curs_index].idx;
      if (idx == -1)
          return;
  
      const spell_type spell = (spell_type) idx;
      const string failure = failure_rate_to_string(raw_spell_fail(spell));
      string desc = make_stringf("%s    (%s)    %d/%d spell slot%s",
                                 spell_title(spell),
                                 failure.c_str(),
                                 spell_levels_required(spell),
                                 player_spell_levels(),
                                 spell_levels_required(spell) > 1 ? "s" : "");
      draw_desc(desc.c_str());
  }
  
  int MemoriseRegion::handle_mouse(wm_mouse_event &event)
  {
      unsigned int item_idx;
      if (!place_cursor(event, item_idx)
          || tile_command_not_applicable(CMD_MEMORISE_SPELL))
      {
          return 0;
      }
  
      const spell_type spell = (spell_type) m_items[item_idx].idx;
      if (event.button == wm_mouse_event::LEFT)
      {
          m_last_clicked_item = item_idx;
          tiles.set_need_redraw();
          if (learn_spell(spell))
              tiles.update_tabs();
          else
              flush_input_buffer(FLUSH_ON_FAILURE);
          return CK_MOUSE_CMD;
      }
      else if (event.button == wm_mouse_event::RIGHT)
      {
          describe_spell(spell);
          redraw_screen();
          update_screen();
          return CK_MOUSE_CMD;
      }
      return 0;
  }
  
  bool MemoriseRegion::update_tab_tip_text(string &tip, bool active)
  {
      const char *prefix1 = active ? "" : "[L-Click] ";
      const char *prefix2 = active ? "" : "          ";
  
      tip = make_stringf("%s%s\n%s%s",
                         prefix1, "Display spells in carried books",
                         prefix2, "Memorise spells");
  
      return true;
  }
  
  bool MemoriseRegion::update_tip_text(string& tip)
  {
      if (m_cursor == NO_CURSOR)
          return false;
  
      unsigned int item_idx = cursor_index();
      if (item_idx >= m_items.size() || m_items[item_idx].empty())
          return false;
  
      int flag = m_items[item_idx].flag;
      vector<command_type> cmd;
      if (flag & TILEI_FLAG_INVALID)
          tip = "You cannot memorise this spell now.";
      else
      {
          tip = "[L-Click] Memorise (%)";
          cmd.push_back(CMD_MEMORISE_SPELL);
      }
  
      tip += "\n[R-Click] Describe";
  
      insert_commands(tip, cmd);
      return true;
  }
  
  void MemoriseRegion::update()
  {
      m_items.clear();
      m_dirty = true;
  
      if (mx * my == 0)
          return;
  
      if (!has_spells_to_memorise())
          return;
  
      const unsigned int max_spells = mx * my;
  
      vector<spell_type> spells = get_sorted_spell_list(); // TODO: should this be silent?
      for (unsigned int i = 0; m_items.size() < max_spells && i < spells.size();
           ++i)
      {
          const spell_type spell = spells[i];
  
          if (you.hidden_spells.get(spell))
              continue;
  
          InventoryTile desc;
          desc.tile     = tileidx_spell(spell);
          desc.idx      = (int) spell;
          desc.quantity = spell_difficulty(spell);
  
          if (!can_learn_spell(true)
              || spell_difficulty(spell) > you.experience_level
              || player_spell_levels() < spell_levels_required(spell)
              || tile_command_not_applicable(CMD_MEMORISE_SPELL))
          {
              desc.flag |= TILEI_FLAG_INVALID;
          }
  
          if (vehumet_is_offering(spell))
              desc.flag |= TILEI_FLAG_EQUIP;
  
          m_items.push_back(desc);
      }
  }
  
  #endif
  