--- /dev/null
+/*
+ * SpellMenu.cpp
+ *
+ *  Created on: Nov 18, 2012
+ *      Author: holy
+ */
+
+#include "SpellMenu.h"
+
+#include "HeroStatus.h"
+#include "PartyMenu.h"
+#include "Resources.h"
+#include "../app/Input.h"
+#include "../common/GameConfig.h"
+#include "../common/GameState.h"
+#include "../common/Hero.h"
+#include "../common/Spell.h"
+#include "../graphics/Font.h"
+#include "../graphics/Frame.h"
+
+#include <SDL.h>
+#include <vector>
+
+using app::Input;
+using common::Hero;
+using common::Spell;
+using geometry::Vector;
+using graphics::Font;
+using graphics::Frame;
+using std::vector;
+
+namespace menu {
+
+SpellMenu::SpellMenu(PartyMenu *parent, int cursor)
+: parent(parent)
+, highlight(0)
+, cursor(cursor)
+, actionMenu(*parent->Res().itemMenuProperties)
+, spellMenu(*parent->Res().spellMenuProperties) {
+       actionMenu.Add(parent->Res().itemMenuUseText, CHOICE_USE);
+       actionMenu.Add(parent->Res().itemMenuSortText, CHOICE_SORT);
+}
+
+
+void SpellMenu::OnEnterState(SDL_Surface *) {
+       const HeroStatus &status(parent->GetHeroStatus(0));
+       highlight = SDL_CreateRGBSurface(0, status.Width(), status.Height(), 32, 0xFF000000, 0xFF0000, 0xFF00, 0);
+       SDL_FillRect(highlight, 0, SDL_MapRGB(highlight->format, 0xFF, 0xFF, 0xFF));
+       SDL_SetAlpha(highlight, SDL_SRCALPHA|SDL_RLEACCEL, 0x20);
+
+       actionMenu.SetSelected();
+       LoadSpells();
+}
+
+void SpellMenu::LoadSpells() {
+       spellMenu.Clear();
+       // TODO: set to max spells once implementation is changed
+       spellMenu.Reserve(GetHero().Spells().size());
+       for (vector<const Spell *>::const_iterator
+                       i = GetHero().Spells().begin(), end = GetHero().Spells().end();
+                       i != end; ++i) {
+               const Spell *spell = *i;
+               spellMenu.Add(spell->Name(), spell, spell->CanUseOnStatusScreen(), 0, spell->Cost());
+       }
+}
+
+const Hero &SpellMenu::GetHero() const {
+       return *parent->Game().state->party[cursor];
+}
+
+void SpellMenu::OnExitState(SDL_Surface *) {
+       SDL_FreeSurface(highlight);
+}
+
+void SpellMenu::OnResumeState(SDL_Surface *) {
+
+}
+
+void SpellMenu::OnPauseState(SDL_Surface *) {
+
+}
+
+
+void SpellMenu::OnResize(int width, int height) {
+
+}
+
+
+void SpellMenu::HandleEvents(const Input &input) {
+       if (actionMenu.IsActive()) {
+               if (input.JustPressed(Input::PAD_LEFT)) {
+                       actionMenu.PreviousItem();
+               }
+               if (input.JustPressed(Input::PAD_RIGHT)) {
+                       actionMenu.NextItem();
+               }
+       } else {
+               if (input.JustPressed(Input::PAD_UP)) {
+                       spellMenu.PreviousRow();
+               }
+               if (input.JustPressed(Input::PAD_RIGHT)) {
+                       spellMenu.NextItem();
+               }
+               if (input.JustPressed(Input::PAD_DOWN)) {
+                       spellMenu.NextRow();
+               }
+               if (input.JustPressed(Input::PAD_LEFT)) {
+                       spellMenu.PreviousItem();
+               }
+       }
+
+       if (input.JustPressed(Input::ACTION_A)) {
+               if (actionMenu.IsActive()) {
+                       if (actionMenu.Selected() == CHOICE_SORT) {
+                               // TODO: sort spells
+                               LoadSpells();
+                       } else {
+                               actionMenu.SetSelected();
+                               spellMenu.SetActive();
+                       }
+               } else if (spellMenu.IsActive()) {
+                       spellMenu.SetDualSelection();
+               } else if (spellMenu.SelectedIndex() == spellMenu.SecondaryIndex()) {
+                       if (spellMenu.Selected()->CanUseOnStatusScreen()) {
+                               // TODO: use spell
+                       }
+               } else {
+                       // TODO: swap spells
+                       spellMenu.SwapSelected();
+                       spellMenu.SetActive();
+               }
+       }
+
+       if (input.JustPressed(Input::ACTION_B)) {
+               if (actionMenu.IsActive()) {
+                       Ctrl().PopState();
+               } else if (spellMenu.IsActive()) {
+                       actionMenu.SetActive();
+                       spellMenu.SetInactive();
+               } else {
+                       spellMenu.SetActive();
+               }
+       }
+}
+
+void SpellMenu::UpdateWorld(float deltaT) {
+
+}
+
+void SpellMenu::Render(SDL_Surface *screen) {
+       const Font &font(*parent->Res().normalFont);
+       Vector<int> offset((screen->w - Width()) / 2, (screen->h - Height()) / 2);
+       Vector<int> menuOffset(font.CharWidth(), 13 * font.CharHeight() + font.CharHeight() / 8);
+       Vector<int> spellsOffset(font.CharWidth(), 16 * font.CharHeight() + font.CharHeight() / 8);
+
+       parent->RenderBackground(screen);
+       RenderHighlight(screen, offset);
+       parent->RenderHeros(screen, offset);
+       RenderMenu(screen, menuOffset + offset);
+       RenderSpells(screen, spellsOffset + offset);
+}
+
+int SpellMenu::Width() const {
+       return parent->Width();
+}
+
+int SpellMenu::Height() const {
+       return parent->Height();
+}
+
+void SpellMenu::RenderHighlight(SDL_Surface *screen, const Vector<int> &offset) const {
+       if (cursor < 0) return;
+       Vector<int> statusOffset(parent->StatusOffset(cursor));
+       statusOffset -= Vector<int>(0, parent->Res().normalFont->CharHeight() / 8);
+       SDL_Rect rect;
+       rect.x = statusOffset.X();
+       rect.y = statusOffset.Y();
+       SDL_BlitSurface(highlight, 0, screen, &rect);
+}
+
+void SpellMenu::RenderMenu(SDL_Surface *screen, const Vector<int> &offset) const {
+       const Font &font(*parent->Res().normalFont);
+       const Frame &frame(*parent->Res().statusFrame);
+
+       const Vector<int> labelOffset(2 * font.CharWidth(), font.CharHeight());
+       const Vector<int> menuFrameOffset(offset.X() + 9 * font.CharWidth(), offset.Y());
+       const Vector<int> menuOffset(menuFrameOffset.X() + 3 * font.CharWidth(), menuFrameOffset.Y() + font.CharHeight());
+
+       frame.Draw(screen, offset, 9 * font.CharWidth(), 3 * font.CharHeight());
+       font.DrawString(parent->Res().mainMenuSpellText, screen, labelOffset + offset);
+       frame.Draw(screen, menuFrameOffset, 21 * font.CharWidth(), 3 * font.CharHeight());
+       actionMenu.Draw(screen, menuOffset);
+}
+
+void SpellMenu::RenderSpells(SDL_Surface *screen, const Vector<int> &offset) const {
+       const Font &font(*parent->Res().normalFont);
+       const Frame &frame(*parent->Res().statusFrame);
+       const Vector<int> menuOffset(3 * font.CharWidth(), font.CharHeight() + font.CharHeight() / 4);
+
+       frame.Draw(screen, offset, 30 * font.CharWidth(), 11 * font.CharHeight());
+       spellMenu.Draw(screen, offset + menuOffset);
+}
+
+}
 
--- /dev/null
+/*
+ * SpellMenu.h
+ *
+ *  Created on: Nov 18, 2012
+ *      Author: holy
+ */
+
+#ifndef MENU_SPELLMENU_H_
+#define MENU_SPELLMENU_H_
+
+#include "fwd.h"
+#include "../app/State.h"
+#include "../common/fwd.h"
+#include "../geometry/Vector.h"
+#include "../graphics/Menu.h"
+
+namespace menu {
+
+class SpellMenu
+: public app::State {
+
+public:
+       SpellMenu(PartyMenu *parent, int heroIndex);
+
+public:
+       virtual void HandleEvents(const app::Input &);
+       virtual void UpdateWorld(float deltaT);
+       virtual void Render(SDL_Surface *);
+
+public:
+       int Width() const;
+       int Height() const;
+
+private:
+       virtual void OnEnterState(SDL_Surface *screen);
+       virtual void OnExitState(SDL_Surface *screen);
+       virtual void OnResumeState(SDL_Surface *screen);
+       virtual void OnPauseState(SDL_Surface *screen);
+
+       virtual void OnResize(int width, int height);
+
+       const common::Hero &GetHero() const;
+
+       void LoadSpells();
+
+       void RenderHighlight(SDL_Surface *screen, const geometry::Vector<int> &offset) const;
+       void RenderMenu(SDL_Surface *screen, const geometry::Vector<int> &offset) const;
+       void RenderSpells(SDL_Surface *screen, const geometry::Vector<int> &offset) const;
+
+private:
+       PartyMenu *parent;
+       SDL_Surface *highlight;
+       int cursor;
+       enum Choice {
+               CHOICE_USE,
+               CHOICE_SORT,
+       };
+       graphics::Menu<Choice> actionMenu;
+       graphics::Menu<const common::Spell *> spellMenu;
+
+};
+
+}
+
+#endif /* MENU_SPELLMENU_H_ */