/**********************************************************************
 
	Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
	This program is free software; you can redistribute it 
	and/or modify it under the terms of the GLOBALBASE 
	Library General Public License (G-LGPL) as published by 

	http://www.globalbase.org/
 
	This program is distributed in the hope that it will be 
	useful, but WITHOUT ANY WARRANTY; without even the 
	implied warranty of MERCHANTABILITY or FITNESS FOR A 
	PARTICULAR PURPOSE.

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

#include "kibandata_util.h"
#include "string.h"
#include "kibandata.h"

FILE *g_fpLog;

void strtoupper(char *str)
{
	for(;*str;++str){
		*str = toupper(*str);
	}
}

/* 改行文字を取り除く */
void chop(char *sz){
	int nLen;
	char *p;
	if(!sz)
		return;
	nLen = strlen(sz);
	if(nLen == 0)
		return;
	p = &sz[nLen-1];
	while(*p == '\r' || *p == '\n'){
		*p = '\0';
		--p;
		if(--nLen<1)
			break;
	}
}

void ExtractFileName(const char *szPath, char *szFileName)
{
	int LastDviderExists = 0;
	const char *p;
	int nLen;
	if(!szPath) return ;
	p = &szPath[strlen(szPath)-1];
	if(*p == PATH_DEVIDER) {
		--p;
		LastDviderExists = 1;
	}
	while(*p != PATH_DEVIDER){
		--p;
		if(szPath == p)
			break;
	}
	++p;
	nLen = strlen(p)-LastDviderExists;
	strncpy(szFileName, p, nLen);
	szFileName[nLen] = '\0';
}

void ExtractFilePath(const char *szFullPath, char *szPathName)
{
	const char *p;
	int nLen;
	if(!szFullPath) return ;
	p = &szFullPath[strlen(szFullPath)-1];
	/* 一番末尾のPATH_DEVIDERは無視する */
	if(*p == PATH_DEVIDER)
		--p;
	while(*p != PATH_DEVIDER){
		--p;
		if(szFullPath == p)
			break;
	}
	nLen = strlen(szFullPath) - strlen(p) +1;
	strncpy(szPathName, szFullPath, nLen);
	szPathName[nLen] = '\0';
}

void SetPathDevider(char *szPath){
	int  l = strlen(szPath);
	if(szPath[l-1] != '/' && szPath[l-1] != '\\'){
		szPath[l] = PATH_DEVIDER;
		szPath[l+1] = '\0';
	}
}


V_LIST *vl_Front(V_LIST *l){
	for(;l->pPrev;l = l->pPrev);
	return l;
}

V_LIST *vl_Back(V_LIST *l){
	for(;l->pNext;l = l->pNext);
	return l;
}

V_LIST *vl_PushBack(V_LIST *l,void *d){
	if(!l){
		l = (V_LIST *)calloc(sizeof(V_LIST),1);
		l->Data = d;
		return l;
	}
	l = vl_Back(l);
	l->pNext = (V_LIST *)calloc(sizeof(V_LIST),1);
	l->pNext->pPrev = l;
	l->pNext->Data = d;
	return l->pNext;
}

V_LIST *vl_PushFront(V_LIST *l,void *d){
	if(!l){
		l = (V_LIST *)calloc(sizeof(V_LIST),1);
		l->Data = d;
		return l;
	}
	l = vl_Front(l);
	l->pPrev = (V_LIST *)calloc(sizeof(V_LIST),1);
	l->pPrev->pNext= l;
	l->pPrev->Data = d;
	return l->pPrev;	
}

void vl_Free(V_LIST *l, int Flags){
	V_LIST *pNext;
	l = vl_Front(l);
	for(; l; l=pNext ){
		pNext = l->pNext;
		if(Flags & VL_FREEDATA)
			free(l->Data);
		free(l);
	}
}

void *vc_Find(VC_TREE *p, char *Key)
{
	while(p){
		int cmp = strcmp(p->Key,Key);
		if(cmp==0){
			return p->Value;
		}
		else if(cmp > 0){
			p = p->pLeft;
		}
		else{
			p = p->pRight;
		}
	}
	return NULL;
}


VC_TREE *vc_Add(VC_TREE **pp, char *Key, void *Value, int Flags)
{
	VC_TREE *p = *pp;
	while(p){
		int cmp = strcmp(p->Key,Key);
		if(cmp==0){
			p->Value = Value;
			return p;
		}
		else if(cmp > 0){
			if(!p->pLeft){
				pp = &(p->pLeft);
				break;
			}
			p = p->pLeft;
		}
		else{
			if(!p->pRight){
				pp = &(p->pRight);
				break;
			}
			p = p->pRight;
		}
	}
	
	*pp=(VC_TREE*)calloc(sizeof(VC_TREE),1);
	if(Flags & VCA_COPYKEY){
		(*pp)->Key = (char *)malloc(strlen(Key)+1);
		strcpy((*pp)->Key,Key);
	}
	else
		(*pp)->Key = Key;
	(*pp)->Value = Value;
	return *pp;
}

void vc_Free(VC_TREE *p, int Flags){
	if(p){
		vc_Free(p->pLeft, Flags);
		vc_Free(p->pRight, Flags);	
		if(Flags & VCF_FREEKEY)
			free(p->Key);
		if(Flags & VCF_FREEVALUE)
			free(p->Value);
		free(p);
	}
}

void *vch_Find(VC_HASH_TABLE *p, char *Key){
	VC_TREE *pTree = p->Table[vch_GetKey(Key)];
	return vc_Find(pTree, Key);
}
void vch_Add(VC_HASH_TABLE *p, char *Key, void *Value, int Flags){
	VC_TREE **ppTree = &(p->Table[vch_GetKey(Key)]);
	vc_Add(ppTree, Key, Value, Flags);
}
void vch_Free(VC_HASH_TABLE *p, int Flags){
	int i;
	for(i=0; i<VCH_HASH_MAX; ++i){
		vc_Free(p->Table[i], Flags);
	}
}
int vch_GetKey(char *sz){
	int nReturn=0;
	for(;*sz;++sz){
		nReturn += (int)*sz;
	}
	return nReturn%VCH_HASH_MAX;
}

void *v_Find(V_TREE *p, int nKey)
{
	while(p){
		if(p->nKey==nKey){
			return p->Value;
		}
		else if(p->nKey > nKey){
			p = p->pLeft;
		}
		else{
			p = p->pRight;
		}
	}
	return NULL;
}


V_TREE *v_Add(V_TREE *p, int nKey, void *Value)
{
	V_TREE **pp = &p;
	while(p){
		if(p->nKey==nKey){
			p->Value = Value;
			return p;
		}
		else if(p->nKey > nKey){
			if(!p->pLeft){
				pp = &(p->pLeft);
				break;
			}
			p = p->pLeft;
		}
		else{
			if(!p->pRight){
				pp = &(p->pRight);
				break;
			}
			p = p->pRight;
		}
	}

	*pp=(V_TREE*)calloc(sizeof(V_TREE),1);
	(*pp)->nKey = nKey;
	(*pp)->Value = Value;
	return *pp;
}

void v_Free(V_TREE *p)
{
	if(p){
		v_Free(p->pLeft);
		v_Free(p->pRight);	
		free(p);
	}
}


int pt_Find(PAIR_TREE *p, int nKey)
{
	while(p){
		if(p->nKey==nKey){
			return p->nValue;
		}
		else if(p->nKey > nKey){
			p = p->pLeft;
		}
		else{
			p = p->pRight;
		}
	}
	return -1;
}


PAIR_TREE *pt_Add(PAIR_TREE *p, int nKey,int nValue)
{
	PAIR_TREE **pp = &p;
	while(p){
		if(p->nKey==nKey){
			p->nValue = nValue;
			return p;
		}
		else if(p->nKey > nKey){
			if(!p->pLeft){
				pp = &(p->pLeft);
				break;
			}
			p = p->pLeft;
		}
		else{
			if(!p->pRight){
				pp = &(p->pRight);
				break;
			}
			p = p->pRight;
		}
	}

	*pp=(PAIR_TREE*)calloc(sizeof(PAIR_TREE),1);
	(*pp)->nKey = nKey;
	(*pp)->nValue = nValue;
	return *pp;
}

void pt_Free(PAIR_TREE *p)
{
	if(p){
		pt_Free(p->pLeft);
		pt_Free(p->pRight);	
		free(p);
	}
}


#ifdef WIN32
#include <windows.h>
void EnumDirNames(const char *szFilePath, int (*EnumDirNameProc)(char *,long), long lParam){
	WIN32_FIND_DATA ffd;
	char szFind[MAX_PATH];
	HANDLE hFind;
	sprintf(szFind, "%s*.*", szFilePath);
	hFind = FindFirstFile(szFind, &ffd);
	if(hFind == INVALID_HANDLE_VALUE){
		return;
	}
	while(1){
		if(strcmp(ffd.cFileName, ".") != 0 &&
			strcmp(ffd.cFileName, "..") != 0 &&
			(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
			){
			int i=0;
			char szFileName[64];
			memset(szFileName, '\0', sizeof(szFileName));
			/* while(szFileName[i++] = tolower(ffd.cFileName[i])); */
			strcpy(szFileName, ffd.cFileName);
			EnumDirNameProc(szFileName, lParam);
		}
		if(!FindNextFile(hFind, &ffd)){
			FindClose(hFind);
			hFind = NULL;
			break;
		}
	}
}

void MakeDirectory(const char *szPath){
	CreateDirectory(szPath, NULL);
}

#else

#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include "machine/include.h"
#include <string.h>
#include <stdio.h>

void EnumDirNames(const char *szFilePath, int (*EnumDirNameProc)(char *,long), long lParam)
{
	DIR *dp;
	struct dirent *entry;
	struct stat statbuf;
	char szOldPath[MAX_PATH+1];
	dp = opendir(szFilePath);
	if(!dp)
		return;
	getcwd(szOldPath,MAX_PATH);
	chdir(szFilePath);
	while(entry=readdir(dp)){
		stat(entry->d_name, &statbuf);
		if(S_ISDIR(statbuf.st_mode)){
			if(strcmp(".",entry->d_name) == 0 ||
				strcmp("..",entry->d_name) == 0)
				continue;
			EnumDirNameProc(entry->d_name,lParam);
		}
	}
	closedir(dp);
	chdir(szOldPath);
}
void MakeDirectory(const char *szPath){
	mkdir(szPath,511);
}
#endif

void
er_panic(char * str)
{
	fprintf(stderr,"%s",str);
	printf("%i",*(int*)1);
	exit(1);
}
