/* vim: ts=4 sw=4 sts=4 fenc=utf-8 :
 * =============================================================================
 *  SDL sample  for  C
 * =============================================================================
 */

#include <stdio.h>
#include <string.h>

#include <SDL.h>
#include <SDL_ttf.h>


/* エラーメッセージ出力. */
#define ERROR(x)     printError(x, __FILE__, __LINE__)
#define SDL_ERROR(x) printSDLError(x, __FILE__, __LINE__)

/* プロトタイプ宣言 */
int  init(void);
void quit(void);
SDL_Surface* setVideoMode(void);
void mainLoop(void);

/* プロトタイプ宣言 [フォント表示]. */
void showFont(SDL_Surface* screen, const char* msg);
void getFontName(char* fontfile);

/* プロトタイプ宣言 [エラー表示用]. */
void printError(const char* msg, const char* file, int line);
void printSDLError(const char* msg, const char* file, int line);


/**
 * MAIN.
 *
 * @param argc   起動引数の数
 * @param argv[] 起動引数
 *        [1] メディアファイル(省略時は, sample/resource/park.mp3 を使用する)
 *        [2] サンプリングレート
 * ※日本語ファイル名は対応していません...
 */
int main(int argc, char* argv[])
{
	int ret;
	SDL_Surface* screen;

	/* SDL初期化. */
	ret = init();
	if (ret < 0) { return -1; }

	/* SDL終了処理を終了時に自動実行するよう登録. */
	atexit(quit);

	/* ビデオモード設定. */
	screen = setVideoMode();
	if (screen == NULL) { return -1; }

	/* フォント表示 */
	showFont(screen, "Sample");

	/* メインループ */
	mainLoop();

	return 0;
}


/**
 * SDL初期化.
 */
int init(void)
{
	/* 初期化 */
	int ret = SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
	if (ret < 0)
	{	/* 初期化エラー */
		SDL_ERROR("can't init sdl.");
		return -1;
	}

	/*
	 * SDL_Init 後にまだ初期化していないサブシステムを
	 * 初期化する場合は, 下記関数を使用する.
	 * int SDL_InitSubSystem(Uint32 flags);
	 */

	return 0;
}


/**
 * SDL終了処理.
 */
void quit(void)
{
	SDL_Quit();
}


/**
 * ビデオ表示初期化.
 * @return SDL_Screen
 */
SDL_Surface* setVideoMode(void)
{
	SDL_Surface* screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);
	if (screen == NULL)
	{	/* ビデオモード設定エラー */
		SDL_ERROR("can't set video mode.");
		return NULL;
	}
	return screen;
}


/**
 * メディア再生.
 *
 * @param screen スクリーン
 * @param msg    メッセージ
 */
void showFont(SDL_Surface* screen, const char* msg)
{
	int          ret;
	SDL_Surface* txtSurface;
	TTF_Font*    font;
	SDL_Color    color = { 0, 0, 255, 0 };
	SDL_Rect     dest;
	char         fontfile[1024];

	/* TTF 初期化 */
	ret = TTF_Init();
	if (ret != 0)
	{
		SDL_ERROR("can't init ttf");
		return;
	}

	/* フォントファイルオープン */
	getFontName(fontfile);
	font = TTF_OpenFont(fontfile, 12);
	if (!font)
	{
		SDL_ERROR("can't open font");
		return;
	}

	/* 文字設定 */
	txtSurface = TTF_RenderUTF8_Solid(font, msg, color);

	dest.x = 0;
	dest.y = 0;
	SDL_BlitSurface(txtSurface, NULL, screen, &dest);

	/* 画面更新 */
	SDL_Flip(screen);
}


/**
 * イベントループ.
 * @param music メディア停止用
 */
void mainLoop(void)
{
	int quit = 0;
	SDL_Event event;

	/* unicode 変換を有効にする. */
	SDL_EnableUNICODE(1);

	while (!quit)
	{
		while (SDL_PollEvent(&event))
		{
			switch (event.type)
			{
				/* SDL_QUIT イベント (ウィンドウが閉じられた) */
				case SDL_QUIT:
					quit = 1;
					break;
				default:
					break;
			}
		}
	}
}


/* =============================================================================
 *  以下, エラーメッセージ表示や, ユーティリティなど.
 *  本質ではないので・・・あんま見なくて良いかと.
 * =============================================================================
 */
/**
 * エラーメッセージ表示.
 *
 * @param msg  メッセージ
 * @param file ファイル名
 * @param line 行番号
 */
void printError(const char* msg, const char* file, int line)
{
	fprintf(stderr, "%s:%d %s\n", file, line, msg);
}


/**
 * SDLエラーメッセージを含む, エラーメッセージ表示.
 *
 * @param msg  メッセージ
 * @param file ファイル名
 * @param line 行番号
 */
void printSDLError(const char* msg, const char* file, int line)
{
	char* sdlerr = SDL_GetError();
	fprintf(stderr, "%s:%d %s [%s]\n", file, line, msg, sdlerr);
}


/**
 * フォントファイル名取得.
 * @return フォントファイル名
 */
void getFontName(char* fontfile)
{
	char* path = getenv("SystemRoot");
	sprintf(fontfile, "%s\\Fonts\\arial.ttf", path);
}

