#ifndef RENDERER_H
#define RENDERER_H

#include <stdint.h>

#include "SDL.h"
#include "sge.h"

#include "../util/ResourceHandler.h"
#include "../util/Session.h"
#include "../util/stringUtils.h"

#include "../ruleset/Map.h"
#include "../ruleset/MapUnit.h"
#include "../ruleset/Player.h"
#include "../ruleset/Store.h"
#include "../ruleset/BattleAbility.h"

#include "../ruleset/Rules.h"

#include "shippingHandler.h"
#include "AudioTransformation.h"
#include "AnimatedState.h"
#include "AffineTransformationMatrix.h"

#include "../util/FixedInt.h"

#include "../state/StateDefines.h"

#include "../interface/HitBox.h"
#include "../interface/PowerSelector.h"
#include "../interface/TextContainer.h"

#include <stdint.h>

#include <vector>
#include <string>
using namespace std;

#define RENDERER_LOAD_RESOURCES 0
#define RENDERER_RELEASE_RESOURCES 1

//prototype class for the compiler
class Session;

//the Renderer's job is to position and align everything, drawing it to the surface.
//GameState should pass whatever it needs to draw to Renderer. Renderer should load resources for these items.
//Renderer only has the information it needs to draw stuff. It needs to be told, for example, what the map looks like because it shouldn't store ingame information like that.
class Renderer {
 public:
  Renderer ();
  ~Renderer ();
  bool initialize ();

  //shippingHandler
  void setResourceEngine (shippingHandler *);
  shippingHandler * getResourceEngine ();

  //session
  void setSession (Session *);
  Session * getSession ();

  //loading resources
  void startStateLoadResources (int);
  void endStateReleaseResources (int);

  //drawing object helpers
  void drawPowerSelector(vector<FixedInt> & shading, vector<string> & symbols);
  void drawTextContainer(TextContainer & tc);

  //draw sts and modular entities
  void drawPlayerStats(const string & detailLevel);
  void drawStat(int x, int y, const string & stat, const string & intConversion);

  /*
    each output screen is basically for a different game state. The
    Renderer knows nothing about this and it is up to GameState to pass
    the correct variables to it.

    These should be called by the overarching handling function.
  */
  void drawState(int);
  void stateStartTest();
  void drawStateTest();
  void drawStatePlayerAttacks();
  void stateStartPlayerAttacks();
  void drawStateBattleSwitchRound();
  void stateStartAttackPreview(int);
  void drawStateAttackPreview();
  void stateStartAttackDrawing();
  void drawStateAttackDrawing();
  void stateStartAttackWaitForUser();
  void drawStateAttackWaitForUser();
  void stateStartDefendClicking ();
  void drawStateDefendClicking ();

  void screenDelay ();

 private:
  //using ResourceHandlers to automate resource handling.
  //load the correct type of resource and store the results into this resource handler.
  bool loadToResourceHandler(const string & key, const string & resourceName, int resourceType, ResourceHandler & rh);
  //remove the resource from this resource handler. Unload it, too.
  bool removeFromResourceHandler(const string & key, ResourceHandler & rh);
  //one function to manage all resources based on state
  void stateManageResources (int state, int operation);

  //shippingHandler that handles the low-level drawing
  Session * session;

  ResourceHandler resources;
  AnimatedState animatedS, animatedS2;
};

#endif
