implementation module pdExtFile;

//1.3
from StdArray import size,size_u;
from StdInt import >>, %, +, -, toChar;
from StdString import String;
//3.1

import code from library "StdDynamic_kernel32_library";
/*2.0
import StdEnv;
/*
from StdArray import class size;
from StdClass import class Eq, <>, class ==;
from StdInt import class ==;
from StdString import class %;
*/
0.2*/
from StdBool import &&,not;
//1.3
from StdClass import inc, one, Eq;
//3.1
/*2.0
//from StdClass import class IncDec,class  Eq;
0.2*/
import StdArray;
import StdFile;
from StdMisc import abort;

from ExtString import CharIndexBackwards, CharIndex;
import code from "filesize.obj";
import code from "fileutilities.obj";
import code from library "fileutilities_library";
import code from library "kernel32_library";
import Directory;

path_separator :== '\\';

/*
c\File uitities

compile fileutilities with cl /c fileutilities.c

*/

/*
ExtractPathAndFile :: !String -> (!String,!String);
ExtractPathAndFile path_and_file 
	#! (dir_delimiter_found,i)
		= CharIndexBackwards path_and_file (size path_and_file - 1) '\\';
	| dir_delimiter_found
		= (path_and_file % (0,i-1),path_and_file % (i+1,size path_and_file - 1));
		= ("",path_and_file);

ExtractPathFileAndExtension :: !String -> (!String,!String);
ExtractPathFileAndExtension path_and_file 
	| dot_found && not path_separator_after_dot_found
		#! extension
			= path_and_file % (inc dot_index,size path_and_file-1);
		#! pathfile
			= path_and_file % (0, dot_index-1);
		= (pathfile,extension);
		
		= (path_and_file,"");
		//abort (path_and_file % (inc dot_index,size path_and_file-1)) 
		//abort (path_and_file % (0, dot_index-1));
where
{
	(dot_found,dot_index)
		= CharIndexBackwards path_and_file (size path_and_file - 1) '.';
	(path_separator_after_dot_found,path_sep_index)
		= CharIndex path_and_file (inc dot_index) '\\';
}
*/
	
FileSize :: !String -> (!Bool,!Int);
FileSize _ =
	code {
		ccall FileSize "S-II"
	};

(FWW) infixl;
(FWW) f w :== fwritec (toChar (w>>8)) (fwritec (toChar w) f);

(FWB) infixl;
(FWB) f b :== fwritec (toChar b) f;

FetchFileTime :: !String -> (!Bool,!Int,!Int);
FetchFileTime _ 
	= code {
		ccall FetchFileTime "S-III"
	};
	
CompareFileTimes :: !Int !Int !Int !Int -> !Int;
CompareFileTimes _ _ _ _
	= code {
		ccall CompareFileTimes "IIII-I"
	};
	
/*
FileExists :: !String -> !Bool;
FileExists _ 
	= code {
		ccall FileExists "S-I"
	};
*/

GetShortPathName :: !String -> (!Bool,!String);
GetShortPathName long_path
	#! s_short_path
		= GetShortPathName_ long_path "\0" 0;
	#! short_path
		= createArray s_short_path '\0';
	#! result
		= GetShortPathName_ long_path short_path s_short_path;
	= (not (result == 0),short_path);
where {
	GetShortPathName_ :: !String !String !Int -> !Int;
	GetShortPathName_ long_path short_path s_short_path
		= code {
			ccall GetShortPathNameA@12 "PssI:I"
		}
}

file_exists :: !String !*f -> !(!Bool,!*f) | FileEnv f;
file_exists file_name io
	#! ((ok,file),io)
		= accFiles (pd_StringToPath file_name) io;
	# ((file_error,_),io)
		= accFiles (getFileInfo file) io;
	= (file_error <> DoesntExist,io);
	
FileExists :: !String !*env -> (!Bool,!*env) | FileSystem env;
FileExists pd_path env
	#! ((ok,path), env)
		= pd_StringToPath pd_path env; 
	| not ok
		= abort "pdExtFile (FileExists): could not convert path to platform independent representation";
		
	#! ((dir_error, _), env)
		= getFileInfo path env;
	= (not (dir_error == DoesntExist),env);
	
GetFullPathName :: !String -> (!Bool,!String);
GetFullPathName lpFileName
	#! buffer_s = (GetFullPathName_ lpFileName 0 "\0" 0);
	#! buffer = createArray buffer_s '*';
	#! result = GetFullPathName_ lpFileName buffer_s buffer 0;
	= (result <> 0,buffer % (0,result - 4));
where {
	GetFullPathName_ :: !String !Int !String !Int -> !Int;
	GetFullPathName_ lpFileName nBufferLength buffer _
		= code {
			ccall GetFullPathNameA@16 "PsIsI:I"
		}
}



