include doszip/doszip.inc
include conio.inc
include io.inc
include malloc.inc
include string.inc
include stdio.inc
include keyb.inc

	extrn	IDD_DZHistory:DWORD

	public	history
	public	history_open
	public	history_close
	public	history_move
	public	history_save
	public	history_delete
	public	cmhistory
	public	doskey_save
	public	cmpathleft      ; Alt-Left  - Previous Directory
	public	cmpathright	; Alt-Right - Next Directory
	public	cmdoskey_up	; Alt-Up    - Previous Command
	public	cmdoskey_dn	; Alt-Down  - Next Command
	public	searchstring
	public	replacestring
	public	findfilemask
	public	findfilepath
	public	filelist_bat
	public	format_lst
	public	mklist
	public	cp_selectmask

_DATA	SEGMENT

MAXDOSKEY	= 128
MAXDOSKEYS	= 16
HISTORY_MAX	= 16
DOSKEY_SIZE	= MAXDOSKEYS * MAXDOSKEY
HISTORY_SIZE	= HISTORY_MAX * SIZE S_DZPATH

S_DZ_CMD	STRUC
hi_dzpath	db HISTORY_SIZE dup(?)
hi_doskey	db DOSKEY_SIZE dup(?)
hi_search	db 128 dup(?)
hi_replace	db 128 dup(?)
hi_mklist	S_MKLST <?>
hi_selectmask	db 32 dup(?)
hi_filelist	db 80 dup(?)
hi_format	db 80 dup(?)
hi_ffmask	db 128 dup(?)
hi_ffpath	db WMAXPATH dup(?)
S_DZ_CMD	ENDS

history		dd ?
searchstring	db 128 dup(?)
replacestring	db 128 dup(?)
mklist		S_MKLST	<?,?,?,?,?,?,?,-1,?>
cp_selectmask	db 32 dup(?)
size_static	= $ - offset searchstring
filelist	db 'filelist.bat',0
formatlist	db '%f\n',0
findmask	db '*.*',0
filelist_bat	dd ?
format_lst	dd ?
findfilemask    dd ?
findfilepath    dd ?
doskey_bindex	db ?
doskey_isnext	db ?

_DATA	ENDS

_DZIP	SEGMENT

history_delete PROC
	call getcmdfile
	push dx
	push ax
	invoke setfattr,dx::ax,0
	call remove
	ret
history_delete ENDP

ifdef __TE__
 topenh	proto dist pascal handle:word
 tsaveh	proto dist pascal handle:word
endif

history_open PROC
	push si
	.if func(malloc, SIZE S_DZ_CMD)
	    stom history
	    push dx
	    push ax
	    push SIZE S_DZ_CMD
	    add  ax,hi_filelist
	    stom filelist_bat
	    add  ax,80
	    stom format_lst
	    add  ax,80
	    stom findfilemask
	    add  ax,128
	    stom findfilepath
	    call memzero
	    invoke strcpy,filelist_bat,addr filelist
	    invoke strcpy,format_lst,addr formatlist
	    invoke strcpy,findfilemask,addr findmask
	    call getcmdfile
	    .if func(osopen,dx::ax,_A_NORMAL,M_RDONLY,A_OPEN) != -1
		mov si,ax
		.if func(osread,ax,history,SIZE S_DZ_CMD) == SIZE S_DZ_CMD
		    lodm history
		    add ax,hi_search
		    invoke memcpy,addr searchstring,dx::ax,size_static
		  ifdef __TE__
		    call getinifile
		    invoke topenh,si
		  endif
		.endif
		invoke close,si
		inc ax
	    .endif
	.endif
	pop si
	ret
history_open ENDP

history_close PROC
	push si
	lodm history
	.if ax
	    add ax,hi_search
	    invoke memcpy,dx::ax,addr searchstring,size_static
	    call getcmdfile
	    .if func(osopen,dx::ax,_A_NORMAL,M_WRONLY,A_CREATE or A_TRUNC) != -1
		mov si,ax
		invoke oswrite,ax,history,SIZE S_DZ_CMD
		invoke free,history
	      ifdef __TE__
		invoke tsaveh,si
	      endif
		invoke close,si
		inc ax
	    .endif
	.endif
	pop si
	ret
history_close ENDP

history_move PROC 	; AL direction
	push	si
	push	di
	cmp	word ptr history+2,0
	je	history_move_end
	mov	di,ds
	mov	es,di
	mov	di,offset convbuf
	lds	si,history
	mov	cx,size S_DZPATH
	mov	bx,size S_DZPATH * (HISTORY_MAX-1)
	cld
	or	al,al
	push	si
	jnz	history_move_00
	add	si,bx
    history_move_00:
	rep	movsb
	pop	di
	mov	si,di
	add	si,size S_DZPATH
	push	ds
	pop	es
	mov	cx,bx
	or	al,al
	jnz	history_move_01
	xchg	si,di
	dec	bx
	add	si,bx
	add	di,bx
	inc	bx
	std
    history_move_01:
	rep	movsb
	push	ss
	pop	ds
	mov	si,offset convbuf
	mov	di,word ptr history
	mov	cx,size S_DZPATH
	cld
	or	al,al
	jz	history_move_02
	add	di,bx
    history_move_02:
	rep	movsb
    history_move_end:
	pop	di
	pop	si
	ret
history_move ENDP

history_save PROC
	mov	bx,cpanel
	mov	bx,[bx]
	mov	ax,[bx]
	and	ax,_W_ARCHIVE or _W_ROOTDIR
	jz      history_save_00
	xor	ax,ax
	jmp	history_save_02
    history_save_00:
	push	si
	mov	si,offset _bufin
	invoke	fullpath, ds::si, 0
	or	ax,ax
	jz	history_save_01
	invoke	strcmp, ds::si, history
	or	ax,ax
	jz	history_save_01
	xor	ax,ax
	call	history_move
	invoke	strcpy, history, addr _bufin
	mov	si,cpanel
	mov	ax,[si.pn_fcb_index]
	les	bx,history
	mov	es:[bx.dzp_bufid],ax
	mov	ax,[si.pn_cel_index]
	mov	es:[bx.dzp_celid],ax
	mov	si,[si]
	mov	ax,[si]
	mov	es:[bx.dzp_flag],ax
	inc	ax
    history_save_01:
	pop	si
    history_save_02:
	ret
history_save ENDP

cmhistory PROC DIST
	push	si
	push	di
	les	bx,DLG_Commandline
	mov	ax,es:[bx]
	and	ax,_D_ONSCR
	jz	cmhistory_end
	invoke	rsopen, IDD_DZHistory
	jz	cmhistory_end
	push	dx		; twclose
	push	ax
	pushm	IDD_DZHistory
	push	dx
	push	ax
	push	dx		; tdinit
	push	ax
	push	dx		; twshow
	push	ax
	push	dx		; .copy
	push	ax
	mov	di,word ptr history
	add	di,HISTORY_SIZE
	add	bx,16
	push	ds
	mov	si,word ptr history+2
	mov	es,si
	mov	ds,dx
	mov	dx,not _O_STATE
	xor	cx,cx
    cmhistory_init:
	mov	word ptr [bx.to_data],di
	mov	word ptr [bx.to_data+2],si
	cmp	byte ptr es:[di],0
	jz	cmhistory_event
	and	[bx],dx
	add	bx,size S_TOBJ
	add	di,MAXDOSKEY
	inc	cx
	cmp	cx,MAXDOSKEYS
	jb	cmhistory_init
	jmp	cmhistory_event
    cmhistory_end:
	pop	di
	pop	si
	ret
    cmhistory_close:
	call	dlclose
	mov	ax,dx
	jmp	cmhistory_end
    cmhistory_event:
	pop	ds
	pop	bx
	pop	es
	mov	ax,cx
	mov	es:[bx.dl_count],al
	mov	al,doskey_bindex
	mov	es:[bx.dl_index],al
	cmp	al,cl
	jb	cmhistory_02
	mov	es:[bx.dl_index],ch
    cmhistory_02:
	call	dlshow
	call	dlinit
	call	rsevent
	or	ax,ax
	jz	cmhistory_close
	dec	ax
	mov	doskey_bindex,al
	inc	ax
	shl	ax,4
	add	bx,ax
	push	ds
	push	offset com_base
	pushm	es:[bx.to_data]
	call	strcpy
	call	dlclose
	push	KEY_END
	call	comevent
	mov	ax,1
	jmp	cmhistory_end
cmhistory ENDP

doskey_save PROC
	.if func(strtrim, addr com_base)
	    lodm history
	    .if dx
		add ax,HISTORY_SIZE
		mov bx,ax
		.if func(strcmp, addr com_base, dx::ax)
		    mov ax,bx
		    add ax,MAXDOSKEY
		    invoke memmove, dx::ax, dx::bx, MAXDOSKEY*(MAXDOSKEYS-1)
		    invoke strcpy, dx::bx, addr com_base
		.endif
		mov ax,1
	    .endif
	.endif
	ret
doskey_save ENDP

doskeytocommand PROC
	push	ds
	push	offset com_base
	push	word ptr history+2
	mov	ah,doskey_bindex
	mov	al,00h
	shr	ax,1
	add	ax,word ptr history
	add	ax,HISTORY_SIZE
	push	ax
	call	strcpy
	ret
doskeytocommand ENDP

cmdoskey_up PROC DIST
	les	bx,DLG_Commandline
	mov	ax,es:[bx]
	and	ax,_D_ONSCR
	jz	cmdoskey_up_end
	mov	al,1
	cmp	doskey_isnext,al
	jne	cmdoskey_up_00
	mov	com_base,ah
	jmp	cmdoskey_up_01
    cmdoskey_up_00:
	call	doskeytocommand
	inc	doskey_bindex
	cmp	doskey_bindex,MAXDOSKEYS
	jb	cmdoskey_up_01
	mov	doskey_bindex,0
    cmdoskey_up_01:
	push	KEY_END
	call	comevent
	mov	ax,1
	mov	doskey_isnext,ah
    cmdoskey_up_end:
	ret
cmdoskey_up ENDP

cmdoskey_dn PROC DIST
	les	bx,DLG_Commandline
	mov	ax,es:[bx]
	and	ax,_D_ONSCR
	jz	cmdoskey_dn_end
	cmp	doskey_isnext,ah
	jne	cmdoskey_dn_00
	mov	com_base,ah
	jmp	cmdoskey_dn_03
    cmdoskey_dn_00:
	cmp	doskey_bindex,0
	jne	cmdoskey_dn_01
	mov	doskey_bindex,(MAXDOSKEYS-1)
	jmp	cmdoskey_dn_02
    cmdoskey_dn_01:
	dec	doskey_bindex
    cmdoskey_dn_02:
	call	doskeytocommand
    cmdoskey_dn_03:
	push	KEY_END
	call	comevent
	mov	ax,1
	mov	doskey_isnext,al
    cmdoskey_dn_end:
	ret
cmdoskey_dn ENDP

historytocpanel PROC
	push	si
	push	di
	les	si,history
	xor	ax,ax
	or	si,si
	jz	historytocpanel_end
	cmp	al,es:[si]
	jz	historytocpanel_end
	mov	di,cpanel
	mov	di,[di]
	mov	dx,[di]
	test	dx,_W_ARCHIVE or _W_ROOTDIR
	jnz	historytocpanel_end
	mov	ax,dx
	or	ax,es:[si.dzp_flag]
	mov	[di],ax
	mov	ax,es:[si.dzp_bufid]
	mov	dx,es:[si.dzp_celid]
	mov	bx,cpanel
	mov	[bx.pn_fcb_index],ax
	mov	[bx.pn_cel_index],dx
	mov	dx,es
	mov	ax,si
	call	cpanel_setpath
	mov	ax,cpanel
	call	panel_redraw
	mov	ax,1
    historytocpanel_end:
	or	ax,ax
	pop	di
	pop	si
	ret
historytocpanel ENDP

cmpathleft PROC DIST	; Alt-Left - Previous Directory
	call	history_save
	mov	ax,1
	call	history_move
	call	historytocpanel
	jz	cmpathleft_00
	ret
    cmpathleft_00:
	call	history_move
	ret
cmpathleft ENDP

cmpathright PROC DIST	; Alt-Right - Next Directory
	call	history_save
	xor	ax,ax
	call	history_move
	call	historytocpanel
	jz	cmpathright_00
	ret
    cmpathright_00:
	inc	ax
	call	history_move
	ret
cmpathright ENDP

_DZIP	ENDS

	END
