implementation module EdMyIO;

/* OS dependent module */
/* Primitives which 'should be' in the standard CLEAN IO lib */

import StdEnv;
import deltaEventIO, deltaFileSelect, deltaSystem, intrface;
import expand_8_3_names_in_path;

NoDate	:== {exists=False,yy=0,mm=0,dd=0,h=0,m=0,s=0};

::	DATE = {	exists	:: !Bool,
				yy		:: !Int,
				mm		:: !Int,
				dd		:: !Int,
				h		:: !Int,
				m		:: !Int,
				s		:: !Int };

/*	Opens a directory which can subsequently be read by 'FGetPlainFileName'.
	The boolean indicates whether the directory was successfully opened.
*/				
FOpenDir :: !String !Files -> (!Bool, !Files);
FOpenDir name files = (False, files);


/*	Closes a directory which has been previously opened by 'FOpenDir'.
	The boolean indicates whether the directory was successfully closed.
*/				
FCloseDir :: !Files -> !(Bool, !Files);
FCloseDir files = (False, files);

/*	Returns the next file name in the directory wich is currently open.
	The boolean indicates whether there are still file names.
*/
FGetPlainFileName :: !Files -> (!Bool, !String, !Files);
FGetPlainFileName files = (False, "", files);

/*	Returns True if the file name exists.
*/

FExists	:: !String !Files -> (!Bool, !Files);
FExists name files =  (WinFileExists name, files);


/*	Removes the indicated file.
	The boolean indicates successfull removal.
*/
FRemove	:: !String !Files -> (!Bool, !Files);
FRemove name files = (True, files);

/*	Returns the last modification date of the indicated file.
*/
FModified :: !String !Files -> (!DATE, !Files);
FModified name files =  ( daterec, files);
where
{  (exist, year, month, day, hour, minute, second) 
      =  WinFileModifiedDate name;
	daterec 
	  =  { exists=exist, yy=year, mm=month, dd=day,
                         h=hour, m=minute, s=second };
}

/*	Returns directory in which the indicated application resides.
*/

FStartUpDir :: !String !Files -> (!String, !Files);
FStartUpDir _ files = (expand_8_3_names_in_path name, files);
where 
{  name  =  RemoveFileName WinGetModulePath;
}

/*	Checks whether the first date is older than the second one.
*/
Older_Date	:: !DATE !DATE -> Bool;
Older_Date	{exists=b1,yy=yy1,mm=mm1,dd=dd1,h=h1,m=m1,s=s1}
			{exists=b2,yy=yy2,mm=mm2,dd=dd2,h=h2,m=m2,s=s2}
	| b1		&& not b2	= True;
	| not b1	|| not b2	= False;
							= Older_IntList [yy1,mm1,dd1,h1,m1,s1] [yy2,mm2,dd2,h2,m2,s2];
	
Older_IntList	:: ![Int] ![Int] -> Bool;
Older_IntList []		[]					=  False;
Older_IntList [h1:t1]	[h2:t2]	| h1 < h2	=  True;
								| h1 > h2	=  False;
											=  Older_IntList t1 t2;

/*	Opens a directory selector dialog.
	Analogous to 'SelectInputFile'.
*/
SelectDir ::  !*s !(IOState *s) -> (!Bool, !String, !*s, !IOState *s);
SelectDir s io 
   | gotit = ( True, RemoveFileName filepath, s2, os2);
           = result;
where
{   
   (result=:( gotit, filepath, s2, os2)) = SelectInputFile s io;
}

RemoveFileName :: !String -> String;
RemoveFileName path
		| found	= (path % (0, dec position));
				= path;
		where {
		(found,position)	= LastColon path last;
		last				= dec (size path);
		};

LastColon :: !String !Int -> (!Bool, !Int);
LastColon s i
	| i <= 0
		= (False,0);
	| DirSeparator==s.[i]
	 	= (True, i);
		= LastColon s (dec i);

/*	Launches the indicated appliaction.
	The result consists of a boolean indicating success, a result code returned by the
	application and the new program and io state.
*/
Launch ::	!String !*state !(IOState *state)
			-> (!Bool,!Int,!*state,!IOState *state);
Launch n s io = ( False, -1, s, io );

ShiftKeyIsDown :: !(IOState .s) -> (!Bool, !IOState .s);
ShiftKeyIsDown ioState
	=	(False, ioState);

GetFullApplicationPath :: !*Files -> ({#Char}, *Files);
GetFullApplicationPath files
	=	FStartUpDir "" files;