#pragma once
#include<Multimedia/SDX.h>
#include<Multimedia/Window.h>
#include<Multimedia/Screen.h>
#include<Multimedia/Input.h>

namespace SDX
{
/** ライブラリの初期化やシステム的な処理を行う関数群.*/
///	\include SystemSample.h
class System
{
private:
	System();
	~System();
public:

	/** ライブラリの初期化.*/
	///初期化に失敗した場合、ソフトを強制的に終了する。
	///一部の設定関数は初期化前に呼び出す必要がある。
	static void Initialise( const char* ウィンドウ名 , int 幅 , int 高さ )
	{
	#ifdef DXLIB
		Window::SetTitle(const_cast<char*>(ウィンドウ名));
		DxLib::SetGraphMode(幅, 高さ, 32);
	#ifndef DEBUG
		SetUseDirectInputFlag(FALSE);//DebugビルドではDirectInputが重い。
	#endif

		if( !Window::Single().isFullScreen )
		{
			DxLib::ChangeWindowMode( true );
		}

		if( DxLib::DxLib_Init() == -1 ) exit(1);

		DxLib::SetDrawScreen( DX_SCREEN_BACK ); 
	#elif defined(SDL)
		if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER) < 0) 
		{
			fprintf(stderr, "SDLの初期化に失敗しました：%s\n", SDL_GetError());
			exit(1);
			return;
		}

		setlocale(LC_CTYPE, "jpn");//文字コードを日本語に

		TTF_Init();

		int flag = 0;
		if (Window::Single().isFullScreen)
		{
			flag = SDL_WINDOW_FULLSCREEN;
		}

		Window::Single().handle = SDL_CreateWindow( ウィンドウ名 ,SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 幅 , 高さ , flag);
		Screen::SetRenderer(SDL_CreateRenderer(Window::Single().handle, 0, SDL_RENDERER_ACCELERATED));	

		//音声関連の初期化
		Mix_OpenAudio(44100, AUDIO_S16, 2, 4096);
		Mix_AllocateChannels(16);
	#endif
	}
			
	/** ライブラリの終了処理.*/
	///この関数を使用した後は速やかにプログラムを終了させなければならない。
	static bool End()
	{
	#ifdef DXLIB
		return !DxLib::DxLib_End();
	#elif defined(SDL)
		TTF_Quit();
		Mix_CloseAudio();
		SDL_Quit();		
		return true;
	#endif
	}

	/** 各種更新処理をまとめて行う.*/
	static bool Update(bool 描画更新フラグ = true)
	{
		if (描画更新フラグ)
		{
			Screen::Flip();
			Screen::Clear();
		}
		bool result = System::ProcessMessage();
		Input::Update();
		return result;
	}

	/** OSのメッセージ処理を行う.*/
	///目安として1/60秒に一回程度、この関数を呼び出す必要があり。
	///falseを返した場合、速やかにプログラムを終了させなければならない。
	static bool ProcessMessage()
	{
	#ifdef DXLIB
		return !DxLib::ProcessMessage();
	#elif defined(SDL)
		SDL_Event event;

		while (SDL_PollEvent(&event))
		{
			/* QUIT イベントが発生したら終了する*/
			if (event.type == SDL_QUIT) return false;
			else Input::GetState(event);
		}

		return true;
	#endif
	}

	/** ログ出力の有無を設定.*/
	///DXライブラリのデバッグ情報ログ・ファイル『App.log』を出力設定する。
	///この関数は、Initialise前に呼び出す必要がある。
	static bool SetOutputLog( bool 出力フラグ)
	{
	#ifdef DXLIB
		return !DxLib::SetOutApplicationLogValidFlag(出力フラグ);
	#elif defined(SDL)
		return false;
	#endif
	}
			
	/** ビデオRAM使用を設定.*/
	///この関数は、Initialise前に呼び出す必要がある。
	static bool SetMemToVram( bool VRAM使用フラグ)
	{
	#ifdef DXLIB
		return !SetScreenMemToVramFlag(VRAM使用フラグ);
	#elif defined(SDL)
		return false;
	#endif
	}

	/** 非アクティブ時も処理を続行するか設定.*/
	///デフォルトで非アクティブ時は処理を停止する。
	static bool SetAlwaysRun( bool 常時処理フラグ )
	{
	#ifdef DXLIB
		return !DxLib::SetAlwaysRunFlag(常時処理フラグ);
	#elif defined(SDL)
		return false;
	#endif
	}
};
}

