const IProgramm$="ChangeAppPos"
const IArt$="Freeware"
const IVersion$="1.00F"
const IBuild$="Build 13"
const ICreatedate$="Samstag, 18.11.2000"
const IAutorname$="Sebastian Hochstetter"
const ICopyright$="Copyright  2000 by PsiSoft & c't"
const IEmail$="development@psisoft.de"
const IWeb$="www.psisoft.de"
const MaxApps%=255
const KUidShellIni1&=&10000050
const KUidShellIni2&=&100000e4
const KUidSystem&=&10000076

include "system.oxh"
include "const.oph"

rem ******************************
rem * Schaltzentrale						 *
rem * Wird als Erstes ausgefhrt *
rem ******************************
PROC main:
	global i%,posicon%(MaxApps%),posfile&(MaxApps%),app$(MaxApps%,50),menu%,inifile$(KMaxStringLen%),inichk%,inidir$(KMaxStringLen%),shelldir$(KMaxStringLen%)
	rem I%        Anzahl der gefundenen Programme in der Shell.ini
	rem PosIcon%  Array: Position des i%ten Programms
	rem PosFile&  Array: Adresse des i%ten Programms in der Shell.ini
	rem App$      Array: Programmname mit bis zu 50 Zeichen
	rem Menu%     Merkt sich den letzten gewhlten Meneintrag
	rem IniFile$  Pfad der programmeigenen INI-Datei
	rem IniChk%   Wenn gleich KTrue%, verwende System Shell.ini
	rem IniDir$   Wenn nicht System Shell.ini, dann in diesem Ordner suchen
	rem ShellDir$ Pfad der Shell.ini
	
	local a&(16)
	giprint icopyright$
	setflags KAutoCompact&
	readini:
	do
		getevent32 a&()
		if a&(1)=KKeyMenu32% or a&(1)=KKeySidebarMenu32%
			a&(1)=menu&:
		elseif a&(1)> KKeySidebarMenu32% and a&(1)< KKeySidebarMenu32%+5 rem copy, ir send, zoom
			giprint "Dieses Element ist nicht verfgbar",KBusyTopRight%
		elseif a&(4)=KKmodControl% or a&(4)=KKmodControl%+KKmodShift% rem hotkey
			a&(1)=a&(1)+$60
			if a&(4)=KKmodControl%+KKmodShift% :a&(1)=a&(1)-32 :endif
				hotkey&:(a&(1))
			endif
	until a&(1)=%e
	saveini:
	stop
ENDP

rem **********************************
rem * ffnet bzw. Erstellt INI-Datei *
rem **********************************
proc readini:
	local ini%(6)
	
	rem Bestimmt den Pfad der INI-Datei. Datei liegt im gleichen Verzeichnis wie Programm
	inifile$=cmd$(KCmdAppName%)
	inifile$=parse$(inifile$,"",ini%())
	inifile$=left$(inifile$,ini%(4)-1)+iprogramm$+".ini"
	
	if not exist(inifile$) rem erster Programmstart => INI-Datei erstellen
		about:
		create """"+inifile$+"""",a,inichk%,inidir$
		insert
			a.inichk%=KTrue%
			a.inidir$=""
		put
	else rem INI-Datei bereits vorhanden
		open """"+inifile$+"""",a,inichk%,inidir$
	endif
	inichk%=a.inichk%
	inidir$=a.inidir$
	close
endp

rem ****************************************
rem * Schreibt nderungen in die INI-Datei *
rem ****************************************
proc saveini:
	open """"+inifile$+"""",a,inichk%,inidir$
	modify
		a.inichk%=inichk%
		a.inidir$=inidir$
	put
	close
endp

rem *********************************************************************************
rem * Stellt das Men da																														*
rem * Liefert Ascii-Code des ausgewhlten Menpunktes an Hotkey& und an Main zurck *
rem *********************************************************************************
proc menu&:
	minit
	mcard "Datei","Shell.ini auslesen",%r,"Applikationen tauschen",-%c,"Beenden",%e
	mcard "Extras","Einstellungen",-%q,"ber...",%a
	return hotkey&:(int(menu(menu%)))
endp

rem ********************************************************************
rem * Untersucht k& und ruft gegebenenfalls die ntige Prozedur auf    *
rem * Liefert k& ohne nderung an die rufende Prozedur/Funktion zurck *
rem ********************************************************************
proc hotkey&:(k&)
	if k&=%r rem shell.ini auslesen
		geticons:
	elseif k&=%c rem applikationen tauschen
		if i%>0
			change:
		else
			giprint "Zuerst Shell.ini auslesen!",KBusyTopRight%
		endif
	elseif k&=%q rem einstellungen
		dinit "Einstellungen"
		dcheckbox inichk%,"System Shell.ini verwenden"
		dtext ""," ",KDTextLineBelow%
		dtext "","Standardverzeichnis fr Shell.ini's auswhlen:"
		dfile inidir$,"Ordner,Disk",KDFileFoldersOnly%+KDFileSelectorWithSystem%
		dialog
	elseif k&=%a rem ber...
		about:
	endif
	return k&
endp

rem *****************************************************************************
rem * Liest Shell.ini aus und speichert die Informationen in globalen Variablen *
rem * i% gibt die Anzahl der gefundenen Programme an														*
rem *****************************************************************************
proc geticons:
	local ret%,handel%,offset&,puffer%(255),addr&,len%,zero%(3),k%

	cls

	if inichk%=KFalse% rem nicht system shell.ini
		shelldir$=inidir$
		dinit "Shell.ini ffnen"
		dfile shelldir$,"Datei,Ordner,Disk",KDFileSelectorWithSystem%,KUidShellIni1&,KUidShellIni2&,KUidSystem&
		if dialog=KDlgCancel% :return :endif
	else
		shelldir$="c:\system\apps\shell\Shell.ini"
	endif

	ret%=ioopen(handel%,shelldir$,KIoOpenAccessRandom%)
	if ret%<0 :raise ret% :endif
	
	rem springt zum 48. Byte (1. Byte hat offset&=0)
	offset&=47
	ret%=ioseek(handel%,1,offset&)
	if ret%<0 :raise ret% :endif
	
	rem speichert Lnge des folgenden Ordners (Standardordner) in puffer%
	addr&=addr(puffer%(1))
	ret%=ioread(handel%,addr&,1)
	if ret%<0 :raise ret% :endif
	
	rem springt zum nchsten Ordner (Lesezeichen)
	rem peekb(addr&) ist die Lnge des Standardordners, wobei 2 fr das Byte der Lngenangabe abgezogen werden mssen
	rem jeder Buchstabe wird mit 4 berechnet
	offset&=(peekb(addr&)-2)/4
	ret%=ioseek(handel%,3,offset&)
	if ret%<0 :raise ret% :endif
	
	rem speichert Lnge des folgenden Ordners (Lesezeichen) in puffer%
	addr&=addr(puffer%(1))
	ret%=ioread(handel%,addr&,1)
	if ret%<0 :raise ret% :endif
	
	rem berspringt Ordner Lesezeichen + 9 weitere Bytes
	offset&=(peekb(addr&)-2)/4+9
	ret%=ioseek(handel%,3,offset&)
	if ret%<0 :raise ret% :endif
	
	rem jetzt kommen die Informationen ber die Programme
	rem das Muster ist: Positionsnummer, 3 leere Bytes, Programm-UID und Programmname
	posfile&(1)=offset& :i%=0
	do
		i%=i%+1
		
		rem speichert Positionsnummer in posicon%
		addr&=addr(puffer%(1))
		ret%=ioread(handel%,addr&,1)
		if ret%<0 :raise ret% :endif
		posicon%(i%)=peekb(addr&)
		
		rem gibt es noch weitere Eintrge?
		k%=1
		do
			addr&=addr(puffer%(1))
			ret%=ioread(handel%,addr&,1)
			if ret%<0 :raise ret% :endif
			zero%(k%)=peekb(addr&)
			k%=k%+1
		until k%>3
		if zero%(1)<>0 or zero%(2)<>0 or zero%(3)<>0
			i%=i%-1 :break
		endif
		
		offset&=4
		ret%=ioseek(handel%,3,offset&)
		if ret%<0 :raise ret% :endif
		posfile&(i%+1)=offset&
		
		addr&=addr(puffer%(1))
		ret%=ioread(handel%,addr&,1)
		if ret%<0 :raise ret% :endif
		len%=(peekb(addr&)-2)/4
		posfile&(i%+1)=posfile&(i%+1)+ret%
		
		rem speichert Programmname in app$
		addr&=addr(app$(i%))
		ret%=ioread(handel%,addr&+1,len%)
		if ret%<0 :raise ret% :endif
		pokeb addr&,ret%
		posfile&(i%+1)=posfile&(i%+1)+ret%
		
		print posicon%(i%),app$(i%)
	until 0
	ioclose(handel%)
endp

rem *************************************************************************
rem * Tauscht die Positionsnummern von zwei Programmen in der Shell.ini aus *
rem *************************************************************************
proc change:
	local k%,tausch1$(KMaxStringLen%),tausch2$(KMaxStringLen%)
	local t1%,t2%,len1%,len2%
	local threadid&,prev&
	local ret%,handel%,offset&
	local temp%
	
	rem baut String mit allen Programmen fr DChoice zusammen
	rem wird der String zu gro, werden die letzten Programme weg gelassen
	k%=1
	while k%<=i%
		len1%=len(tausch1$)
		len2%=len(app$(k%)+",")
		if len1%+len2%>KMaxStringLen% :break :endif
		tausch1$=tausch1$+app$(k%)+","
		k%=k%+1
	endwh
	len1%=len(tausch1$)
	tausch1$=left$(tausch1$,len1%-1)
	tausch2$=tausch1$
	
	dinit "Tausche Icons"
	dchoice t1%,"",tausch1$
	dchoice t2%,"mit",tausch2$
	if dialog <> KDlgCancel%
		if t1%<>t2%
			print
			print "Tausche",app$(t1%),"mit",app$(t2%)
			
			ret%=ioopen(handel%,shelldir$,KIoOpenAccessUpdate% or KIoOpenAccessRandom%)
			if ret%<0 :raise ret% :endif
			
			rem springt zu Programm 1
			offset&=posfile&(t1%)
			ret%=ioseek(handel%,1,offset&)
			if ret%<0 :raise ret% :endif
			
			rem berschreibt Positionsnummer mit der von Programm 2
			ret%=iowrite(handel%,addr(posicon%(t2%)),1)
			if ret%<0 :raise ret% :endif
			
			rem springt zu Programm 2
			offset&=posfile&(t2%)
			ret%=ioseek(handel%,1,offset&)
			if ret%<0 :raise ret% :endif
			
			rem berschreibt Positionsnummer mit der von Programm 1
			ret%=iowrite(handel%,addr(posicon%(t1%)),1)
			if ret%<0 :raise ret% :endif
			
			ioclose(handel%)
			
			rem Dreieckstausch mit posicon%(t1%) und posicon%(t2%)
			temp%=posicon%(t2%)
			posicon%(t2%)=posicon%(t1%)
			posicon%(t1%)=temp%
			
			rem System killen damit nderungen wirksam werden ist nur bei System Shell.ini ntig
			if inichk%=KTrue%
				rem verwende Befehle der System.opx
				ThreadID&=GetThreadIdFromAppUID&:(KUidSystem&,Prev&)
				KillTask&:(ThreadID&,0)
			endif
		endif
	endif
endp

rem *********************************
rem * Zeigt Copyright-Bildschrim an *
rem *********************************
proc about:
	dinit icopyright$,KDlgButRight%+KDlgDensePack%
	dtext "Programm",iprogramm$+" - "+iart$
	dtext "Version",iversion$
	dtext "Build",ibuild$,KDTextLineBelow%
	dtext "Erstellungsdatum",icreatedate$
	dtext "Autor",iautorname$
	dtext "Email",iemail$
	dtext "Web",iweb$, KDTextLineBelow%
	dtext "Kompatibel mit","Epoc32 R1-R5"
	dtext " ","WINS Emulator R1-R5"
	dbuttons "Weiter",KDButtonEnter% or KDButtonNoLabel%
	dialog
endp