// Pocket Post Pet用 stdio.h

#include <windows.h>
#include "ppp_stdio.h"

#define MAX_OPEN_FILE 16

static int first_init = 1;
void log( char * str , ... );

typedef struct _FILE_HANDLE {
	int    use;
	HANDLE fp;
	int    eof;
	int    error;
} FILE_HANDLE;
	
FILE_HANDLE	FH[MAX_OPEN_FILE];

void log( char * defaultMsg,...)
{
}

void DEBUGLOG( char * str , ... )
{
}

void LOG( char * str , ... )
{
	HANDLE fp;
	int ret;
	DWORD rcount;
	va_list marker;
	char buf[1024];
	TCHAR fname[1024];
	TCHAR * bufptr;

	GetModuleFileName(GetModuleHandle(NULL),fname,1023);
    if ((bufptr=_tcsrchr(fname,_T('\\'))) != NULL ) *bufptr = NULL;
	_tcscat( fname, _T("\\VBAdvenceCE.log") );
	fp = CreateFile(
				fname , 
				GENERIC_WRITE,
				0,					// no shared
				NULL,				// set NULL
				OPEN_ALWAYS,
				FILE_ATTRIBUTE_NORMAL |	FILE_FLAG_RANDOM_ACCESS,
				0 );

	SetFilePointer(fp, 0,NULL,FILE_END );

	va_start( marker, str );     /* 可変個の引数の初期化 */
	vsprintf( buf,str,marker );
	va_end( marker );

	ret = WriteFile( fp, buf, strlen(buf), &rcount, NULL ); 

	CloseHandle( fp );
}

FILE * ppp_fopen(const char * name, const char * type)
{
	int i;
	int dwDesiredAccess;
	int dwCreationDispostion;
	wchar_t	wname[512];

//	DEBUGLOG("ppp_fopen start name[%s]\n",name);

	if( first_init ){
		first_init = 0;
		memset( FH, '\0', sizeof(FILE_HANDLE) * MAX_OPEN_FILE );
	}

//  DEBUGLOG("ppp_fopen type[%c%c] \n",type[0],type[1]);
	if (type[0]=='w' ) { 
		dwDesiredAccess = GENERIC_WRITE;	
		dwCreationDispostion = OPEN_ALWAYS;		
	}else if( type[0]=='r' ){
		if( type[1]=='+' ){
			dwDesiredAccess = GENERIC_READ + GENERIC_WRITE;
		}else{
			dwDesiredAccess = GENERIC_READ;
		}
		dwCreationDispostion = OPEN_EXISTING;
	}else if (type[0]=='a' ) { 
		dwDesiredAccess = GENERIC_WRITE;
		dwCreationDispostion = OPEN_ALWAYS;
	}else{
		return NULL;
	}

	for( i =1;i<MAX_OPEN_FILE;i++ ){
		if( !FH[i].use ) break;
	}
//	DEBUGLOG("ppp_fopen FH[%d] \n", i);

	mbstowcs( wname, name, 512 );

	FH[i].fp = CreateFile( wname, 
				dwDesiredAccess,
				0,					// no shared
				NULL,				// set NULL
				dwCreationDispostion,
				FILE_ATTRIBUTE_NORMAL |	FILE_FLAG_RANDOM_ACCESS,
				0 );
//	DEBUGLOG("ppp_fopen CreateFile[%d]\n", FH[i].fp);
	if( FH[i].fp > 0 ){
		FH[i].use=1;
		FH[i].eof=0;
		FH[i].error=0;
	}else{
//		DEBUGLOG("ppp_fopen error end\n");
		return (FILE *)NULL;
	}

	if( type[0]=='a' ) {
		ppp_fseek( (FILE *)i, 0, SEEK_END );
	}

//	DEBUGLOG("ppp_fopen end\n");
	return (FILE *) i;
}

int cdecl ppp_fclose(FILE * fp)
{
//	DEBUGLOG("ppp_fclose start FH[%d]\n", (int)fp );
	CloseHandle( FH[(int)fp].fp );
	FH[(int)fp].use = 0;
	FH[(int)fp].eof = 0;
	FH[(int)fp].error = 0;
//	DEBUGLOG("ppp_fclose end \n");
	return 0;
}

size_t ppp_fread(void *buffer, size_t size, size_t count, FILE * fp )
{
	BOOL ret;
	DWORD rcount;
//	DEBUGLOG("ppp_fread start FH[%d]\n", (int)fp );

	ret = ReadFile( FH[(int)fp].fp , buffer, size * count, &rcount, NULL );
	if( ret ){
//		DEBUGLOG("ppp_fread normal end ret[%d]\n", (size_t)rcount/size );
		return (size_t)rcount/size;
	}else{
//		DEBUGLOG("ppp_fread error? end ret[0]\n" );
		return 0;
	}
}

size_t ppp_fwrite( const void *buffer, size_t size, size_t count, FILE *fp )
{
	BOOL ret;
	DWORD rcount;

//	DEBUGLOG("ppp_fwrite start ret[%d]\n", (int)fp );

	ret = WriteFile( FH[(int)fp].fp, buffer, size * count, &rcount, NULL ); 
	if( ret ){
//		DEBUGLOG("ppp_fwrite normal end ret[%d]\n", (size_t)rcount/size );
		return (size_t)rcount/size;
	}else{
//		DEBUGLOG("ppp_fwrite error? end ret[0]\n");
		return 0;
	}
}

int ppp_fseek( FILE *stream, long offset, int origin )
{
	DWORD ret;
	DWORD mmethod; 

//	DEBUGLOG("ppp_fseek start FH[%d]\n", (int)stream );
	
	switch( origin ){
		case SEEK_SET : mmethod = FILE_BEGIN;	break;
		case SEEK_CUR : mmethod = FILE_CURRENT;	break;
		case SEEK_END : mmethod = FILE_END;		break;
	}

	ret = SetFilePointer( FH[(int)stream].fp, offset, NULL, mmethod );

	if( ret != 0xFFFFFFFF ){	
//		DEBUGLOG("ppp_fseek normal end ret[0]\n" );
		FH[(int)stream].eof = 0;
		FH[(int)stream].error = 0;
		return 0;
	}else{
//		DEBUGLOG("ppp_fseek error end ret[1]\n" );
		return 1;
	}
}

int ppp_rewind( FILE *stream )
{
	return ppp_fseek( stream, 0, FILE_BEGIN );
}

int ppp_fscanf(FILE * fp, const char * first , ...)
{
	DEBUGLOG( "fscanf function is not impliment.\n" );
	return 0;
}

int ppp_fprintf(FILE * fp, const char * first, ...)
{
	va_list marker;
	char buf[1024];
    int num;
//	DEBUGLOG("ppp_fprintf start FH[%d]\n",(int)fp );

	va_start( marker, first );     /* 可変個の引数の初期化 */
	num = vsprintf( buf,first,marker );
	va_end( marker );

	ppp_fwrite( buf, 1, num,fp );
//	DEBUGLOG("ppp_fprintf end\n" );
	return 0;
}

int ppp_fgetc( FILE * fp )
{
	DWORD ret;
	DWORD rcount;
	char buffer;

//	DEBUGLOG("ppp_fgetc start FH[%d]\n",(int)fp );
	
	ret = ReadFile( FH[(int)fp].fp , &buffer, 1, &rcount, NULL );
	if( ret ){
		if(rcount > 0){
//			DEBUGLOG("ppp_fgetc end ret[%d]\n", (int)buffer );
			return (int)buffer;
		} else {
//			DEBUGLOG("ppp_fgetc end ret[EOF]\n" );
		}
	}else{
//		DEBUGLOG("ppp_fgetc error end\n" );
		FH[(int)fp].error = 1;
	}
	FH[(int)fp].eof = 1;
	return EOF;
}

char * ppp_fgets( char * str , int n, FILE * fp )
{
	DWORD ret;
	int i;
	DWORD rcount;

//	DEBUGLOG("ppp_fgets start FH[%d]\n",(int)fp );

	str[0] = '\0';
	for(i=0;i<n-1;i++){
		ret = ReadFile( FH[(int)fp].fp , &str[i], 1, &rcount, NULL );
		if( ret ){
			if(rcount<1){
				str[i]='\0';
				FH[(int)fp].eof = 1;
				break;
			}
			if(str[i]=='\n'){
				str[i+1] = '\0';
				break;
			}
		}else{
			str[0]='\0';
			FH[(int)fp].eof = 1;
			FH[(int)fp].error = 1;
			break;
		}
	}
	if( i == n-1 ) str[i] = '\0';

//	DEBUGLOG("ppp_fgets end ret[%s]\n",str );
	if( str[0] == '\0' ) return NULL;
					else return str;
}

int ppp_fputc(int c,  FILE * fp )
{
	int ret;
	DWORD rcount;
	unsigned char buf = (unsigned char)c;
	ret = WriteFile( FH[(int)fp].fp , &buf, 1, &rcount, NULL );
	if( ret ){
		if( rcount ){
			return c;
		}
	}
	return EOF;
}

int ppp_ftell( FILE * fp )
{
	return SetFilePointer(FH[(int)fp].fp, 0,NULL,FILE_CURRENT );
}

int ppp_feof( FILE * fp )
{
	return FH[(int)fp].eof;
}

int ppp_ferror( FILE * fp )
{
	return FH[(int)fp].error;
}

int ppp_GetFileSize( FILE * fp )
{
	DWORD len;
		
	len = GetFileSize( FH[(int)fp].fp, NULL );
	return len;
}


void * ppp_calloc( size_t num, size_t siz)
{
	void * ret;
	ret = malloc( num*siz );
    if(!ret)return NULL;
	memset( ret,0,num*siz );
	return ret;
}

char * ppp_strrchr(const char * buf, int chr)
{
	size_t cnt;
	char *p;

	if( (cnt = strlen(buf)) ==(size_t)0 ) return NULL;
	p =(char*)buf + cnt;
	while(p>=buf){
		if(*p == chr) return p;
		p--;
	}
    return NULL;
}

int ppp_islower(int a )
{
	if( (a>='a')&&(a<='z') ) return 1;
	return 0;
}

int ppp_isupper(int a )
{
	if( (a>='A')&&(a<='Z') ) return 1;
	return 0;
}

int ppp_isdigit(int a )
{
	if( (a>='0')&&(a<='9') ) return 1;
	return 0;
}

int ppp_isalpha(int a )
{
  if( ppp_islower(a) ) return 1;
  if( ppp_isupper(a) ) return 1;
  return 0;
}

int ppp_isgraph(int a)
{
  if( ppp_isdigit(a) ) return 1;
  if( ppp_isalpha(a) ) return 1;
  return 0;
}

int ppp_atoi(const char *s)
{
	int a = 0;
  int sign = 0;

  while(*s == ' ') s++;

  if (*s == '0')
	{
		s++;
		if (*s == 'x' || *s == 'X')
		{
			s++;
			while (*s)
			{
				if (isdigit(*s))
					a = (a<<4) + *s - '0';
				else if (strchr("ABCDEF", *s))
					a = (a<<4) + *s - 'A' + 10;
				else if (strchr("abcdef", *s))
					a = (a<<4) + *s - 'a' + 10;
				else return a;
				s++;
			}
			return a;
		}
		while (*s)
		{
			if (strchr("01234567", *s))
				a = (a<<3) + *s - '0';
			else return a;
			s++;
		}
		return a;
	}
	if (*s == '-') sign = 1;
	while (*s)
	{
		if (isdigit(*s))
			a = (a*10) + *s - '0';
		else break;
		s++;
	}
	if(sign) return -a;
	    else return  a;
}

int ppp_stricmp( char * a, char * b )
{
    char * aa;
    char * bb;
    char * i;
    int ret;

    aa = (char*)malloc(strlen(a)+1);
    bb = (char*)malloc(strlen(b)+1);
    strcpy(aa,a);
    strcpy(bb,b);

    for(i=aa;*i!='\0';i++)
        if(ppp_isupper(*i)) *i+=0x20;

    for(i=bb;*i!='\0';i++)
        if(ppp_isupper(*i)) *i+=0x20;

    ret = strcmp(aa,bb);

    free(aa);
    free(bb);

    return ret;
}