#include <stream.h>
#include <ctype.h>
#include <string.h>
#include "dosname.h"
#include "mkstr.h"

// convert directory name to legal dos name
// 1. convert to lower case
// 2. truncate to 8 characters
// convert all characters except except `!', `%', -', `@', `{' and `}'

char * ToDosName(const char * UnixName, int CppNameFlag)
{
	// 1. remove directory part of name, out it back when done
	const char * orig_name = UnixName ;
	char * to_delete = OpdRemoveDirectory(UnixName);
	UnixName = to_delete ;

	// LogOut << "ToDosName(" << UnixName << ", " << CppNameFlag << ")\n" ;
	const MaxDosPrefix = 8 ;
	const MaxDosSuffix = 3 ;
	const char * UnixDosChar = "!%-@{}" ;
	const MaxDosName = MaxDosPrefix + 1 + MaxDosSuffix ;
	char NameBuf[MaxDosName+1];
	for (const char * FirstDot = UnixName; *FirstDot && *FirstDot != '.';
		FirstDot++);
/*
 *	LogOut << "*FirstDot = `" << *FirstDot << "', FirstDot = " <<
 *		(void *) FirstDot << ", UnixName = " << (void *) UnixName <<
 *		", df = " << (FirstDot - UnixName) << "\n" ;
 */
	strncpy(NameBuf,UnixName,MaxDosName);
	if (*FirstDot) {
		int Length = FirstDot - UnixName  ;
		if (Length > MaxDosPrefix) Length = MaxDosPrefix ;
		strncpy(NameBuf+Length,FirstDot,MaxDosSuffix+1);
		NameBuf[Length + MaxDosSuffix + 1] = '\0' ;
	} else NameBuf[MaxDosPrefix] = '\0' ;
	// LogOut << "ToDosName before char trans `" << NameBuf << "'\n" ;
	const char * ReadDot = 0 ;
	for (char * Ptr = NameBuf ; *Ptr; Ptr++) {
		char P = *Ptr ;
		if (!isascii(P)) {
			*Ptr = '@' ;
			continue ;
		}
		if (isalnum(P)) {
			if (CppNameFlag) if (ReadDot == Ptr - 1)
				if (P == 'C') continue ;
			*Ptr = tolower(P);
			continue ;
		}
		if (P == '_') continue ;
		if (P == '.') if (!ReadDot) {
			ReadDot = Ptr ;
			continue ;
		}
		for (const char * Legal = UnixDosChar; *Legal ; Legal++)
			if (P == *Legal) break ;
		if (*Legal) continue ; 
		*Ptr = '@' ;
	}
	// LogOut << "ToDosName returning `" << NameBuf << "'\n" ;
	char * dir = FindDirectory(orig_name);
	delete to_delete ;
	if (dir) {
		char * Return = Concatenate(dir,"/",NameBuf);
		delete dir ;
		return Return ;
	}
	return Concatenate(NameBuf);
}

char * ToCppName(const char * String)
{
	if (!String) return 0 ;
	if (!*String) return 0 ;
	char * Return = Concatenate(String);
	if (!isalpha(*Return)) *Return = '_' ;
	for (char * Ptr = Return; *Ptr ; Ptr++)
		if (!isascii(*Ptr)) *Ptr = '_' ;
		else if (isalnum(*Ptr)) continue ;
		else *Ptr = '_' ;
	return Return ;
}

char * TruncateToLength(char * Name, int Length)
{
	int Len = strlen(Name);
	for (int i = Len ; i > Length; i--) Name[i-1] = '\0' ;
	return Name ;
}

char * TruncateToDosPrefix(char * Name,int SaveLast)
{
	char * Save = 0 ;
	int Length = strlen(Name);
	if (SaveLast > Length) SaveLast = Length ;
	char * SavePos = Name + Length - SaveLast ;
	if (SaveLast) Save = Concatenate(SavePos);
	cerr << "Save = `" << Save << "'\n" ;
	if (SaveLast > MaxDosPrefix) SaveLast = MaxDosPrefix ;
	cerr << "Name `" << Name << "', SaveLast = " << SaveLast << "\n" ;
	TruncateToLength(Name,MaxDosPrefix - SaveLast) ;
	cerr << "Name `" << Name << "', MaxDosPrefix = " << MaxDosPrefix <<"\n";
	if (Save) strcpy(SavePos,Save);
	delete Save ;
	cerr << "Returning `" << Name << "'\n" ;
	return Name ;
}


