/**
 *  Triangles
 *  Copyright (C) 2016 POSITIVE MENTAL ATTITUDE
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, version 3 of the License.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <SFML/Graphics.hpp>
#include <vector>
#include <functional>
#include "TrianglesWindow.hpp"
#include "State.hpp"
#include "Assets.hpp"
#include "Triangle.hpp"

class Triangles 
{
	public:
		Triangles() = delete;
		Triangles(int argc, char** argv);
		int run();

	private:
		/**
		 * @brief This speaks for itself.
		 */
		void init();
		/**
		 * @brief This will redo some of constructor's and init's job, reading the program arguments.
		 * @param argc Argument count + 1
		 * @param argv Argument vector
		 */
		void passArguments(int argc, char** argv);
		void searchArgument(int argc, std::string argvStr[], std::string callShort, std::string callLong, std::function<void()> lambda);
		void searchArgument(int argc, std::string argvStr[], std::string callShort, std::string callLong, std::function<void(std::string param)> lambda);
		/**
		 * @brief Changes gamestate.
		 * @param stateType The type of state that is about to be loaded (takes flags from the enum of State class).
		 */
		void load(int stateType);
		/**
		 * @brief Called whenever the screen resolution changes.
		 */
		void refresh();
		/**
		 * @brief Game's event loop
		 */
		void coreThink();
		/**
		 * @brief Input outside of the event loop.
		 */
		void coreInput();
		/**
		 * @brief Handles the top-left fps counter, if it is enabled.
		 * @param delta Delta time since last update.
		 */
		void fpsCalc(sf::Time delta);
		/**
		 * @brief Game logic
		 * @param delta Delta time since last update.
		 */
		void coreUpdate(sf::Time delta);
		/**
		 * @brief Renders the stuff of the current gamestate.
		 */
		void coreRender();
		/**
		 * @brief A temporal loop that renders the loading screen in a seperate thread. Calls coreThink() and renders stuff.
		 */
		void loadingRender();
		
		sf::Text _loadingText;
		sf::Text _loadingHint;
		Triangle _loadingTriangle;
		std::vector<sf::String> _loadingHints;
		
		int _returnCode;
		
		TrianglesWindow _window;
		
		sf::Text _fps;
		sf::RectangleShape _fpsRect;
		
		State* _current;
		int _initialState;
		
		Context _context; // Intended to be a pointer for States.
		Context _variables; // Used internally by Triangles class.
		
		Assets _assets;
};