include	clib.inc
ifdef __CLIP__
include	clip.inc
include	keyb.inc
include	string.inc
include	iost.inc
include	mouse.inc
include	conio.inc
include	tinfo.inc

	extrn	IDD_ClipboardWarning:DWORD
	extrn	tiseto:		NEAR
	extrn	tidelete:	NEAR
	extrn	ticontinue:	NEAR
	extrn	tiputc:		NEAR
	extrn	tievent:	NEAR
  ifdef __TE__
	extrn	tiflushl:	NEAR
	extrn	tiremline:	NEAR
  endif

	public	ticlipdel
	public	ticlipcut
	public	ticlipset
	public	ticlipget
	public	tiselected
	public	ticlipevent
  ifdef __TE__
	public	tiselectall
  endif

;
; Cut		Shift-Del	Ctrl-X
; Copy		Ctrl-Ins	Ctrl-C
; Paste		Shift-Ins	Ctrl-V
; Clear		Del		Ctrl-Del
;

_TEXT	SEGMENT

ticlip_Copy PROC
	xor	ax,ax
	jmp	ticlipcut
ticlip_Copy ENDP

ticlip_Cut PROC
	mov	ax,1
	jmp	ticlipcut
ticlip_Cut ENDP

tiselected PROC ; test if selected text
	mov	bx,tinfo
  ifdef __TE__
	mov	ax,[bx.ti_clel]
	sub	ax,[bx.ti_clsl]
	mov	cx,ax
	jnz	@F
  endif
	mov	ax,[bx.ti_cleo]
	sub	ax,[bx.ti_clso]
    @@:
	ret
tiselected ENDP

ticlipset PROC	; set clipboard to current position
	mov	bx,tinfo
	mov	ax,[bx.ti_boff]
	add	ax,[bx.ti_xoff]
	mov	[bx.ti_clso],ax
	mov	[bx.ti_cleo],ax
  ifdef __TE__
	test	[bx.ti_flag],_T_LINEBUF
	jz	@F
	mov	ax,[bx.ti_loff]
	add	ax,[bx.ti_yoff]
	mov	[bx.ti_clsl],ax
	mov	[bx.ti_clel],ax
    @@:
  endif
	ret
ticlipset ENDP

alignxy PROC	; subtract ax then dx while cx--
	test	cx,cx
	je	alignxy_end
	cmp     ax,cx
	jb	alignxy_00
	sub	ax,cx
    alignxy_end:
	ret
    alignxy_00:
	sub	cx,ax
	xor	ax,ax
	sub	dx,cx
	ret
alignxy ENDP

tialigncl PROC	; goto start of selection
	mov	bx,tinfo
  ifdef __TE__
	test	[bx.ti_flag],_T_LINEBUF
	jz	@F
	mov	dx,[bx.ti_loff]
	mov	ax,[bx.ti_yoff]
	mov	cx,dx
	add	cx,ax
	sub	cx,[bx.ti_clsl]
	call	alignxy
	mov	[bx.ti_loff],dx
	mov	[bx.ti_yoff],ax
    @@:
  endif
	mov	dx,[bx.ti_boff]
	mov	ax,[bx.ti_xoff]
	mov	cx,dx
	add	cx,ax
	sub	cx,[bx.ti_clso]
	call	alignxy
	mov	[bx.ti_boff],dx
	mov	[bx.ti_xoff],ax
	ret
tialigncl ENDP

ticlipdel PROC
	push	si
	push	di
	call	tiselected
  ifdef __TE__
	mov	di,cx
	jz	ticlipdel_end
	call	tialigncl
	mov	ax,[bx.ti_clsl]
	call	tigetline
	jz	ticlipdel_end
	test	di,di
	jnz	@F
	or	[bx.ti_flag],_T_MODIFIED
	push	dx
	mov	cx,ax
	add	ax,[bx.ti_clso]
	push	ax
	push	dx
	add	cx,[bx.ti_cleo]
	push	cx
	call	strcpy
	jmp	ticlipdel_set
    @@:
	mov	es,dx
	mov	si,ax
	xor	ax,ax
	add	si,[bx.ti_clso]
	mov	es:[si],al
	mov	ax,[bx.ti_clel]
	call	tigetline
	jz	ticlipdel_end
	or	[bx.ti_flag],_T_MODIFIED
	push	dx
	push	ax
	push	dx
	add	ax,[bx.ti_cleo]
	push	ax
	call	strcpy
	dec	di
	jz	ticlipdel_del
	mov     si,[bx.ti_clsl]
	inc	si
    ticlipdel_lines:
	mov	ax,si
	mov	dx,di
	call	tiremline
    ticlipdel_del:
	call	tidelete
  else
	jz	ticlipdel_end
	mov	dx,word ptr [bx.ti_bp+2]
	mov	si,word ptr [bx.ti_bp]
	mov	di,[bx.ti_cleo]
	mov	ax,si
	add	ax,[bx.ti_clso]
	push	dx
	push	ax
	mov	ax,si
	add	ax,di
	push	dx
	push	ax
	call	strcpy
	mov	dx,si
	add	dx,di
	sub	dx,ax
	mov	cx,si
	add	cx,[bx.ti_boff]
	add	cx,[bx.ti_xoff]
	cmp	ax,cx
	je	ticlipdel_set
	sub	[bx.ti_xoff],dx
  endif
    ticlipdel_set:
	call	tiseto
	call	ticlipset
	xor	ax,ax
	inc	ax
    ticlipdel_end:
	pop	di
	pop	si
	ret
ticlipdel ENDP

ifdef __TE__

tiselectall PROC
	mov	bx,tinfo
	xor	ax,ax
	mov	[bx.ti_clsl],ax
	mov	[bx.ti_clso],ax
	mov	[bx.ti_clel],ax
	mov	ax,[bx.ti_bcol]
	mov	[bx.ti_cleo],ax
	cmp	[bx.ti_lcnt],ax
	je	@F
	mov	ax,[bx.ti_lcnt]
	dec	ax
	mov	[bx.ti_clel],ax
    @@:
	jmp	ticontinue
tiselectall ENDP

ticopyselection PROC
	push	si
	push	di
	xor	di,di
	mov	si,tinfo
	invoke	oinitst,addr STDO,MAXCLIPSIZE
    	jnz	@F
	invoke	oinitst,addr STDO,1000h
	jz	ticopyselection_eof
    @@:
	inc	di
	mov	STDO.ios_flag,IO_CLIPBOARD
	mov	ax,[si.ti_clsl]
	mov	dx,[si.ti_clso]
	mov	cx,[si.ti_clel]
	mov	bx,[si.ti_cleo]
	call	tiflushl
	jnz	@F
	mov	ax,bx
	mov	[si.ti_clsl],dx
	mov	[si.ti_clso],ax
	inc	di
	invoke	rsmodal, IDD_ClipboardWarning
    @@:
	call	oflush
	invoke	ofreest,addr STDO
    ticopyselection_eof:
	mov	ax,di
	test	ax,ax
	pop	di
	pop	si
	ret
ticopyselection ENDP

endif

ticlipcut PROC
	mov	dx,ax
	call	tiselected
	jz	ticlipcut_set
	push	dx
  ifdef __TE__
	call	ticopyselection
	pop	dx
	jz	ticlipcut_eof
	dec	ax
	mov	ax,dx
	jnz	ticlipcut_eof
  else
	mov	dx,ax
	push	word ptr [bx.ti_bp+2]
	mov	ax,[bx.ti_clso]
	add	ax,word ptr [bx.ti_bp]
	push	ax
	push	dx
	call	ClipboardCopy
	pop	ax
  endif
	test	ax,ax
	jz	ticlipcut_set
	call	ticlipdel
    ticlipcut_set:
	call	ticlipset
    ticlipcut_eof:
	xor	ax,ax
	ret
ticlipcut ENDP

ticlipget PROC
	push	si
	push	di
	mov	si,tinfo
	mov	ax,[si.ti_flag]
	and	ax,_T_OVERWRITE
	jnz	@F
	call	ticlipset
	jmp	ticlipget_get
    @@:
	call	ticlipdel
    ticlipget_get:
	call	ClipboardPaste
	jz	ticlipget_end
  ifdef __TE__
	push	[si.ti_yoff]
	push	[si.ti_loff]
  endif
	push	[si.ti_xoff]
	push	[si.ti_boff]
	mov	si,Clipbsize
	mov	di,ax
	mov	es,dx
  ifdef __TE__
	mov	dx,ax		; Problem of inserting text by pushing
	mov	cx,si		; a long line in front - EOL == abort
	cld
	mov	ax,0Ah		; Insert '\n' if clipboard contain a '\n'
	repne	scasb		; then move back to prev pos
	mov	di,dx
	jne	ticlipget_00
	mov	bx,si
	cmp	es:[di+bx-2],al	; remove '\n' from end if exist
	jne	@F		; This align line-based clip-set
	;
	; A val to indicate the need of calling Delete
	; if the last char is not 0Ah may be set her..
	;
	mov	es:[di+bx-2],ah
    @@:
	push	es
	call	tiputc
	pop	es
	test	ax,ax
	jnz	ticlipget_01
	pop	dx
	pop	ax
	pop	cx
	pop	bx
	push	bx
	push	cx
	push	ax
	push	dx
	mov	si,tinfo
	mov	[si.ti_xoff],ax
	mov	[si.ti_boff],dx
	mov	[si.ti_yoff],cx
	mov	[si.ti_loff],bx
	mov	si,Clipbsize
  endif
    ticlipget_00:
	mov	al,es:[di]
	test	al,al
	jz	ticlipget_01
	inc	di
	push	es
	call	tiputc
	pop	es
	test	ax,ax
	jnz	ticlipget_01
	dec	si
	jnz	ticlipget_00
    ticlipget_01:
	pop	dx
	pop	ax
	mov	bx,tinfo
	mov	[bx.ti_xoff],ax
	mov	[bx.ti_boff],dx
  ifdef __TE__
	pop	dx
	pop	ax
	mov	[bx.ti_yoff],ax
	mov	[bx.ti_loff],dx
  endif
    ticlipget_end:
	xor	ax,ax
	pop	di
	pop	si
	ret
ticlipget ENDP

ticlipevent PROC
	push	si
	push	di
	mov	si,ax
	call	tiselected
	jnz	@F
	call	ticlipset
    @@:
	xor	di,di
	mov	cx,cl_keycount
	jmp     ticlipevent_loop
    ticlipevent_found:
	call	cl_proctable[di]
	jmp     ticlipevent_end
    ticlipevent_loop:
	cmp	si,cl_keytable[di]
	je	ticlipevent_found
	add	di,2
	dec	cx
	jnz	ticlipevent_loop
	les	bx,keyshift
	mov	al,es:[bx]
	and	al,KEY_SHIFT
	jnz	@F
	cmp	si,KEY_DEL
	jne	ticlipevent_ESC
	call	ticlipdel
	jz	ticlipevent_set
	xor	ax,ax
	jmp	ticlipevent_end
    @@:
	cmp	si,KEY_INS
	jne	@F
	call	ticlipget
	jmp	ticlipevent_end
    @@:
	cmp	si,KEY_DEL
	jne	@F
	mov	ax,1
	call	ticlipcut
	jmp	ticlipevent_end
    @@:
	mov	di,offset cl_shiftkeytable
	mov	cx,cl_shiftkeycount
  ifdef __TE__
	mov	bx,tinfo
	test	[bx.ti_flag],_T_LINEBUF
	jnz	@F
	sub	cx,4
  endif
    @@:
	cmp	si,[di]
	je	ticlipevent_MOVE
	add	di,2
	dec	cx
	jnz	@B
    ticlipevent_ESC:
	mov	cx,cl_nodeletecount
	xor	di,di
    @@:
	cmp	si,cl_nodeletekeys[di]
	je	ticlipevent_set
	add	di,2
	dec	cx
	jnz	@B
	mov	ax,si
	test	al,al
	jz	ticlipevent_set
	call	ticlipdel
    ticlipevent_set:
	call	ticlipset
	mov	ax,si
    ticlipevent_end:
	pop	di
	pop	si
	ret
    ticlipevent_MOVE:
	mov	ax,si
	call	tievent
	test	ax,ax
	jnz	ticlipevent_nul
	mov	bx,tinfo
  ifdef __TE__
	mov	cx,[bx.ti_loff]
	add	cx,[bx.ti_yoff]
	cmp	cx,[bx.ti_clsl]
	jb	ticlipevent_MOVEBACK
  endif
	mov	ax,[bx.ti_boff]
	add	ax,[bx.ti_xoff]
	cmp	ax,[bx.ti_clso]
	jb	ticlipevent_MOVEBACK
	cmp	si,KEY_RIGHT
	jne	@F
	mov	dx,ax
	dec	dx
	cmp	dx,[bx.ti_clso]
	jne	@F
	cmp	dx,[bx.ti_cleo]
	jne	ticlipevent_MOVEBACK
    @@:
	mov	[bx.ti_cleo],ax
  ifdef __TE__
	mov	[bx.ti_clel],cx
  endif
	jmp	ticlipevent_nul
    ticlipevent_MOVEBACK:
	mov	[bx.ti_clso],ax
  ifdef __TE__
	mov	[bx.ti_clsl],cx
  endif
    ticlipevent_nul:
	xor	ax,ax
	jmp	ticlipevent_end
ticlipevent ENDP

_TEXT	ENDS

_DATA	SEGMENT

cl_proctable label word
	dw	ticlip_Copy
	dw	ticlip_Copy
	dw	ticlipget
	dw	ticlip_Cut
	dw	ticlip_Cut
cl_keytable label word
	dw	KEY_CTRLINS
	dw	KEY_CTRLC
	dw	KEY_CTRLV
	dw	KEY_CTRLX
	dw	KEY_CTRLDEL
cl_keycount = (($ - offset cl_keytable) / 2)

cl_shiftkeytable label word
	dw	KEY_HOME
	dw	KEY_LEFT
	dw	KEY_RIGHT
	dw	KEY_END
  ifdef __TE__
	dw	KEY_UP
	dw	KEY_DOWN
	dw	KEY_PGUP
	dw	KEY_PGDN
  endif
cl_shiftkeycount = (($ - offset cl_shiftkeytable) / 2)

cl_nodeletekeys label word
	dw	KEY_ESC
  ifdef __MOUSE__
	dw	MOUSECMD
  endif
	dw	KEY_BKSP
	dw	KEY_TAB
	dw	KEY_ENTER
	dw	KEY_KPENTER
cl_nodeletecount = (($ - offset cl_nodeletekeys) / 2)

_DATA	ENDS
endif
	END
