#include "wsubform.h"	//サブフォーム専用ヘッダファイルをインクルードする。

#define Textbox	1
#define Grid	2
#define Panel	3

#define Tret	199
#define Gret	299
#define Pret	399

extern int wmode;
extern char gridtitles[MAX_POS][MAX_LEN];

extern TextBox	 *begin;
extern TextBox	 *tp;

typedef struct stat Dir;
static Dir dirptr;
static Dir  *fileptr = &dirptr;

char tmp[MAX_STR];
static int sqlcode = 0;
static int DBcount = 0;

int DBConnect(void)
{
	// DB接続用変数宣言
	EXEC SQL BEGIN DECLARE SECTION;
		char dbname[12];
		char user[12];
		char passwd[12];
	EXEC SQL END DECLARE SECTION;

	strcpy(dbname,"apsch");
	strcpy(user,"cms");
	strcpy(passwd,"cms");

	// ECPGデバッグ文出力設定
	ECPGdebug (0, stderr);

	// 接続
	memset (sqlca.sqlstate, '0', 5);
	EXEC SQL CONNECT TO :dbname AS dbConnection user :user USING :passwd;
	if (memcmp (sqlca.sqlstate, "00", 2) != 0)
	{
		sprintf(tmp,"CONNECT エラー。終了します。:%d - %s",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
		popmsg((COLS/2)-24,(LINES/2)-4,tmp);
		exit (EXIT_FAILURE);
	}
	return(0);
}

int FetchTBL(int no)
{
	static char DBbuff[MAX_STR];
	int i = 0;

	DBConnect();
	memset (sqlca.sqlstate, '0', 5);

	EXEC SQL BEGIN DECLARE SECTION;
		int rec_count;
		char	schedule_name[16 + 1];
		char	schedule_day[8 + 1];
		char	schedule_time[4 + 1];
		char	cmd_line[256 + 1];
		int		status;	
		char	start_time[14 + 1];	
		char	end_time[14 + 1];
		int		error_code;	
		int		max_retry_count;
		int		retry_interval;
		int		current_retry_count;
		char	entry_date[22 + 1];
		char	update_date[22 + 1];
		char	comment1[40 + 1];
	EXEC SQL END DECLARE SECTION;

	sqlcode = 0;
	DBcount = 0;

	rec_count = 0;

	// スケジュール情報テーブル取得
	EXEC SQL 
	SELECT 
	COUNT(*)
	INTO :rec_count
	FROM	schdytbl;
	EXEC SQL END;

	// SELECTエラー 
	if(memcmp (sqlca.sqlstate, "00", 2) != 0)
	{
		sprintf(tmp,"データベースSELECTエラー:%d - %s",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
		popmsg((COLS/2)-24,(LINES/2)-4,tmp);
		return(-1) ;
	}

	DBcount = rec_count;

	EXEC SQL DECLARE schdytbl_CURSOR CURSOR FOR 
	SELECT 
		coalesce(schedule_name,' ','0'),
		coalesce(schedule_day,' ','0'),
		coalesce(schedule_time,' ','0'),
		coalesce(cmd_line,' ','0'),
		status,
		coalesce(start_time,' ','0'),
		coalesce(end_time,' ','0'),
		error_code,
		max_retry_count,
		retry_interval,
		current_retry_count,
		TO_TIMESTAMP(entry_date, 'YYYY/MM/DD HH24:MI:SS'),
		TO_TIMESTAMP(update_date, 'YYYY/MM/DD HH24:MI:SS'),
		coalesce(comment1,' ','0')
	FROM	schdytbl
	ORDER BY schedule_name;
	EXEC SQL END;

	// カーソルオープン
	EXEC SQL OPEN schdytbl_CURSOR;

	// SELECT OPENエラー 
	if (memcmp (sqlca.sqlstate, "00", 2) != 0)
	{
		sprintf(tmp,"データベースSELECT OPENエラー:%d - %s",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
		popmsg((COLS/2)-24,(LINES/2)-4,tmp);
		return(-1);
	}

	for(i=0;i<DBcount;i++)
	{
	EXEC SQL FETCH schdytbl_CURSOR INTO
		:schedule_name,
		:schedule_day,
		:schedule_time,
		:cmd_line,
		:status,
		:start_time,
		:end_time,
		:error_code,
		:max_retry_count,
		:retry_interval,
		:current_retry_count,
		:entry_date,
		:update_date,
		:comment1;

		if (memcmp (sqlca.sqlstate, "00", 2) != 0)
		{
			fprintf (stderr, "%s\n", sqlca.sqlerrm.sqlerrmc);
			return(-1);
		}

	// テーブル項目をsplitbDBbuff[][]にセットする
		sf_assgetDB(no,i,0,schedule_name,16 + 1);
		sf_assgetDB(no,i,1,schedule_day,8 + 1);
		sf_assgetDB(no,i,2,schedule_time,4 + 1);
		sf_assgetDB(no,i,3,cmd_line,256 + 1);
		sf_to_text(status,DBbuff);	//NUMERIC型(int)を文字に変換する。
		sf_assgetDB(no,i,4,DBbuff,2 + 1);
		sf_assgetDB(no,i,5,start_time,14 + 1);
		sf_assgetDB(no,i,6,end_time,14 + 1);
		sf_to_text(error_code,DBbuff);	//NUMERIC型(int)を文字に変換する。
		sf_assgetDB(no,i,7,DBbuff,5 + 1);
		sf_to_text(max_retry_count,DBbuff);	//NUMERIC型(int)を文字に変換する。
		sf_assgetDB(no,i,8,DBbuff,5 + 1);
		sf_to_text(retry_interval,DBbuff);	//NUMERIC型(int)を文字に変換する。
		sf_assgetDB(no,i,9,DBbuff,5 + 1);
		sf_to_text(current_retry_count,DBbuff);	//NUMERIC型(int)を文字に変換する。
		sf_assgetDB(no,i,10,DBbuff,4 + 1);
		sf_assgetDB(no,i,11,entry_date,22 + 1);
		sf_assgetDB(no,i,12,update_date,22 + 1);
		sf_assgetDB(no,i,13,comment1,40 + 1);

		if (memcmp (sqlca.sqlstate, "00", 2) != 0)
		{
			EXEC SQL CLOSE schdytbl_CURSOR;
			EXEC SQL END;
			sprintf(tmp,"データベースFETCHエラー:%d - %s",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
			popmsg((COLS/2)-24,(LINES/2)-4,tmp);
			return(-1);
		}
	}
	// カーソルクローズ 
	EXEC SQL CLOSE schdytbl_CURSOR;
	EXEC SQL END;

	DBcount = rec_count;

	// 結果チェック
	if (sqlca.sqlcode != 0)
	{
		sprintf(tmp,"データベースFETCH結果チェック:%d - %s",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
		popmsg((COLS/2)-24,(LINES/2)-4,tmp);
		return(0);
	}
	// 切断
	sqlca.sqlcode = 0;
	EXEC SQL DISCONNECT dbConnection;
	return(0);
}

//***********************************************************************
// NAME     : UpdateTBL		テーブルの更新
// SYNOPSIS : UpdateTBL()
// RETURN   : 	0	成功
//		-1	失敗
//***********************************************************************
int	UpdateTBL(int no,const char* key1,const char* key2,int sqlcode,int line)
{
	static char DBbuff[MAX_STR];

	DBConnect();

	memset (sqlca.sqlstate, '0', 5);
	EXEC SQL BEGIN DECLARE SECTION;
		char	schedule_name[16+1];
		char	schedule_day[8+1];
		char	schedule_time[4+1];
		char	cmd_line[256 + 1];
		int	  	status;
		char	start_time[14 + 1];
		char	end_time[14 + 1];
		int	  	error_code;
		int	  	max_retry_count;
		int		retry_interval;
		int	  	current_retry_count;
		char  	entry_date[19 + 1];
		char  	update_date[19 + 1];
		char	comment1[40 + 1];
	EXEC SQL END DECLARE SECTION;

  	sqlcode = 0;

	strncpy((char*)schedule_name,key1,sizeof(schedule_name));   // KEY
	strncpy((char*)schedule_day,key2,sizeof(schedule_day));   // KEY

		// テーブル項目をsplitbDBbuff[]からDB配列にセットする。
		sf_assputDB(no,0,schedule_name,16+1);
		sf_assputDB(no,1,schedule_day,8+1);
		sf_assputDB(no,2,schedule_time,4+1);
		sf_assputDB(no,3,cmd_line,256+1);
		sf_assputDB(no,4,DBbuff,2+1);
		status = sf_to_integer(DBbuff);

		sf_assputDB(no,5,start_time,14+1);
		sf_assputDB(no,6,end_time,14+1);

		sf_assputDB(no,7,DBbuff,5+1);
		error_code = sf_to_integer(DBbuff);

		sf_assputDB(no,8,DBbuff,5+1);
		max_retry_count = sf_to_integer(DBbuff);
		sf_assputDB(no,9,DBbuff,5+1);
		retry_interval = sf_to_integer(DBbuff);
		sf_assputDB(no,10,DBbuff,5+1);
		current_retry_count = sf_to_integer(DBbuff);
		sf_assputDB(no,11,entry_date,22+1);
		sf_assputDB(no,12,update_date,22+1);
		sf_assputDB(no,13,comment1,40+1);

 	/* 更新対象レコードをUPDATE */
	EXEC SQL UPDATE SCHDYTBL
    	SET 
		SCHEDULE_NAME=		:schedule_name,
		SCHEDULE_DAY=		:schedule_day,
		SCHEDULE_TIME=		:schedule_time,
		CMD_LINE=			:cmd_line,
		STATUS=				:status,
		START_TIME=			:start_time,
		END_TIME=			:end_time,
		ERROR_CODE=			:error_code,
		MAX_RETRY_COUNT=	:max_retry_count,
		RETRY_INTERVAL=		:retry_interval,
		CURRENT_RETRY_COUNT=:current_retry_count,
		ENTRY_DATE=			TO_DATE(:entry_date, 'YYYY/MM/DD HH24:MI:SS'),
		UPDATE_DATE=		TO_DATE(:update_date, 'YYYY/MM/DD HH24:MI:SS'),
		COMMENT1=			:comment1

	WHERE	SCHEDULE_NAME =	:schedule_name AND SCHEDULE_DAY = :schedule_day;
	EXEC SQL END;


	/* 更新エラー */
	if (memcmp (sqlca.sqlstate, "00", 2) != 0)
	{

  	/* ロールバック */
  		EXEC SQL ROLLBACK WORK;
		EXEC SQL END;
		sprintf(tmp,"データベースUPDATEエラー:%d - %s",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
		popmsg((COLS/2)-24,(LINES/2)-4,tmp);
		return(-1);
	}

  	/* コミットする */
	EXEC SQL COMMIT WORK;
	EXEC SQL END;

	/* 結果チェック */
	if (sqlca.sqlcode != 0)
	{
		sprintf(tmp,"UPDATE結果チェック:%d - %s",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
		popmsg((COLS/2)-24,(LINES/2)-4,tmp);
		return(-1);
	}
	/* 切断 */
	sqlca.sqlcode = 0;
	EXEC SQL DISCONNECT dbConnection;
	EXEC SQL END;

	return(0);
}

//***********************************************************************
// NAME     : InsertTBL     テーブルの登録
// SYNOPSIS : AddTBL()
// RETURN   : 	0	成功
//		-1	失敗
//***********************************************************************
int	InsertTBL(int no, const char* key1,const char* key2,int sqlcode)
{
	static char DBbuff[MAX_STR];

	DBConnect();

	memset (sqlca.sqlstate, '0', 5);
  /* テーブル作成 */
  	EXEC SQL BEGIN DECLARE SECTION;
		char		schedule_name[16+1];
		char		schedule_day[8+1];
		char		schedule_time[4+1];
		char		cmd_line[256+1];
		int		status;	
		char		start_time[14+1];
		char		end_time[14+1];
		int		error_code;
		int		max_retry_count;
		int		retry_interval;
		int		current_retry_count;
		char		entry_date[19+1];
		char		update_date[19+1];
		char		comment1[40+1];
	EXEC SQL END DECLARE SECTION;

  /* インサート */
	// テーブル項目をsplitbDBbuff[]からDB配列にセットする。
	sf_assputDB(no,0,schedule_name,16+1);
	sf_assputDB(no,1,schedule_day,8+1);
	sf_assputDB(no,2,schedule_time,4+1);
	sf_assputDB(no,3,cmd_line,256+1);
	sf_assputDB(no,4,DBbuff,2+1);
	status = sf_to_integer(DBbuff);

	sf_assputDB(no,5,start_time,14+1);
	sf_assputDB(no,6,end_time,14+1);

	sf_assputDB(no,7,DBbuff,5+1);
	error_code = sf_to_integer(DBbuff);

	sf_assputDB(no,8,DBbuff,5+1);
	max_retry_count = sf_to_integer(DBbuff);
	sf_assputDB(no,9,DBbuff,5+1);
	retry_interval = sf_to_integer(DBbuff);
	sf_assputDB(no,10,DBbuff,5+1);
	current_retry_count = sf_to_integer(DBbuff);
	sf_assputDB(no,11,entry_date,22+1);
	sf_assputDB(no,12,update_date,22+1);
	sf_assputDB(no,13,comment1,40+1);

  	/* 対象レコードをADD */
   	EXEC SQL INSERT INTO SCHDYTBL
	(SCHEDULE_NAME,
	SCHEDULE_DAY,
	SCHEDULE_TIME,
	CMD_LINE,
	STATUS,
	START_TIME,
	END_TIME,
	ERROR_CODE,
	MAX_RETRY_COUNT,
	RETRY_INTERVAL,
	CURRENT_RETRY_COUNT,
	ENTRY_DATE,
	UPDATE_DATE,
	COMMENT1)
	VALUES
	(:schedule_name,
	:schedule_day,
	:schedule_time,
	:cmd_line,
	:status,
	:start_time,
	:end_time,
	:error_code,
	:max_retry_count,
	:retry_interval,
	:current_retry_count,
	TO_TIMESTAMP(:entry_date,'YYYY/MM/DD HH24:MI:SS'),
	TO_TIMESTAMP(:update_date,'YYYY/MM/DD HH24:MI:SS'),
	:comment1);
	EXEC SQL END;

	/* 登録エラー */
	if (memcmp (sqlca.sqlstate, "00", 2) != 0)
	{
  	/* ロールバック */
  		EXEC SQL ROLLBACK WORK;
		EXEC SQL END;
		sprintf(tmp,"データベースINSERTエラー:%d - %s",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
		popmsg((COLS/2)-24,(LINES/2)-4,tmp);
		return(-1);
	}

	/* コミット */
	EXEC SQL COMMIT;
	EXEC SQL END;

	/* 結果チェック */
	if (sqlca.sqlcode != 0)
	{
		sprintf(tmp,"INSERT結果チェック:%d - %s",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
		popmsg((COLS/2)-24,(LINES/2)-4,tmp);
		return(-1);
	}
	/* 切断 */
	sqlca.sqlcode = 0;
	EXEC SQL DISCONNECT dbConnection;
	return(0);
}

//***********************************************************************
// NAME     : DeleteTBL()	レコード削除(キー１個)
// SYNOPSIS : DeleteTBL()
// RETURN   :	0	成功
//		-1	失敗
//***********************************************************************
int	DeleteTBL(const char* key,int sqlcode)
{
	DBConnect();

	memset (sqlca.sqlstate, '0', 5);

		/* ホスト変数定義 */
  	EXEC SQL BEGIN DECLARE SECTION;
		char		schedule_day[16+1];	/* スケジュール名称 */
	EXEC SQL END DECLARE SECTION;

	sqlcode = 0;

		/* スケジュール名（キー項目）設定 */
	memset((char *)schedule_day, '\0', sizeof(schedule_day));
	strncpy((char*)schedule_day,key,sizeof(schedule_day));

		/* 削除対象レコードをDELETE */
	EXEC SQL DELETE FROM SCHDYTBL
	WHERE	SCHEDULE_DAY =:schedule_day;
	EXEC SQL END;

		/* DELETE失敗 */
	if (memcmp (sqlca.sqlstate, "00", 2) != 0)
	{
  		/* ロールバック */
  		EXEC SQL ROLLBACK WORK;
		EXEC SQL END;
		sprintf(tmp,"データベースDELETEエラー:%d - %s",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
		popmsg((COLS/2)-24,(LINES/2)-4,tmp);
		return(-1);
	}

		/* コミットする */
	EXEC SQL COMMIT WORK;
	EXEC SQL END;

	/* 結果チェック */
	if (sqlca.sqlcode != 0)
	{
		sprintf(tmp,"DELETE結果チェック:%d - %s",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
		popmsg((COLS/2)-24,(LINES/2)-4,tmp);
		return(0);
	}
	/* 切断 */
	sqlca.sqlcode = 0;
	EXEC SQL DISCONNECT dbConnection;
	EXEC SQL END;
	return(0);
}

//***********************************************************************
// NAME     : DeleteTBL2()	レコード削除(キー２個)
// SYNOPSIS : DeleteTBL2()
// RETURN   :	0	成功
//		-1	失敗
//***********************************************************************
int	DeleteTBL2(const char* key1,char* key2,int sqlcode)
{
	DBConnect();

	memset (sqlca.sqlstate, '0', 5);

		/* ホスト変数定義 */
  	EXEC SQL BEGIN DECLARE SECTION;
		char		schedule_name[16+1];	/* スケジュール名称 */
		char		schedule_day[8+1];	/* スケジュール日 */
	EXEC SQL END DECLARE SECTION;

	sqlcode = 0;

		/* スケジュール名（キー項目）設定 */
	memset((char *)schedule_name, '\0', sizeof(schedule_name));
	strncpy((char*)schedule_name,key1,sizeof(schedule_name));
	memset((char *)schedule_day, '\0', sizeof(schedule_day));
	strncpy((char*)schedule_day,key2,sizeof(schedule_day));

		/* 削除対象レコードをDELETE */
	EXEC SQL DELETE FROM SCHDYTBL
	WHERE	SCHEDULE_NAME =:schedule_name AND SCHEDULE_DAY =:schedule_day;
	EXEC SQL END;

		/* DELETE失敗 */
//	if ( sqlca.sqlcode < 0 || sqlca.sqlcode == 1403)
	if (memcmp (sqlca.sqlstate, "00", 2) != 0)
	{
  		/* ロールバック */
  		EXEC SQL ROLLBACK WORK;
		EXEC SQL END;
		sprintf(tmp,"データベースDELETEエラー:%d - %s",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
		popmsg((COLS/2)-24,(LINES/2)-4,tmp);
		return(-1);
	}

		/* コミットする */
	EXEC SQL COMMIT WORK;
	EXEC SQL END;

	/* 結果チェック */
	if (sqlca.sqlcode != 0)
	{
		sprintf(tmp,"DELETE結果チェック:%d - %s",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
		popmsg((COLS/2)-24,(LINES/2)-4,tmp);
		return(0);
	}
	/* 切断 */
	sqlca.sqlcode = 0;
	EXEC SQL DISCONNECT dbConnection;
	EXEC SQL END;
	return(0);
}

//***********************************************************************
// NAME     : DeleteTBL3()	レコード削除(キー３個)
// SYNOPSIS : DeleteTBL3()
// RETURN   :	0	成功
//		-1	失敗
//***********************************************************************
int	DeleteTBL3(const char* key1,char* key2,char *key3,int sqlcode)
{
	DBConnect();

	memset (sqlca.sqlstate, '0', 5);

		/* ホスト変数定義 */
  	EXEC SQL BEGIN DECLARE SECTION;
		char		schedule_name[16+1];	/* スケジュール名称 */
		char		schedule_day[8+1];	/* スケジュール日 */
		char		schedule_time[4+1];	/* スケジュール時刻 */
	EXEC SQL END DECLARE SECTION;

	sqlcode = 0;

		/* スケジュール名（キー項目）設定 */
	memset((char *)schedule_name, '\0', sizeof(schedule_name));
	strncpy((char*)schedule_name,key1,sizeof(schedule_name));
	memset((char *)schedule_day, '\0', sizeof(schedule_day));
	strncpy((char*)schedule_day,key2,sizeof(schedule_day));
	memset((char *)schedule_time, '\0', sizeof(schedule_time));
	strncpy((char*)schedule_time,key3,sizeof(schedule_time));

		/* 削除対象レコードをDELETE */
	EXEC SQL DELETE FROM SCHDYTBL
	WHERE	SCHEDULE_NAME =:schedule_name AND SCHEDULE_DAY =:schedule_day AND SCHEDULE_TIME =:schedule_time;
	EXEC SQL END;

		/* DELETE失敗 */
//	if ( sqlca.sqlcode < 0 || sqlca.sqlcode == 1403)
	if (memcmp (sqlca.sqlstate, "00", 2) != 0)
	{
  		/* ロールバック */
  		EXEC SQL ROLLBACK WORK;
		EXEC SQL END;
		sprintf(tmp,"データベースDELETEエラー:%d - %s",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
		popmsg((COLS/2)-24,(LINES/2)-4,tmp);
		return(-1);
	}

		/* コミットする */
	EXEC SQL COMMIT WORK;
	EXEC SQL END;

	/* 結果チェック */
	if (sqlca.sqlcode != 0)
	{
		sprintf(tmp,"DELETE結果チェック:%d - %s",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
		popmsg((COLS/2)-24,(LINES/2)-4,tmp);
		return(0);
	}
	/* 切断 */
	sqlca.sqlcode = 0;
	EXEC SQL DISCONNECT dbConnection;
	EXEC SQL END;
	return(0);
}

//***********************************************************************
// NAME     : DeleteTBLday()	レコード削除(キー１個 指定したスケジュール日付より以前を削除)
// SYNOPSIS : DeleteTBLday()
// RETURN   :	0	成功
//		-1	失敗
//***********************************************************************
int	DeleteTBLday(const char* key,int sqlcode)
{
	DBConnect();

	memset (sqlca.sqlstate, '0', 5);

		/* ホスト変数定義 */
  	EXEC SQL BEGIN DECLARE SECTION;
		char		schedule_day[16+1];	/* スケジュール名称 */
	EXEC SQL END DECLARE SECTION;

	sqlcode = 0;

		/* スケジュール名（キー項目）設定 */
	memset((char *)schedule_day, '\0', sizeof(schedule_day));
	strncpy((char*)schedule_day,key,sizeof(schedule_day));

		/* 削除対象レコードをDELETE */
	EXEC SQL DELETE FROM SCHDYTBL
	WHERE	SCHEDULE_DAY <= :schedule_day;
	EXEC SQL END;

		/* DELETE失敗 */
//	if ( sqlca.sqlcode < 0 || sqlca.sqlcode == 1403)
	if (memcmp (sqlca.sqlstate, "00", 2) != 0)
	{
  		/* ロールバック */
  		EXEC SQL ROLLBACK WORK;
		EXEC SQL END;
		sprintf(tmp,"データベースDELETEエラー:%d - %s",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
		popmsg((COLS/2)-24,(LINES/2)-4,tmp);
		return(-1);
	}

	/* コミットする */
	EXEC SQL COMMIT WORK;
	EXEC SQL END;

	/* 結果チェック */
	if (sqlca.sqlcode != 0)
	{
		sprintf(tmp,"DELETE結果チェック:%d - %s",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
		popmsg((COLS/2)-24,(LINES/2)-4,tmp);
		return(0);
	}
	/* 切断 */
	sqlca.sqlcode = 0;
	EXEC SQL DISCONNECT dbConnection;
	EXEC SQL END;
	return(0);
}

int schdytbl_disp(int no, int startline, int maxcol)
{
	int i, j;
	char s[MAX_TMP];

	if((FetchTBL(no)) == 0)
	{
		for(i=startline;i<DBcount;i++)
		{
			for(j=0;j<maxcol;j++)
			{
				sf_gputDB(no,i,j,startline,s);
			}
		}
		return(0);
	}
	else
	{
		return(-1);
	}
}

void inputwin_write(int no, int get, int line,int maxcol)
{
	int i;
	char s[MAX_TMP];

	sf_tbegin();
	for(i=0;i<maxcol;i++)
	{
		sprintf(s,"%s",ft[get].splitDBbuff[line][i]);
		sf_tput(no,i,s);
		sf_tnext();
	}
}

int subform(void)
{
	int i,j,k;
	int ret;
	char f[256];
	int xcol,rows;
	int maxtext;
	char s[MAX_STR];

	int xcol2;
	int maxcol;
	int startline;
	
	int line;
	char key1[MAX_STR];
	char key2[MAX_STR];
	char key3[MAX_STR];

	sprintf(f,"%s","_schdytbl.def");
	initscr();

	xcol = COLS;
	rows = LINES;

	cbreak();
	noecho();
	keypad(stdscr, TRUE);
	meta(stdscr, TRUE);

	if(stat(f,fileptr) != 0)
	{
		popmsg((COLS/2)-24,(LINES/2)-4,"メイングリッドフォーム定義ファイルがありあません。");
		echo();
		endwin();
		exit(0);
	}
	if(stat("_inputwin2.def",fileptr) != 0)
	{
		popmsg((COLS/2)-24,(LINES/2)-4,"入力用テキストボックスフォーム定義ファイルがありあません。");
		echo();
		endwin();
		exit(0);
	}
	if(stat("_header.def",fileptr) != 0)
	{
		popmsg((COLS/2)-24,(LINES/2)-4,"ヘッダータイトル用グリッドフォーム定義ファイルがありあません。");
		echo();
		endwin();
		exit(0);
	}
	if(stat("_footer.def",fileptr) != 0)
	{
		popmsg((COLS/2)-24,(LINES/2)-4,"ファンクションキー用グリッドフォーム定義ファイルがありあません。");
		echo();
		endwin();
		exit(0);
	}

	xcol = wsubform(3,140,16,2,27,"_inputwin2.def");
	maxcol = wsubform(0,140,44,1,2,f);
	maxtext = textbox(3,2,27,"_inputwin2.def");

	wrefresh(xt[0].form);

	for(i=0;i<MAX_POS;i++)
		memset(gridtitles[i],'\0',MAX_LEN);

	xcol = wsubform(2,xcol,rows,0,43,"_footer.def");
	sf_gcep(2,0,0,3,"入力画面へ");
	sf_gcep(2,12,0,3,"ESC終了");
	wrefresh(xt[2].form);

	for(i=0;i<MAX_POS;i++)
		memset(gridtitles[i],'\0',MAX_LEN);

	/*
	if((ret = MConnect()) == -1)
	{
		if(popmsg((COLS/2)-24,(LINES/2)-4,"DBの接続に失敗しました。終了します。") == 1)
		{
			echo();
			endwin();
			exit(1);
		}
	}
	*/

	xcol = wsubform(1,xcol,rows,0,0,"_header.def");
	sf_gcep(1,0,0,1,"v1.0.3");
	sprintf(ft[1].cp[0][0].s,"%s","APscheduler");
	mvwprintw(ft[1].st[0][0].vs,0,1,"%s",ft[1].cp[0][0].s);
	sf_wrefreshcell(1,0,0);
	sf_wrefreshform(1);

	sf_startcell(0);

	ret = Gret;

	while(1)
	{
		startline = sf_getstartline(0);	//DBgrid()の持っているスクロールに必要なＤＢグリッドの画面初期行の位置情報。
		if(schdytbl_disp(0,startline,maxcol) == -1)	//*splitDBbuff[][]をグリッドに書き込み表示する。
		{
			popmsg(12,12,"schtbl_disp():error");
		}
		ret = DBgrid(0,maxtext,xcol,0,DBcount,maxcol);	//データベース連結用グリッド。*splitDBbuff[][]を表示する。
		switch(ret)
		{
		case -1:
			echo();
			endwin();
			exit(0);
			break;

		//for grid
		case 200: //ESC　キーでプログラムを終了する。
			if(popmsg((COLS/2)-24,(LINES/2)-4,"Exit grid area in Subform?") == 1)
				goto end;
			ret = Pret;
			break;
		case 201: //F1
		//DBへの入力用ウインドウの作成
			line = sf_status(0,Grid,'D');
			inputwin_write(3,0,line,maxcol);
			sf_gcep(2,0,0,3,"戻る");
			sf_gcep(2,4,0,3,"更新");
			sf_gcep(2,5,0,3,"追加");
			sf_gcep(2,6,0,3,"削除 n+d+t");
			sf_gcep(2,7,0,3,"削除 n+d");
			sf_gcep(2,8,0,3,"削除 < d");
			while(1)
			{
				ret = formtext(3,maxtext, 140);
				switch(ret)
				{
				case -1:
					echo();
					endwin();
					exit(0);
					break;
				case 100:
					if(popmsg((COLS/2)-24,(LINES/2)-4,"Exit grid area in Subform?") == 1)
						goto end;
					break;
				case 101:
					goto mainwin;
					break;
				case 105:
					sf_tgetDBall(3);
					sprintf(key1,"%s",ft[0].splitDBbuff[line][0]);
					sprintf(key2,"%s",ft[0].splitDBbuff[line][1]);
					if(UpdateTBL(0,key1,key2,sqlcode,line) == -1)
					{
						popmsg((COLS/2)-24,(LINES/2)-4,"データベースが更新出来ません。");
					}
					goto mainwin;
					break;
				case 106:
					sf_tgetDBall(3);
					sprintf(key1,"%s",ft[0].splitDBbuff[line][0]);
					sprintf(key2,"%s",ft[0].splitDBbuff[line][1]);
					if(InsertTBL(0,key1,key2,sqlcode) == -1)
					{
						popmsg((COLS/2)-24,(LINES/2)-4,"データベースが追加出来ません。");
					}
					goto mainwin;
					break;
				case 107:
					if(popmsg((COLS/2)-24,(LINES/2)-4,"名前と日付と実行時間でデータを削除しますか？") == 1)
					{
					//	schdytbl_write(line);
						sprintf(key1,"%s",ft[0].splitDBbuff[line][0]);
						sprintf(key2,"%s",ft[0].splitDBbuff[line][1]);
						sprintf(key3,"%s",ft[0].splitDBbuff[line][2]);
					//	schdytbl_write(line);
						if(DeleteTBL3(key1,key2,key3,sqlcode) == -1)
						{
							popmsg((COLS/2)-24,(LINES/2)-4,"データベースから削除出来ません。");
						}
					}
					else
					{
						goto mainwin;
					}
					goto cleardisp;
					break;
				case 108:
					if(popmsg((COLS/2)-24,(LINES/2)-4,"名前と日付でデータを削除しますか？") == 1)
					{
						sprintf(key1,"%s",ft[0].splitDBbuff[line][0]);
						sprintf(key2,"%s",ft[0].splitDBbuff[line][1]);
						if(DeleteTBL2(key1,key2,sqlcode) == -1)
						{
							popmsg((COLS/2)-24,(LINES/2)-4,"データベースから削除出来ません。");
						}
					}
					else
					{
						goto mainwin;
					}
					goto cleardisp;
					break;
				case 109:
					sf_tget(3,1,s);
					sprintf(tmp,"%s の日付以前の全てのデータを削除しますか？",s);
					if(popmsg((COLS/2)-24,(LINES/2)-4,tmp) == 1)
					{
						sprintf(key1,"%s",ft[0].splitDBbuff[line][1]);
						if(DeleteTBLday(key1,sqlcode) == -1)
						{
							popmsg((COLS/2)-24,(LINES/2)-4,"データベースから削除出来ません。");
						}
					}
					else
					{
						goto mainwin;
					}
					goto cleardisp;
					break;
				}
			}
			cleardisp:
			sf_initdisp(0);
			mainwin:
			sf_gcep(2,0,0,3,"入力画面へ");
			sf_gcep(2,4,0,3,"          ");
			sf_gcep(2,5,0,3,"          ");
			sf_gcep(2,6,0,3,"          ");
			sf_gcep(2,7,0,3,"          ");
			sf_gcep(2,8,0,3,"          ");
			ret = Pret;
			break;
		case 202: //F2
			ret = Pret;
			break;
		case 203: //F3　現在のセルの位置を調べた後、セル内文字を読みとりセンター詰めで書き込む。
			i = sf_status(0,Grid,'X');
			j = sf_status(0,Grid,'Y');
			sf_ggetDB(0,i,j,0,tmp);
			sf_gcep(0,i,j,3,tmp);
			ret = Pret;
			break;
		case 204: //F4　現在のセルの位置を調べた後、数値"999999"を"999,999"で書き込む。
			i = sf_status(0,Grid,'c');
			j = sf_status(0,Grid,'Y');
			sf_gvarprint(0,i,j,"999999");
			ret = Pret;
			break;
		case 205: //F5
				i = sf_status(0,Grid,'D');
				sprintf(tmp,"i=%d splitbuff=%s",i,ft[0].splitDBbuff[i][0]);
				popmsg(25,25,tmp);
			ret = Pret;
			break;
		case 206: //F6　セル内文字を読みとりメッセージウインドウに表示する。
			i = sf_status(0,Grid,'X');
			j = sf_status(0,Grid,'Y');
			sf_ggetDB(0,i,j,0,tmp);
			popmsg((COLS/2)-24,(LINES/2)-4,tmp);
			ret = Pret;
			break;
		case 207: //F7　現在のセルの位置を調べた後、セルカーソルの移動場所を選択する。最後にNUMERIC型のセルに移動
			i = sf_status(0,Grid,'X');
			j = sf_status(0,Grid,'Y');
			sprintf(tmp,"i=%d/j=%d",i,j);
			if(popmsg((COLS/2)-24,(LINES/2)-4,tmp)== 1)
				sf_glocate(0,8,32);
			i = sf_status(0,Grid,'f');
			sprintf(tmp,"f=%d",i);
			popmsg((COLS/2)-24,(LINES/2)-4,tmp);
			if(sf_status(0,Grid,'f') == 4)
			{
				sf_glocate(0,8,1);
			}
			ret = Pret;
			break;
		case 208: //F8　セルの属性をメッセージウインドウに表示。
			/*
			j = sf_status(0,Grid,'D');
			sprintf(tmp,"dbindex=%d",j);
			*/
			sprintf(tmp,"w=%d,x=%d,y=%d,X=%d,n=%d,l=%d,c=%d,a=%d,A=%d,f=%d,s=%d,D=%d",
					sf_status(0,Grid,'w'),sf_status(0,Grid,'x'),sf_status(0,Grid,'y'),sf_status(0,Grid,'X'),
					sf_status(0,Grid,'n'),sf_status(0,Grid,'l'),sf_status(0,Grid,'c'),sf_status(0,Grid,'a'),
					sf_status(0,Grid,'a'),sf_status(0,Grid,'f'),sf_status(0,Grid,'s'),sf_status(0,Grid,'D'));
			popmsg((COLS/2)-24,(LINES/2)-4,tmp);
			ret = Pret;
			break;
		case 209: //F9　カンマ付き１１桁数値を全てのセルに書き込む。
			for(i=0,k=1;i<ft[0].lcol;i++)
			{
				for(j=DBcount;j<(ft[0].ey-ft[0].sy)+1;j++)
				{
					sprintf(s,"%ld",33335 * 60000);
					sf_gvarprint(0,i,j,s);
				}
			}
			ret = Pret;
			break;
		case 210: //F10　全てのセルに番号を書き込む。
			for(i=0;i<ft[0].lcol;i++)
			{
				for(j=DBcount,k=1;j<(ft[0].ey-ft[0].sy)+1;j++)
				{
					sprintf(s,"%d",k);
					sf_gput(0,i,j,s);
					k++;
				}
			}
			ret = Pret;
			break;
		case 211: //F11　セルに番号を書き込む。
			for(i=0;i<ft[0].lcol;i++)
			{
				for(j=DBcount,k=1;j<(ft[0].ey-ft[0].sy)+1;j++)
				{
					sprintf(s,"%d",k);
					sf_gput(0,i,j,s);
					k++;
				}
			}
			ret = Pret;
			break;

		default:
			break;
		}
		sf_freeDB(0,DBcount,maxcol);
	}

end:
	echo();
	endwin();
}

int main(void)
{
	subform();
}

