* ------------------------------------------------------------------------- *
* FS2.ASM -- Assembly support routines for PathMaster(tm) File Selector
* Copyright  1987-1989 by Justin V. McCormick.  All Rights Reserved.
* ------------------------------------------------------------------------- *

;BENCHMARK	EQU	1

	include "exec/types.i"
	include "exec/nodes.i"
	include "exec/lists.i"

SYS	MACRO	*
	IFGT	NARG-2
	FAIL	!!!
	ENDC
	IFEQ	NARG-2
	MOVE.L	\2,a6
	ENDC
	JSR	_LVO\1(a6)
	ENDM

XLVO	MACRO	*
	XREF	_LVO\1
	ENDM


* These three equate control the size of the path, file, and pattern string limits
PATHSTRSIZE	EQU	300
FILESTRSIZE	EQU	32
MATCHSTRSIZE	EQU	32

AUTOKNOB	EQU	$1
FREEVERT	EQU	$4
PROPBORDERLESS	EQU	$8
MEMF_CLEAR 	EQU	$10000
WINDOWSIZING	EQU	$1
WINDOWDRAG	EQU	$2
WINDOWDEPTH	EQU	$4
WINDOWCLOSE	EQU	$8
WINDOWTGADS	EQU	WINDOWDRAG!WINDOWDEPTH!WINDOWCLOSE
FPEN		EQU	1
DPEN		EQU	3

fib_DirEntryType EQU	$4
fib_FileName	EQU	$8
fib_Size	EQU	$7C
fib_DateStamp	EQU	$84
fib_SIZEOF	EQU	$104

gg_Flags	EQU	$C
id_SIZEOF	EQU	$24
it_FrontPen	EQU	$0
it_IText	EQU	$C
rp_AreaPtrn	EQU	$8
rp_AreaPtSz	EQU	$1D
wd_Flags	EQU	$18
wd_RPort	EQU	$32

	STRUCTURE FSRequest,0
	STRUCT	fs_dirname,PATHSTRSIZE
	STRUCT	fs_filename,FILESTRSIZE
	STRUCT	fs_matchpattern,MATCHSTRSIZE
	WORD	fs_leftedge
	WORD	fs_topedge
	WORD	fs_sorttype
	UWORD	fs_flags
	ULONG	fs_windowflags
	APTR	fs_fullname
	APTR	fs_ignorepattern
	APTR	fs_pathgadstr
	APTR	fs_filegadstr
	APTR	fs_titlestr
	APTR	fs_readingstr
	APTR	fs_sortingstr
	APTR	fs_emptydirstr
	APTR	fs_nomatchstr
	APTR	fs_selectfilestr
	APTR	fs_selectstr
	APTR	fs_cancelstr
	APTR	fs_specgadstr
	APTR	fs_userscreen
	APTR	fs_userport
	APTR	fs_specgadfunc
	APTR	fs_dirfunc
	APTR	fs_filefunc
	APTR	fs_userfunc
	APTR	fs_initfunc
	APTR	fs_matchfunc
	LABEL	fs_SIZEOF

	STRUCTURE node_data,0
	STRUCT	nd_alphadata,58
	WORD	nd_filetype
	WORD	nd_showit
	WORD	nd_textcolor
	WORD	nd_namelength
	ULONG	nd_filesize
	ULONG	nd_days
	ULONG	nd_minutes
	ULONG	nd_ticks
	LABEL	nd_SIZEOF

	STRUCTURE file_node,0
	STRUCT	fn_Node,MLN_SIZE
	APTR	fn_info
	WORD	fn_idnum
	LABEL	fn_SIZEOF

	STRUCTURE dev_node,0
	STRUCT	dn_Node,MLN_SIZE
	STRUCT	dn_name,32
	LABEL	dn_SIZEOF

	XREF	_AlphaGad
	XREF	_ColonStr
	XREF	_CurDevNames
	XREF	_DevGads
	XREF	_devList
	XREF	_DevTxts
	XREF	_DOSBase
	XREF	_EmptyPattern
	XREF	_FileUndoBuffer
	XREF	_FileUndoName
	XREF	_fnList
	XREF	_fsbaddatestr
	XREF	_FSCountDown
	XREF	_fscurmicros
	XREF	_fscursecs
	XREF	_fsdatefmtstr
	XREF	_fsdayspermonth
	XREF	_FSDirFmtStr
	XREF	_fsdirlocked
	XREF	_FSDone
	XREF	_FSDownGad
	XREF	_fserrmsgs
	XREF	_FSFib
	XREF	_FSFileGad
	XREF	_FSFileInfo
	XREF	_FSFileNodes
	XREF	_fsflags
	XREF	_FSIgnorePat
	XREF	_FSInfo
	XREF	_FSLock
	XREF	_fsneedshow
	XREF	_FSNextDevs
	XREF	_fsnumentries
	XREF	_fsoldmicros
	XREF	_fsoldsecs
	XREF	_FSPathBuf
	XREF	_FSPathGad
	XREF	_FSPathInfo
	XREF	_FSPatternGad
	XREF	_FSPatternInfo
	XREF	_FSPatternUndoBuffer
	XREF	_FSPrevDevs
	XREF	_fsprevgadid
	XREF	_FSReq
	XREF	_FSRPort
	XREF	_FSSizeFmtStr
	XREF	_FSSlideGad
	XREF	_FSSlideProp
	XREF	_fsstartedstr
	XREF	_fstempdate
	XREF	_fstitlelength
	XREF	_fstitstatus
	XREF	_FSUndoGad
	XREF	_FSUpGad
	XREF	_FSUserGad
	XREF	_fsvheight
	XREF	_fsvirgindir
	XREF	_fsvposition
	XREF	_FSWin
	XREF	_FSWinTitleStr
	XREF	_FSwstr
	XREF	_GfxBase
	XREF	_IntuitionBase
	XREF	_lastdev
	XREF	_NIL2Gad
	XREF	_OldFSPathBuf
	XREF	_RamDirNameStr
	XREF	_SizeGad
	XREF	_SlashStr
	XREF	_TimeGad
	XREF	_topfin

	XREF	_sprintf
	XREF	_FSVBDelay

	IFD	BENCHMARK
	XREF	_StartTime
	XREF	_StopTime
	XREF	_timermsg1
	ENDC
	
	XLVO	ActivateGadget
	XLVO	AddHead
	XLVO	AddTail
	XLVO	AllocMem
	XLVO	ClipBlit
	XLVO	DisplayBeep
	XLVO	DoubleClick
	XLVO	Examine
	XLVO	ExNext
	XLVO	FreeMem
	XLVO	GetMsg
	XLVO	Insert
	XLVO	IoErr
	XLVO	Move
	XLVO	NewModifyProp
	XLVO	ParentDir
	XLVO	RectFill
	XLVO	RefreshGList
	XLVO	RemHead
	XLVO	ReplyMsg
	XLVO	SetAPen
	XLVO	SetDrMd
	XLVO	SetWindowTitles
	XLVO	Text
	XLVO	UnLock

	SECTION	CODE
* ------------------------------------------------------------------------
; LONG MyActivateGad(gadget, window)
;   struct Gadget *gadget;
;   struct Window *window;
;   
; Activate a gadget, wait till it is ready.  Try up to 3 times.  Returns
; TRUE (1) if it succeeded, FALSE (0) if it failed to activate.
* ------------------------------------------------------------------------
	XDEF	_MyActivateGad
_MyActivateGad:
	movem.l	d2/a2/a6,-(sp)
	moveq	#2,d2			;Try 3 times to activate gadget

1$	movem.l	16(sp),a0/a1		;Grab gadget pointer, window pointer
	suba.l	a2,a2			;No requester pointer
	movea.l	_IntuitionBase,a6
	jsr	_LVOActivateGadget(a6)	;Activate!
	tst.l	d0			;Did it catch?
	 bne.s	2$			;Yep, move on

	pea	5
	jsr	_FSVBDelay
	addq.w	#4,sp
	dbf	d2,1$
2$
	movem.l	(sp)+,d2/a2/a6
	rts

* --------------------------------------------------------------------- *
* LONG FSCheckFlagChange(VOID);
* --------------------------------------------------------------------- *
	XDEF	_FSCheckFlagChange
_FSCheckFlagChange:

	movea.l	_FSReq,a0
	move.w	fs_flags(a0),d0
	move.w	_fsflags,d1
	andi.w	#%00011000,d0
	andi.w	#%00011000,d1
	cmp.w	d0,d1			;FS_SHOW_FILES_FIRST or FS_SHOW_DIRS_FIRST changed?
	 beq.s	1$			;Nope
	move.w	#1,_fsvirgindir	;Else we need to re-read the directory
1$
	move.w	fs_flags(a0),d0
	move.w	_fsflags,d1
	andi.w	#%01100000,d0
	andi.w	#%01100000,d1
	cmp.w	d0,d1			;FS_SHOW_FILES_ONLY or FS_SHOW_DIRS_ONLY changed?
	 beq.s	2$			;Nope
	moveq	#1,d0			;Else flag that we need to FSMatchPattern()
	bra.s	3$
2$
	moveq	#0,d0
3$
	move.w	fs_flags(a0),_fsflags ;Reset flags to match FSReq now
	rts

* ------------------------------------------------------------------------
; Assign device name texts to intuitexts in the 4 Device Gadgets
* ------------------------------------------------------------------------
	XDEF	_SetDevGads
_SetDevGads:
	movem.l	d3-d4/a2-a3/a5,-(sp)

;for (i = 0, tnode = lastdev; i < 4;)
	moveq	#0,d4			;d4 = i = 0
	movea.l	_lastdev,a2		;a2 = tnode = lastdev
	move.l	a2,d3			;Copy for comparison
	lea	_CurDevNames,a3	;a3 = &CurDevNames[0]
	lea	_DevTxts,a5		;a5 = &DevTxts[0]

1$
	lea	dn_name(a2),a1
	move.l	a1,0(a3,d4.w)		;CurDevNames[i] = tnode->name

	moveq	#4,d0
	move.l	0(a5,d4.w),a0
	movea.l	it_IText(a0),a0
	jsr	astrncpy		;astrncpy (DevTxts[i]->IText, tnode->name, 4)

	addq.w	#4,d4			;i++

	movea.l	dn_Node+MLN_SUCC(a2),a2	;tnode = tnode->dn_Node.mln_Succ
	tst.l	dn_Node+MLN_SUCC(a2)	;if (tnode->dn_Node.mln_Succ == 0)
	 bne.s	2$			;Nope
	movea.l	_devList,a2
	movea.l	MLH_HEAD(a2),a2		;Else start the listing over at the start
2$
	cmpa.l	d3,a2			;Have we already shown this node?
	 beq.s	3$			;Yep, disable the rest

	cmpi.w	#16,d4			;Set all 4 Device gadgets yet?
	 bcs	1$			;Nope, do next

3$
* Disable any leftover gadgets
;for (; i < 4; i++)
	lea	_DevGads,a0
	bra.s	5$

4$	movea.l	0(a0,d4.w),a1
	bset.b	#0,gg_Flags(a1)		;DevGads[i]->Flags |= GADGDISABLED
	addq.w	#4,d4

5$	cmpi.w	#16,d4
	 bcs	4$

	movem.l	(sp)+,d3-d4/a2-a3/a5
	rts

* ------------------------------------------------------------------------
; FSScrollDevGads(direction)
;   WORD direction;
* ------------------------------------------------------------------------
	XDEF	_FSScrollDevGads
_FSScrollDevGads:
	movem.l	a2/a6,-(sp)

	movea.l	_lastdev,a0
	tst.w	12+2(sp)		;Grab scroll direction
	 beq.s	1$			;If zero, scroll to next

* Bump list pointer one direction or the other
	move.l	dn_Node+MLN_SUCC(a0),a0	;Get successor
	tst.l	dn_Node+MLN_SUCC(a0)	;EndoList?
	 bne.s	2$			;Nope
	movea.l _devList,a0
	movea.l	MLH_HEAD(a0),a0		;Else lastdev = devList->lh_Head
	bra.s	2$
1$
	movea.l	dn_Node+MLN_PRED(a0),a0 ;Else, lastdev = lastdev->next
	tst.l	dn_Node+MLN_PRED(a0)	;Endolist?
	 bne.s	2$
	movea.l _devList,a0
	movea.l	MLH_TAILPRED(a0),a0	;Else lastdev = devList->lh_TailPred
2$
	move.l	a0,_lastdev
	jsr	_SetDevGads		;Set the gadget text fields

* Refresh gadget texts
;RefreshGList(&NIL2Gad, FSWin, 0L, 4L);
	moveq	#4,d0
	suba.l	a2,a2
	movea.l	_FSWin,a1
	lea	_NIL2Gad,a0
	SYS	RefreshGList,_IntuitionBase

	movem.l	(sp)+,a2/a6
	rts

* ------------------------------------------------------------------------
; CheckFSArrows()
;  See if the Up or Down arrow gadgets are currently activated, scroll
; the file display area or device gadget list if so.
* ------------------------------------------------------------------------
	XDEF	_CheckFSArrows
_CheckFSArrows:
	subq.w	#1,_FSCountDown
	 bge.s	12$

	btst.b	#7,_FSUpGad+gg_Flags+1	;FSUpGad.Flags & SELECTED?
	 beq.s	2$			;Nope, maybe FSDownGad
	pea	1			;Otherwise scroll filegadgets up
	bra.s	3$

2$	btst.b	#7,_FSDownGad+gg_Flags+1 	;FSDownGad.Flags & SELECTED?
	 beq.s	4$			;Nope, maybe slide gadget is selected
	pea	0			;Otherwise scroll filegadgets down

3$	jsr	_FSScrollFileGads
	addq.w	#4,sp
	move.w	#0,_FSCountDown	;Set timer to wake up in .02 secs.
	bra.s	12$

4$	btst.b	#7,_FSSlideGad+gg_Flags+1	;FSSlideGad.Flags & SELECTED?
	 beq.s	5$			;Nope, maybe UpDev
	jsr	_FSDoSlideGadget	;Process slide gadget motion
	move.w	#0,_FSCountDown	;Set timer to wake up in .02 secs.
	bra.s	12$

5$	btst.b	#7,_FSPrevDevs+gg_Flags+1	;FSPrevDevs.Flags & SELECTED?
	 beq.s	7$			;Nope, maybe DownDev
	pea	1			;Otherwise FSScrollDevGads(1);
6$	jsr	_FSScrollDevGads
	addq.w	#4,sp
	move.w	#1,_FSCountDown	;Set timer to wake up in .16 secs.
	bra.s	12$

7$	btst.b	#7,_FSNextDevs+gg_Flags+1	;FSNextDevs.Flags & SELECTED?
	 beq.s	10$			;Nope, nothing of interest, slow down
	pea	0			;Else FSScrollDevGads(0);
	bra	6$

10$
	move.w	#4,_FSCountDown
12$
	rts

* ------------------------------------------------------------------------
; BYTE *FibFileDate(fib_date)
;   struct DateStamp *fib_date;
;
;   Calculate date based on DateStamp structure and return a pointer
; to the formatted date text.
* ------------------------------------------------------------------------
	XDEF	_FibFileDate
_FibFileDate:
	link	a5,#0
	movem.l	d3-d7,-(sp)

	movea.l	8(a5),a1		;Grab datestamp pointer
	moveq	#78,d7			;Initial year = 1978
	
	move.l	(a1),d5			;days = fib_date->ds_Days
	 blt	ffdbaddate		;Hey! you can't be negative! Invalid date...

* Determine what year it is
	divu	#1461,d5
	move.l	d5,d0			;Stash it
	ext.l	d5
	lsl.l	#2,d5
	add.l	d5,d7			;year += (days / 1461) * 4

* Count how many months into that year
ffdgetmo:
	swap	d0
	moveq	#0,d5
	move.w	d0,d5			;days %= 1461

1$	tst.w	d5			;Out of days yet?
	 beq.s	3$			;Yep, done here

	move.w	#365,d6			;Else month_days = 365
	move.w	d7,d0			;Grab year
	andi.w	#3,d0			;if (year & 3) == 0 Leap year?
	 bne.s	2$			;Nope
	addq.w	#1,d6			;Otherwise bump month_days

2$	cmp.w	d6,d5			;is day < month_days?
	 bcs.s	3$			;yep, done here
	sub.w	d6,d5			;otherwise day -= month_days

	addq.l	#1,d7			; year++
	bra	1$
3$

* Count how many days into that month of that year
ffdgetday:
;for (i = 0, day++; i < 12; i++)
	moveq	#0,d4			;current month = 0
	moveq	#0,d6			;Zap hinybs
	addq.w	#1,d5
	lea	_fsdayspermonth,a0

1$	move.b	0(a0,d4.w),d6		;month_days = _fsdayspermonth[i]

	cmpi.w	#1,d4			;if (i == 1 && (year & 3) == 0)
	 bne.s	2$
	move.w	d7,d0
	andi.w	#3,d0
	 bne.s	2$
	addq.w	#1,d6			;month_days++

2$	cmp.w	d6,d5			;if (day <= month_days)
	 ble.s	4$			;Break out, found the right month

	sub.w	d6,d5			;Else, day -= month_days

	addq.w	#1,d4			;i++
3$	cmpi.w	#12,d4			;Done all months yet?
	 bcs	1$			;Nope

4$
ffdprint:
1$	cmpi.l	#99,d7			;while (year >= 100)
	 ble.s	2$
	subi.l	#100,d7			;year -= 100
	bra	1$
2$
;sprintf(_fstempdate, "%02ld-%02ld-%02ld %02ld:%02ld:%02ld", year, i + 1, day, hour, min, sec)
	move.l	8(a1),d0		;sec = fib_date->ds_Tick / 50;
	divu.w	#50,d0
	ext.l	d0
	move.l	d0,-(sp)		;Push secs

	moveq	#0,d0			;Zap reg
	move.w	6(a1),d0		;min = fib_date->ds_Minute
	move.w	d0,d1			;Clone it
	divu	#60,d0
	move.w	d0,d3			;hour = min / 60
	ext.l	d3
	mulu	#60,d0
	sub.w	d0,d1			;min -= hour * 60
	ext.l	d1
	move.l	d1,-(sp)		;Push mins

	move.l	d3,-(sp)		;Push hours
	move.l	d5,-(sp)		;Push day of month
	addq.w	#1,d4			;Push month (offset by 1!)
	move.l	d4,-(sp)
	move.l	d7,-(sp)		;Push year
	pea	_fsdatefmtstr	;Push the format pattern
	pea	_fstempdate		;Push destination buffer
	jsr	_sprintf	
	lea	32(sp),sp
	lea	_fstempdate,a0
	move.l	a0,d0			;return((BYTE *)&_fstempdate[0])

ffddone:
	movem.l	(sp)+,d3-d7
	unlk	a5
	rts

ffdbaddate:
	lea	_fsbaddatestr,a0
	move.l	a0,d0			;return (" <Invalid Date> ")
	bra	ffddone

* --------------------------------------------------------------------- *
	XDEF	_FSSetKnobHeight
_FSSetKnobHeight:
;vheight = (ULONG)( 655350L / (long)fsnumentries );
	move.w	_fsnumentries,d1
	cmpi.w	#10,d1
	 bhi.s	1$
	move.w	#$ffff,_fsvheight
	rts
1$
	move.l	#655350,d0	
	divu	d1,d0
	move.w	d0,_fsvheight
3$
	rts

* --------------------------------------------------------------------- *
	XDEF	_FSSetKnobPos
_FSSetKnobPos:
	movea.l	_topfin,a0
	moveq	#0,d0
	move.w	fn_idnum(a0),d0
	swap	d0
	move.w	_fsnumentries,d1
	subi.w	#10,d1
	 bhi.s	1$
	moveq	#0,d0
	bra.s	2$
1$
	divu	d1,d0
	 bvc.s	2$
	move.w	#$ffff,d0
2$
	move.w	d0,_fsvposition
	rts

* --------------------------------------------------------------------- *
	XDEF	_FSResetKnob
_FSResetKnob:
	jsr	_FSSetKnobHeight
	jsr	_FSSetKnob
	rts

* ------------------------------------------------------------------------
; FSSetKnob()
;  Call ModifyProp() to actually update slide image in window.
* ------------------------------------------------------------------------
	XDEF	_FSSetKnob
_FSSetKnob:
	movem.l	d2-d5/a2/a6,-(sp)

;NewModifyProp(&FSSlideGad, FSWin, 0L, AUTOKNOB|FREEVERT|PROPB, 0L, vposition, 0xffffL, vheight, 1L)
	lea	_FSSlideGad,a0
	movea.l	_FSWin,a1
	suba.l	a2,a2
	moveq	#AUTOKNOB!FREEVERT!PROPBORDERLESS,d0
	moveq	#0,d1
	moveq	#0,d2
	move.w	_fsvposition,d2
	move.l	#$ffff,d3
	moveq	#0,d4
	move.w	_fsvheight,d4
	moveq	#1,d5
	SYS	NewModifyProp,_IntuitionBase

	movem.l	(sp)+,d2-d5/a2/a6
	rts

* ------------------------------------------------------------------------
; FSEnableFGad(gadg_num)
;  LONG gadg_num;
;
; Given a file gadget number, refresh the text for that entry.
* ------------------------------------------------------------------------
	XDEF	_FSEnableFGad
_FSEnableFGad:
	movem.l	a2-a3/a6,-(sp)

	movea.l	_FSRPort,a2

	move.w  4+4*3+2(sp),d0		;Grab gadget number
	move.w	d0,d1			;Copy
	lsl.w	#2,d0			;Conver to long offset
	lea	_FSFileNodes,a0
	movea.l	0(a0,d0.w),a0		;tnode = FSFileNodes[gadg_num]
	movea.l	fn_info(a0),a3		;a3 = tnode->info

* Move to the right slot text position
	mulu	#11,d1
	addi.w	#19,d1
	moveq	#9,d0
	movea.l	a2,a1
	SYS	Move,_GfxBase	;Move(FSRPort, 9, gadnum*11+19)

* Set the pen color according to the node
	move.w	nd_textcolor(a3),d0
	movea.l	a2,a1
	SYS	SetAPen			;SetAPen(FSRPort, tinfo->textcolor)

* Blast out the text
	moveq	#56,d0
	lea	nd_alphadata(a3),a0
	movea.l	a2,a1
	SYS	Text			;Text(FSRPort, tinfo->alphadata, 56)

	movem.l	(sp)+,a2-a3/a6
	rts

* ------------------------------------------------------------------------
; FSDisableFGad(gadg_num)
;  LONG gadg_num;
;
; Given a file gadget number, fill that slot with the EmptyPattern
; and clear the FileNode[] slot for that gadget.
* ------------------------------------------------------------------------
	XDEF	_FSDisableFGad
_FSDisableFGad:
	movem.l	d2-d4/a2/a6,-(sp)

	move.w	4*5+4+2(sp),d4		;Grab gadget number

	movea.l	_FSRPort,a2

	lea	_EmptyPattern,a0
	move.l	a0,rp_AreaPtrn(a2)	;rp->AreaPtrn = EmptyPattern
	move.b	#1,rp_AreaPtSz(a2)	;rp->AreaPtSz = (BYTE)1

	movea.l	a2,a1
	moveq	#2,d0
	SYS	SetAPen,_GfxBase 	;SetAPen(rp, 2)

	move.w	d4,d1
	mulu	#11,d1
	addi.w	#13,d1			;miny = 13L + (gadg_num * 11)

	move.l	d1,d3
	addq.w	#7,d3			;maxy = miny + 7L

	movea.l	a2,a1			;FSWin->RPort
	moveq	#9,d0			;minx
	move.l	#456,d2			;maxx
	SYS	RectFill		;RectFill(rp, minx, miny, maxx, maxy)

	clr.l	rp_AreaPtrn(a2)		;rp->AreaPtrn = 0L
	clr.b	rp_AreaPtSz(a2)		;rp->AreaPtSz = (BYTE)0

	move.w	d4,d0
	lsl.w	#2,d0
	lea	_FSFileNodes,a0
	clr.l	0(a0,d0.w)		;FSFileNodes[gadg_num] = 0L

	movem.l	(sp)+,d2-d4/a2/a6
	rts

* --------------------------------------------------------------------- *
	XDEF	_FSDisableAllFGads
_FSDisableAllFGads:
	move.l	d2,-(sp)

	moveq	#0,d2
	move.w	_fsnumentries,d2
	bra.s	2$
1$	move.l	d2,-(sp)
	jsr	_FSDisableFGad		;FSDisableFGad(i)
	addq.w	#4,sp
	addq.w	#1,d2			;i++
2$	cmpi.w	#10,d2			;Hit 10 entries?
	 bcs	1$			;Nope, disable one
	move.l	(sp)+,d2
	rts

* ------------------------------------------------------------------------
;struct file_node *AllocFileNode()
;
;  Allocate a file_node structure and it's info block, return pointer
; to the file_node or NULL if allocation failed.
* ------------------------------------------------------------------------
	XDEF	_AllocFileNode
_AllocFileNode:
	move.l	a6,-(sp)

	moveq	#fn_SIZEOF+nd_SIZEOF,d0	;sizeof(struct file_node)+sizeof(struct node_data)
	move.l	#MEMF_CLEAR,d1		;MEMF_CLEAR
	SYS	AllocMem,4		;Allocate file node structure
	move.l	d0,d1
	 beq.s	1$
	movea.l	d0,a0
        addi.l	#fn_SIZEOF,d1
	move.l	d1,fn_info(a0)		;Set pointer to tnode->info area
1$
	movea.l	(sp)+,a6
	rts

* ------------------------------------------------------------------------
; FreeFileNode(tnode)
;  struct file_node *tnode;
;
;  Given a pointer to a file_node, Free the memory allocated for that node.
* ------------------------------------------------------------------------
	XDEF	_FreeFileNode
_FreeFileNode:
	move.l	a6,-(sp)

	move.l	4+4(sp),d0		;Grab tnode
	 beq.s	2$			;Nope, get outta here
	movea.l	d0,a1
	moveq	#fn_SIZEOF+nd_SIZEOF,d0
	SYS	FreeMem,4		;FreeMem(tnode, sizeof(struct file_node)+sizeof(struct node_data))

2$	movea.l	(sp)+,a6
	rts
	

* ------------------------------------------------------------------------
; FreeAllFNodes()
;
;  Call FreeFileNode for each node in the linked list of file_nodes,
;then deallocate the head of the list (fnList)
* ------------------------------------------------------------------------
	XDEF	_FreeAllFNodes
_FreeAllFNodes:
	movem.l	a2/a6,-(sp)

	move.l	_fnList,d0		;Is there a list?
	 beq.s	2$			;Nope, get outta here

	movea.l	d0,a2			;Grab head
	movea.l	4,a6			;Set for ExecBase
1$
	movea.l	a2,a0
	SYS	RemHead			;d0 = RemHead(fnList)
	tst.l	d0			;Hit end?
	 beq.s	2$			;yep

	move.l	d0,-(sp)
	jsr	_FreeFileNode		;Free the node
	addq.w	#4,sp
	bra	1$			;Remove next node

2$
* Reset other globals
	clr.w	_fsvposition	;Set slider position to top of area
	move.w	#$ffff,_fsvheight	;Max height
	clr.w	_fsnumentries	;Zero entries

	movem.l	(sp)+,a2/a6
	rts

* ------------------------------------------------------------------------
;struct dev_node *AllocDevNode()
;
;  Allocate a dev_node, return pointer to same
* ------------------------------------------------------------------------
	XDEF	_AllocDevNode
_AllocDevNode:
	move.l	a6,-(sp)

	moveq	#dn_SIZEOF,d0
	move.l	#MEMF_CLEAR,d1
	SYS	AllocMem,4		;AllocMem(sizeof(struct dev_node), MEMF_CLEAR)
	
	movea.l	(sp)+,a6
	rts

* ------------------------------------------------------------------------
;FreeDevNode(tnode)
;  struct dev_node *tnode;
;
;  Given a pointer to a dev_node, free memory allocated for that node.
* ------------------------------------------------------------------------
	XDEF	_FreeDevNode
_FreeDevNode:
	move.l	a6,-(sp)

	move.l	4+4(sp),d0		;Grab dev_node to free
	 beq.s	1$			;Oops, nothing here

	movea.l	d0,a1
	moveq	#dn_SIZEOF,d0
	SYS	FreeMem,4		;FreeMem(tnode, (long)sizeof(struct dev_node))

1$
	movea.l	(sp)+,a6
	rts


* ------------------------------------------------------------------------
;FreeAllDNodes()
;
;  Call FreeDevNode() for each dev_node in the linked list, then free the
; head of the list, devList.
* ------------------------------------------------------------------------
	XDEF	_FreeAllDNodes
_FreeAllDNodes:
	movem.l	a2/a6,-(sp)

	move.l	_devList,d0		;Is there a head node?
	 beq.s	3$			;Nope, don't deallocate

	movea.l	d0,a2			;Grab head of device list
	movea.l	4,a6			;Set for execbase

1$	movea.l	a2,a0
	SYS	RemHead			;d0 = RemHead(devList)
	tst.l	d0			;Got one?
	 beq.s	2$			;Nope, list is empty

	move.l	d0,-(sp)
	jsr	_FreeDevNode		;Free this device node
	addq.w	#4,sp
	bra	1$

2$	movea.l	a2,a1
	moveq	#MLH_SIZE,d0
	SYS	FreeMem			;FreeMem(devList, sizeof(MinList))
	clr.l	_devList

3$	movem.l	(sp)+,a2/a6
	rts

* ------------------------------------------------------------------------
; FreeFileSelect()
;   Deallocate filenames and fileinfoblocks, unlock any locks
* ------------------------------------------------------------------------
	XDEF	_FreeFileSelect
_FreeFileSelect:
	move.l	a6,-(sp)
	move.w	#1,_fsvirgindir	;virgindir = 1
	jsr	_FreeAllFNodes		;Free all allocated filenames
	jsr	_FSClearLock		;Unlock any locks

* Free the head node itself
	move.l	_fnList,d0
	 beq.s	1$
	movea.l	d0,a1
	moveq	#MLH_SIZE,d0
	SYS	FreeMem,4		;FreeMem(fnList, sizeof(MinList))
	clr.l	_fnList		;And clear the pointer
1$
* Free the global FileInfoBlock and InfoData struct
	move.l	_FSFib,d0		;Do we have a FileInfoBlock allocated?
	 beq.s	2$			;Nope
	movea.l	d0,a1
	move.l	#fib_SIZEOF+id_SIZEOF,d0
	SYS	FreeMem,4		;FreeMem(FSFib, 300L)
	clr.l	_FSFib		;Set to NULL so we don't re-free it
	clr.l	_FSInfo
2$
	movea.l	(sp)+,a6
	rts

* --------------------------------------------------------------------- *
* Cleanup function for fileselect
* --------------------------------------------------------------------- *
	XDEF	_ReleaseFileSelect
_ReleaseFileSelect:
	jsr	_FreeFileSelect
	jsr	_FreeAllDNodes
	rts

* ------------------------------------------------------------------------
; LONG FSGetNextFib(VOID)
;
;  Call ExNext() to fill in next FileInfoBlock, set titlebar to reflect
; status of the request.
* ------------------------------------------------------------------------
	XDEF	_FSGetNextFib
_FSGetNextFib:
	movem.l	d2/a6,-(sp)

* Try to get next fileinfoblock from dos
	move.l	_FSLock,d1
	move.l	_FSFib,d2
	SYS	ExNext,_DOSBase
	tst.l	d0			;Did we get an entry?
	 bne.s	gnfgot1			;Yep, got it

* Didn't get one, find out why
;if ( (error = IoErr()) != ERROR_NO_MORE_ENTRIES)
	SYS	IoErr			;Get error number
	cmpi.l	#232,d0			;No more entries?
	 beq.s	gnfnme			;Yep

	move.l	d0,-(sp)
	jsr	_ioerrnum		;Otherwise set window title to error number
	addq.w	#4,sp
	move.w	d0,_fstitstatus
	moveq	#-1,d2			;Return bad get status
	bra.s	gnfsetwintit

gnfnme:
	moveq	#0,d2			;Return DONE!
	tst.w	_fsnumentries	;Got any valid pattern matches?
	 bne.s	gnfselect		;Yep, select a file time

	movea.l	_fnList,a6
	movea.l	MLH_HEAD(a6),a6
	tst.l	fn_Node+MLN_SUCC(a6) 	;Do we have any files?
	 beq.s	gnfnoentry		;Nope, no entries

	move.w	#24,_fstitstatus	;Otherwise no match
	bra.s	gnfsetwintit

gnfnoentry:
	move.w	#22,_fstitstatus	;No Entries...
	bra.s	gnfsetwintit

gnfselect:
	move.w	#29,_fstitstatus	;Select a file...

gnfsetwintit:
	bra.s	gnfdone

gnfgot1:
	moveq	#1,d2

gnfdone:
	move.l	d2,d0
	movem.l	(sp)+,d2/a6
	rts

* ------------------------------------------------------------------------
;AllocFSFib()
;Allocate a fileinfoblock, return status
* ------------------------------------------------------------------------
	XDEF	_AllocFSFib
_AllocFSFib:
	move.l	a6,-(sp)
	tst.l	_FSFib		;Do we already have a fib?
	 bne.s	1$			;Yep, get out of here

;FSFib = AllocMem(sizeof(*FSFib) + sizeof(*FSInfo), MEMF_CLEAR);
	move.l	#fib_SIZEOF+id_SIZEOF,d0
	move.l	#MEMF_CLEAR,d1
	SYS	AllocMem,4
	move.l	d0,_FSFib
	 beq.s	2$			;Oops, allocation failed, return 0

	addi.l	#fib_SIZEOF,d0
	move.l	d0,_FSInfo		;Set pointer to InfoData struct too

1$	moveq	#1,d0			;Return good status

2$	movea.l	(sp)+,a6
	rts

* ------------------------------------------------------------------------
;LONG ioerrnum(num)
;  LONG num;
;
; Given an IoErr n--------------------------------------------
* VOID FSDoSlideGadget(VOID)
*
*  Process the current slide gadget position, scroll file entries
* to match current position.
* ------------------------------------------------------------------------
	XDEF	_FSDoSlideGadget
_FSDoSlideGadget:
	movem.l	d4-d5,-(sp)

	jsr	_FSUpdateSort
	 beq	dsgdone

	cmpi.w	#10,_fsnumentries	;Do we have less than 10 entries?
	 blt	dsgdone			;Yep, can't move anyhow

	moveq	#0,d0
	move.w	_FSSlideProp+4,d0	;Grab new vpot
	cmp.w	_fsvposition,d0 	;Has it moved?
	 beq	dsgdone			;Nope

	move.w d0,_fsvposition 	;Otherwise update position

	move.w	_fsnumentries,d4	;Grab number of entries
	subi.w	#10,d4			;Less max number of visible files
	mulu	d0,d4			;Times position percentage
	addi.l	#32768,d4
	clr.w	d4
	swap	d4

	movea.l	_topfin,a0		;Grab top node
	cmp.w	fn_idnum(a0),d4		;Is node->idnum the same as newpos?
	 beq.s	dsgdone			;Yep, don't have to move it
	 bcc.s	dsgscrup		;newpos is lower, scroll up

**************
* Scroll Down
**************
	move.w	fn_idnum(a0),d0		;Grab topfin->idnum
	sub.w	d4,d0			;i = idnum - newpos
	cmpi.w	#8,d0			;Need to scroll more than 8?
	 ble.s	dsgssdwn		;Nope, use slow scroll

dsgdwn1:
	cmp.w	fn_idnum(a0),d4		;Is topfin->idnum == newpos yet?
	 beq.s	dsgredo			;Yep, we are done

dsgpretop:
	movea.l	fn_Node+MLN_PRED(a0),a0	;topfin = topfin->fn_Node.mln_Pred
	tst.w	fn_idnum(a0)		;Is this idnum >= 0?
	 blt.s	dsgpretop		;Nope, keep looking
	bra.s	dsgdwn1			;Check this new position

dsgssdwn:
	move.l	d0,-(sp)
	jsr	_FSScrollDownGads	;Scroll entries down d5 times
	addq.w	#4,sp
	bra.s	dsgdone

************
* Scroll Up
************
dsgscrup:
	move.w	d4,d5			;Grab newpos
	sub.w	fn_idnum(a0),d5		;i = newpos - node->idnum
	cmpi.w	#8,d5			;i > 8?
	 ble.s	dsgssup			;Nope, use slow scroll

dsgmvup1:
	cmp.w	fn_idnum(a0),d4		;Is topfin->idnum == newpos yet?
	 beq.s	dsgredo			;Yep, we are done

dsgnxttop:
	movea.l	fn_Node+MLN_SUCC(a0),a0	;topfin = topfin->fn_Node.mln_Succ
	tst.w	fn_idnum(a0)		;Is this a valid entry?
	 blt.s	dsgnxttop		;Nope, move on
	bra.s	dsgmvup1

dsgredo:
	move.l	a0,_topfin		;Set new top and bottom
	jsr	_FSSetFileGads		;Redraw all the file entries
	bra.s	dsgdone			;We're done

dsgssup:
	move.l	d5,-(sp)
	jsr	_FSScrollUpGads		;Scroll the entries up d5 times
	addq.w	#4,sp

dsgdone:
	movem.l	(sp)+,d4-d5
	rts

* --------------------------------------------------------------------
* VOID FSStartScrollGad(gadcode)
*   ULONG gadcode;
* Given Gadget ID code, respond to first user click on a arrow gadget.
* Reset the timer.device so that .25 seconds delay occurs before
* the autorepeat kicks in.
* --------------------------------------------------------------------
	XDEF	_FSStartScrollGad
_FSStartScrollGad:
	move.w	6(sp),d0	;Grab gadget code
	subi.w	#33,d0		;Slide gad
	 bne.s	1$
	jsr	_FSDoSlideGadget
	clr.w	_FSCountDown
	rts

1$
	subi.w	#7,d0		;33+7=40, UpGad
	 bne.s	2$
	pea	1
11$	jsr	_FSScrollFileGads
	addq.w	#4,sp
	bra.s	ssgdone
2$
	subq.w	#1,d0		;33+7+1=41, DownGad
	 bne.s	3$
	pea	0
	bra	11$
3$
	subq.w	#1,d0		;33+7+2=42, UpDev
	 bne.s	4$
	pea	1
33$	jsr	_FSScrollDevGads
	addq.w	#4,sp
	bra.s	ssgdone
4$
	subq.w	#1,d0		;33+7+3=43, DownDev
	 bne.s	ssgrts
	pea	0
	bra	33$

ssgdone:
	move.w	#4,_FSCountDown
ssgrts:
	rts

* -----------------------------------------------------------------------
* FSScrollFileGads(direction)
*   BOOL direction;
*
* Scroll the file entries up or down by 1
* if (direction == 0)
*   scrollup;
* else
*   scrolldown;
* -----------------------------------------------------------------------
	XDEF	_FSScrollFileGads
_FSScrollFileGads:

;if (fsnumentries > 10)
	cmpi.w	#10,_fsnumentries	;Less than 10 entries?
	 ble.s	sfgdone			;Yep, can't scroll anyhow

;if (direction)
;  FSScrollDownGads(1);
	tst.w	6(sp)			;ScrollDown?
	 beq.s	sfgup			;Nope, scroll up
	pea	1
	jsr	_FSScrollDownGads
	addq.w	#4,sp
	bra.s	sfgpos

sfgup:
;FSScrollUpGads(1)
	pea	1
	jsr	_FSScrollUpGads
	addq.w	#4,sp

sfgpos:
* Reset the slide knob position the display movement
	jsr	_FSSetKnobPos
	jsr	_FSSetKnob		;Set new knob position

sfgdone:
	rts

* -------------------------------------------------------------------------
; FSScrollUpGads(count)
;  LONG count;
;
;  Single-step scroll the file entries up count times.
* -------------------------------------------------------------------------
	XDEF	_FSScrollUpGads
_FSScrollUpGads:
	link	a5,#0
	movem.l	d2-d7/a2/a6,-(sp)

	jsr	_FSUpdateSort
	 beq.s	sugdone

	movea.l	_FSRPort,a2

;for (i = 0; i < count; i++)
	moveq	#0,d7
	bra.s	sugchk1

sugloop1:
* If the bottom entry is not the last entry, scroll it up
	movea.l	_topfin,a0		;Grab top visible node
	move.w	fn_idnum(a0),d0		;Grab id number
	addi.w	#11,d0			;Plus 11
	cmp.w	_fsnumentries,d0	;Compare to last known entry
	 bgt.s	sugdone			;Yep, can't scroll up any more

* Bump the top pointer down the list to the next visible entry
	movea.l	_topfin,a0
1$	move.l	fn_Node+MLN_SUCC(a0),a0	;topfin = topfin->fn_Node.mln_Succ
	tst.w	fn_idnum(a0)		;while (topfin->idnum < 0)
	 blt	1$			;Not a valid entry
	move.l	a0,_topfin		;Here's our new top entry node

* Now reassign the visible file gadget array to the new node list
	jsr	_FSAssignNodes

* Display new file entries and redraw borders
;ClipBlit(rp, 9L, 24L, rp, 9L, 13L, 447L, 96L, 0xc0L);
	movea.l	a2,a0
	moveq	#9,d0
	moveq	#24,d1
	movea.l	a2,a1
	moveq	#9,d2
	moveq	#13,d3notcancel		;Nope
	move.w	#1,_FSDone		;Global signal that we're done
	movea.l	_FSReq,a0		;a0 = fsreq
	movea.l	fs_fullname(a0),a0	;a0 = fsreq->fullname
	clr.b	(a0)			;Return filename == ""
	bra	dogaddone

dgnotcancel:
* UndoGad
	cmpi.w	#3,d4			;Undo?
	 bne.s	dgnotundo
	movea.l	_FSPathInfo,a0	;Copy OldFSPathBuf to FSPathInfo.Buffer
	movea.l	_OldFSPathBuf,a1
	jsr	astrcpy			;astrcpy(FSPathInfo.Buffer, OldFSPathBuf)
	bra	dgnewdir		;Process new directory

dgnotundo:
* Dev1Gad
	cmpi.w	#20,d4    .Pcmp    _errno    _fabs    
.Pmul    .Pfix    .Pflt    .Psub    .Padd    .Pdiv    _ldexp  NUH8 &<XbN$<@.9"-  - Nq o3 r "<,qu <CL N]Nu&<I$<#+"-  - Nq l3 r r p `/- /- Ns &<\$<;Nq POl
r  <?  `&<e+$<?G"-  - Nt +A+@Nu 8 JDlSD0D Nv &$ "- -Nw v $<?  Nq mRD0D Nv +A+@v $<?0 "- -Nt &$ "-  - Nw // &<\a$<?+"- -Nt &$  "Nx +A +@ &- $- "-  - Nt +A+@&<*$<? D"- -Nt &<*$<?KNx &-$-Nt v $<?  Nx &- $- Nt +A +@ &<V$<>3c"- -Nt &<\($<?DNx &-$-Nt &<Q$<?(Nx &-$-Nt v $<?  Nx &- $- Nw &$ "-  - Ny v $<?  Nx +A +@ 0R@? /- /- Nz O 
`  CJfabs                    	       .Pabs   _fabs   L  Np     CJflt68                 & 	 &     _errno   .Pfix  \.Pflt  |.Pcmp  .Ptst  .Pabs .Pneg 0.Psub 6.Padd V.Pmul .Pdiv    H` $ [HBJBBk0B n.DB    HHAIAA"kJL NuD`p ` <"jD < `JgH [nDr xNL Nur NuHx ( HDDfp r (HDDft v $k(  kmne
bp L NupL NupL Nu  jC`" HAAg$  jpNupNu/ H@@g
 NuXr p Nu/ H@@g 
   Nu" HBBfr p L  Nu
   H| ~ ( [HDDgL*[HEEgMDE      FHE:< ,HFNF     ,HFNFHE,EgznBCEG DED 7kt v `^D kND  k$D  &g& C t `>&*魺ft `.?*,鮼g C <*DDD  魆`
SDQ(Gnm҃тdRD`BC,d@D@NLNup r LNuH( [HDDg*[HEEg     ELD D"Fz,HFNF     ,HFNF~ $B$v x z | JBg6 gHC<& HCJCg܃HBJBg.&HCJCg
BCHC܃G6 g܃G& HCHFCHFBCHCۃ$
JBg86g
BCHC܃ۇ&HCJCg܃ۇ6 gHFCHFBCHCۃ& HCڃهHB6g܃ۇهHA6gHFCHFBCHCۃه6 gڃهH@6 HECHEBCHCك  cRIF gc"HFRFHFۇه  cRH`    <HF":HE (,	NJLNuH( [HDDg 4*[HEEg       EDSD0DHFz.HGOG     .HGOGJBf>Jf:HBH@Bgc
H@RHH@H@8 HDHA08 HA0: HEB@:  "`dff <   RHr `PbRH<< x ~㐒k RDQSFg*`*x ~҃тjQSFf "(HFa6LNu3 p a`r Nu3 p r <Jg     < Nu~ Jf
AD  JgkSDl:EE gc   чdRD`:E fz> OHAGHA DkDn |Jg D LH@DH@Nur 3 p  <   Jg    Nu    CJldexp      r             	  1     _errno   _ldexp   _flterr   /L  $ HB  Jo o  n*JHB$Nu3 r 3 p  <é"<,qu$Nu3 r 3 p  <C"<,qu$Nu      t                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               