/***************************************************************


		C言語の復習

								Author		tanaka kazuki
								Script		C
								CreateDate	2016/04/21
----------------------------------------------------------------
■Update 4/21
・簡易的にscanfの不正値を検出するように変更

■Update 4/28
・配列->構造体のポインタに変更
・UIを改善(見やすくした感じ...)
■Update 5/12
・セーブロード機能を追加
・不定な値のエラー処理を追加

***************************************************************/



/***************************************************************

	インクルードファイル

***************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Windows.h>

/**************************************************************

		マクロ定義

**************************************************************/

#define ENABLE_PROC_SAVE	//セーブ処理有効
//#undef ENABLE_PROC_SAVE		//セーブ処理無効

/**************************************************************

		定数定義

**************************************************************/

#define FILE_NAME "data.bin"

#define NAME_MAX (256)		//名前の最大ビット数
#define MAX_PLAYER (64)		//最大のプレイヤー入力人数
#define PLAYER_NUMBER (3)	//扱うプレイヤーの数

#define MAX_HEIGHT (300)	//身長の最大
#define MAX_WEIGHT (1000)	//体重の最大
/**************************************************************

	構造体

**************************************************************/

typedef enum
{

	MODE_FINISH=0,			//終了
	MODE_INPUT,				//入力
	MODE_OUTPUT,			//出力
	MODE_SAVE,				//セーブ
	MODE_LOAD,				//ロード
	MODE_MAX				//マックス

}MODE;

typedef struct {
	
	char aName[NAME_MAX];	//氏名
	int nAge;				//年齢
	float fHeight;			//身長
	float fWeight;			//体重

}PERSONALDATA;

typedef struct {
	
	int nTotalAge;			//総合年齢
	float fTotalHeight;		//総合身長
	float fTotalWeight;		//総合体重

}TOTALPARAMETER;


/**************************************************************

	プロトタイプ宣言

***************************************************************/

void selectMode( void );							//モードの選択

void Input (PERSONALDATA *pData,int *player);		//データを入力する関数
void Output (PERSONALDATA *pData,int player);		//データを出力する関数

void saveData(int *player,PERSONALDATA *aData);		//データをセーブする
bool loadData(int *player,PERSONALDATA *aData);		//データをロードする

/***************************************************************

	関数(function)

****************************************************************/
//プログラムのメイン処理
void main( void ){


	//モードの選択
	selectMode( );



}
//モード選択
void selectMode( void )
{
	
	PERSONALDATA aData[MAX_PLAYER];		//プレイヤーのデータを格納

	int player;							//使用するプレイヤーの数

	MODE mode;							//モード

	int select;							//モードの選択
	bool modeInput=false;				//モードの選択が正しいか判定
	bool saveClear=false;				//セーブフラグ
	bool loadClear=false;				//ロードフラグ
	bool clearInput=false;				//

	//モード選択
	do{
	
		while(!modeInput){

			system("cls");												//画面初期化
			
			printf("使用したいモードを選択してください\n");
			printf("1 : Input\n");
			printf("2 : Output\n");
			printf("3 : Save\n");
			printf("4 : Load\n");
			printf("0 : exit\n");

			printf("> :");
			rewind(stdin);
			scanf("%d",&select);

			if(select < MODE_MAX){
				modeInput=true;
			}
		}
		

		switch(select)
		{

			case MODE_FINISH:

					printf("終了します!");
					rewind(stdin);
					getchar();
					system("cls");
				
				break;


			case MODE_INPUT:

					Input (&aData[0],&player);
					saveClear=true;
					clearInput=true;

				break;

			case MODE_OUTPUT:

					if(loadClear==true || clearInput==true){
						Output (&aData[0],player);
					}
					else
					{
						printf("出力出来ませんロードしてください\n");
						rewind(stdin);
						getchar();
						system("cls");

					}


				break;

			case MODE_SAVE:

					if(saveClear==true){
						saveData(&player,&aData[0]);
					}
					else
					{
						printf("セーブ出来ません\n");
						rewind(stdin);
						getchar();
						system("cls");
					}

				break;

			case MODE_LOAD:

					loadClear=loadData(&player,&aData[0]);
					

				break;

			default:

				break;
		
		}
		modeInput=false;
	
	}while( select!=MODE_FINISH );

}
//#ifdef ENABLE_PROC_SAVE
//main関数からもらったデータに内容を入れる
void Input (PERSONALDATA *pData,int *player){


	int strCount;		//文字列をカウントする:氏名の合成に使用

	//エラー処理
	if( player==NULL )
	{
		exit(EXIT_FAILURE);
	}
	if( pData==NULL )
	{
		exit(EXIT_FAILURE);
	}

	printf("+++ 個人情報の入力を開始します +++ : PRESS ENTER KEY▼");

	rewind(stdin);
	getchar();

	do{

		printf("何人のデータを入力しますか？ 1〜%d ※半角数字 > ",PLAYER_NUMBER);

		scanf("%d",&(*player));
		rewind(stdin);



		if( (*player) >PLAYER_NUMBER){
		
			printf("入力内容が間違っています\n");

		}

	}while( (*player) >PLAYER_NUMBER || (*player) <= 0);


	for(int count=0;count< (*player) ;pData++,count++){


		printf("\n");

		printf("+++ %d人目の入力を開始します +++ : ▼\n",count+1);

		//rewind(stdin);
		//getchar();



		//氏名を入力
		do{


			printf("半角で256文字以内or全角85文字以内でお願いしますm(_ _)m\n");

			//苗字を入力
			printf("苗字 > ");

			scanf("%s",&pData->aName[0]);

			rewind(stdin);					//標準出力に値を返す
			
			strCount=strlen(pData->aName);

			pData->aName[strCount]=' ';		//苗字と名前の間に空白を入力!!

			//名前を入力
			printf("名前 > ");

			scanf("%s",&pData->aName[strCount+1]);

			rewind(stdin);					//標準出力に値を返す

			strCount=strlen(pData->aName);

			if(strCount>NAME_MAX){
		
				printf("入浴内容が間違っています\n");

			}

		}while(strCount>NAME_MAX);


		//年齢を入力
		do{

			printf("※この先半角数字!!\n");

			printf("年齢 > ");

			//定数を入力
			scanf("%d",&pData->nAge);	//nDataのアドレスに好きな数を代入
			
			rewind(stdin);				//標準出力に値を返す

			//scanfに不正な値が入力された場合もう一度実行
			if(pData->nAge<0){
			
				printf("入力内容が間違っています\n");
	
			}

		}while(pData->nAge<0);


		//身長を入力
		do{


			printf("cmで入力\n");

			printf("身長 > ");

			//定数を入力
			scanf("%f",&pData->fHeight);		//nDataのアドレスに好きな数を代入
			
			rewind(stdin);					//標準出力に値を返す

			//scanfに不正な値が入力された場合もう一度実行
			if(pData->fHeight<0 || pData->fHeight>MAX_HEIGHT){
			
				printf("入力内容が間違っています\n");
	
			}

		}while(pData->fHeight<0 || pData->fHeight>MAX_HEIGHT);



		//体重を入力
		do{

			printf("kgで入力\n");

			printf("体重 > ");

			//定数を入力
			scanf("%f",&pData->fWeight);		//nDataのアドレスに好きな数を代入
			
			rewind(stdin);					//標準出力に値を返す

			//scanfに不正な値が入力された場合もう一度実行
			if(pData->fWeight<0 || pData->fWeight>MAX_WEIGHT){
			
				printf("入力内容が間違っています\n");
	
			}

		}while(pData->fWeight<0 || pData->fWeight>MAX_WEIGHT);

	}
}
//データをセーブする
void saveData(int *player,PERSONALDATA *aData)
{

	FILE *pFile;

	
	//エラー処理
	if( *player==0 || *player>PLAYER_NUMBER)
	{
		printf("プレイヤーの数が正常ではありません!!");
	}
	else{

		if(aData!=NULL){

			pFile = fopen(FILE_NAME,"wb");
			
			if(pFile!=NULL){

				fwrite(player,sizeof(int),1,pFile);

				fwrite(aData,sizeof(PERSONALDATA),(*player),pFile);

				fclose(pFile);

			}
			else{
				printf("ファイルが開けませんでした!\n");
			}

		}
		else
		{
			printf("データの値が不正です\n");
		}
	}

	printf("セーブが完了しました!!\n");
	rewind(stdin);
	getchar();
	system("cls");

}
//#else
//データをロードする
bool loadData(int *player,PERSONALDATA *aData)
{

	FILE *pFile;
	
	if( player == NULL )
	{
		printf("プレイヤーに不正な値が入っています\n");
	}
	else{
		if(aData != NULL)
		{
			pFile = fopen(FILE_NAME,"rb");

			if(pFile!=NULL){

				fread(player,sizeof(int),1,pFile);

				fread(aData,sizeof(PERSONALDATA),(*player),pFile);

				fclose(pFile);

				printf("ロードが完了しました!!\n");

				return true;

			}
			else{
			
				printf("ロードに失敗しました!!");

			}
		}
		else{
			printf("データに不正な値が入っています\n");
		}
	}

	rewind(stdin);
	getchar();
	system("cls");
	
	return false;

}
//main関数からもらったデータを出力
void Output (PERSONALDATA *pData,int player)
{

	TOTALPARAMETER totalData;

	//エラー処理
	if( player==0 || player>PLAYER_NUMBER)
	{
		exit(EXIT_FAILURE);
	}
	if( pData == NULL )
	{
		exit(EXIT_FAILURE);
	}

	int count;		//カウントに使用

	//総合構造体の初期化
	totalData.nTotalAge=0;
	totalData.fTotalHeight=0;
	totalData.fTotalWeight=0;

	system("cls");

	printf("%d",player);

	for(count=0;count<player;count++,pData++){

		printf("-------------------------------------\n");

		printf("%d人目のデータを出力します : ▼\n",count+1);

		printf("-------------------------------------\n");

		//nDataの中身を出力
		printf("氏名 : %s\n",&pData->aName[0]);
		printf("年齢 : %d 歳\n",pData->nAge);
		printf("身長 : %f cm\n",pData->fHeight);
		printf("体重 : %f kg\n",pData->fWeight);

		printf("-------------------------------------\n");

		
		if(pData->fHeight/pData->fWeight<0){
		
			printf("ダイエットしましょう(^q^)ノ\n");
		
		}
		if(pData->fHeight/pData->fWeight>=2.5f){
		
			printf("OKです!!(^o^)ノ\n");

		}
		if(pData->fHeight/pData->fWeight<2.5f){
		
			printf("少し生活を意識しましょう!\n");
		
		}

	}

	for(count=0;count<player;count++,pData--){
		/* 特に何も処理はなしpDataの値を戻す */
	}

	printf("-------------------------------------\n");

	printf("       +++  総合評価  ++++\n");

	printf("-------------------------------------\n");

	for(count=0;count<player;count++,pData++){


		(totalData.nTotalAge)+=(pData->nAge);

	}
	
	totalData.nTotalAge/=player;

	if( totalData.nTotalAge >=0 && totalData.nTotalAge <=25 ){
		
		printf("全体的に若いですね...\n");

	}
	else if( totalData.nTotalAge >=26 && totalData.nTotalAge <=49 ){
		
		printf("全体的に中年が集まっているそんな感じですね...\n");

	}
	else if( totalData.nTotalAge >=50 ){
		
		printf("全体的に年齢層がかなり高いですね...\n");

	}
	

	printf("-------------------------------------\n");

	rewind(stdin);
	getchar();

}
//#endif

