*-----------------------------------------------------------------------------*
*                   Cr‚ation de la fenˆtre de recherche                       *
*-----------------------------------------------------------------------------*
search_form:save.l a0				; pointeur fenˆtre look
	move.l GWVA_WIND_OBJ_USER_PTR1(a0),a1	; structure look

	lea fenetre_search-fenetre_generale(a0),a0	; pointeur fenˆtre search associ‚e
	move.l a1,GWVA_WIND_OBJ_USER_PTR2(a0)	; structure look dans USER_PTR2
	bsr GWVA_WIND_OBJ_PRG_CREATE_OPEN_ONE_WIND
	load.l a0
	tst d7
	bmi .fenetre_search_pas_ouverte

; Comme les fenˆtres sont toutes des clones, on doit d'abord cr‚er la fenˆtre search
; puis modifier les objets et enfin demander un redraw de la fenˆtre clone

	save.l a0

	move.w #FORM_SEARCH,d0
	move.w #FSCHG_BTON_STOP,d1
	move.w #1,d2		; disable stop
	bsr GWVA_ENABLE_DISABLE_OBJECT

	move.w #FORM_SEARCH,d0
	move.w #FSCH_BTON_SEARCH,d1
	move.w #0,d2		; enable search
	bsr GWVA_ENABLE_DISABLE_OBJECT

	move.l (sp),a0			; a0 : fenetre look

	move.l GWVA_WIND_OBJ_USER_PTR1(a0),a1	; structure look
	move.w #1,d2			; disable continue
	tst.w longueur_chaine_search(a1)		; d‚j… eu une recherche ?
	beq.s .pas_de_continue
	clr.w d2
.pas_de_continue:
	move.w #FORM_SEARCH,d0
	move.w #FSCH_BTON_CONT,d1
	bsr GWVA_ENABLE_DISABLE_OBJECT

	move.l (sp),a0			; a0 : fenetre look

	lea fenetre_search-fenetre_generale(a0),a0
	move.l GWVA_WIND_OBJ_SPEC_PTR(a0),a1
	move.l GWVA_WFORM_OBJ_FORM_PTR(a1),a2
	move.w #FSCH_BTON_SEARCH,d0
	mulu #L_OBJECT,d0
	move.w #FSCH_BTON_CONT,d1
	mulu #L_OBJECT,d1
	btst #DISABLED,ob_state+1(a2,d1.l)	; Continue est-il disponible
	bne.s .pas_de_continue_enable
	bclr #DEFAULT,ob_flags+1(a2,d0.l)
	bset #DEFAULT,ob_flags+1(a2,d1.l)	; on passe l'attribut d‚faut … CONTINUE
	bra.s .defaut_continue
.pas_de_continue_enable:
	bclr #DEFAULT,ob_flags+1(a2,d1.l)
	bset #DEFAULT,ob_flags+1(a2,d0.l)	; on passe l'attribut d‚faut … SEARCH
.defaut_continue:

	load.l a0

	add.w #1,GWVA_WIND_OBJ_TOPABLE_STATE(a0)
	move.l a0,GWVA_WIND_OBJ_USER_PTR1+fenetre_search-fenetre_generale(a0)

	move.l GWVA_WIND_OBJ_USER_PTR1(a0),a1	; structure look
	move.l a0,ad_fenetre_search(a1)
	add.l #fenetre_search-fenetre_generale,ad_fenetre_search(a1)

.fenetre_search_pas_ouverte:
	rts

initialisation_fenetre_search:
	move.l GWVA_WIND_OBJ_USER_PTR2(a0),a1	; structure look
	move.l table_obj(a1),a2

	lea struct_searching_slider-fenetre_search(a0),a3

	move.l source_length(a1),d0
	add.l #8+8-1,d0
	divu.l #8+8,d0
	move.l d0,GWVA_FORM_SLIDER_OBJ_LENGTH(a3)
	move.l offset_fichier(a1),d0
	divu.l #8+8,d0
	move.l d0,GWVA_FORM_SLIDER_OBJ_POS(a3)

	move.w f_num_line(a2),d0
	ext.l d0
	move.l d0,GWVA_FORM_SLIDER_OBJ_SIZE(a3)

	save.l a0-a2
	move.l GWVA_WIND_OBJ_SPEC_PTR(a0),a1
	move.l a3,a2
	bsr GWVA_SLIDER_OBJ_PRG_SET_SLIDER
	load.l a0-a2

	clr.w d7
	rts

*-----------------------------------------------------------------------------*
*                            Bouton Search                                    *
*-----------------------------------------------------------------------------*
search_item:
	save.l a0
	move.w #FORM_SEARCH,d0
	move.w #FSCH_TXT_SEARCH,d1
	bsr RETURN_TEXT_OBJ_IN_FORM_OBJ_PTR		; a1->texte de la recherche
	load.l a0

	move.l a1,a2
.calcul_longeur_chaine:
	tst.b (a2)+
	bne.s .calcul_longeur_chaine
	sub.l a1,a2
	move.w a2,d0
	sub.w #1,d0

	tst.w d0		; longueur nulle -> pas de recherche
	beq cancel_search

	cmp.b #'"',(a1)
	beq.s .chaine_ascii

	cmp.b #"'",(a1)
	bne.s .chaine_hexa

* Traitement chaine ascii
.chaine_ascii:
	sub.w #1,d0		; il doit avoir plus qu'une ouverture de  chaine
	beq cancel_search
	
	move.l GWVA_WIND_OBJ_USER_PTR2(a0),a3	; structure look associ‚e
	lea chaine_search(a3),a2	; stockage de la chaine ascii
	lea 1(a1),a3		; d‚but de la chaine ascii

	COPY_STRING_0 a3,a2

	lea -2(a3),a3
	cmp.b #'"',(a3)
	beq.s .enlever_signe_fin_chaine
	cmp.b #"'",(a3)
	bne.s .longueur_bonne
.enlever_signe_fin_chaine:

	sub.w #1,d0
	beq cancel_search

.longueur_bonne:
	bra .recherche_chaine

* Traitement chaine hexa
.chaine_hexa:
	move.l a1,a2

.bon_digit_hexa:
	move.b (a2)+,d1
	beq.s .fin_de_chaine_hexa

	cmp.b #'0',d1
	blt .bad_hexa
	cmp.b #'9',d1
	ble.s .bon_digit_hexa
	or.b #$20,d1	; majuscules -> minuscules
	cmp.b #'a',d1
	blt .bad_hexa
	cmp.b #'f',d1
	ble.s .bon_digit_hexa

.bad_hexa:	move.w #ALERT_BAD_HEXA,d0
	move.w #1,d1
	bsr RSC_ALERT_BOX

	rts

.fin_de_chaine_hexa:		; il faut changer la chaine hexa en valeur hexa
	move.l GWVA_WIND_OBJ_USER_PTR2(a0),a3	; structure look associ‚
	lea chaine_search(a3),a2
	move.l a1,a3

	btst #0,d0		; longueur impaire ?
	beq.s .paire

; Dans le cas d'une chaine de longueur impaire, le premier chiffre est pris … part
	move.b (a3)+,d1
	sub.b #'0',d1
	cmp.b #9,d1
	ble.s .number1
	or.b #$20,d1
	sub.b #'a'-'0'-$a,d1
.number1:	move.b d1,(a2)+
	add.w #1,d0		; '9' -> 09

.paire:	moveq #0,d1
	moveq #0,d2

.conversion_chaine_hexa:
	move.b (a3)+,d1
	beq.s .fin_conversion

	move.b (a3)+,d2
	sub.b #'0',d1
	sub.b #'0',d2
	cmp.b #9,d1
	ble.s .number2
	or.b #$20,d1
	sub.b #'a'-'0'-$a,d1
.number2:	cmp.b #9,d2
	ble.s .number3
	or.b #$20,d2
	sub.b #'a'-'0'-$a,d2
.number3:	mulu #$10,d1
	add.b d2,d1
	move.b d1,(a2)+
	bra.s .conversion_chaine_hexa
.fin_conversion:
	lsr.w #1,d0

.recherche_chaine:

	move.l GWVA_WIND_OBJ_USER_PTR2(a0),a3	; structure look associ‚e
	move.w d0,longueur_chaine_search(a3)

	move.l source_length(a3),d0	; longueur du fichier
	divu.l #10,d0		; on prend un buffer 10 fois plus petit que la taille du fichier
				; et max de 20 ko pour acc‚lerer la recherche
	cmp.l buffer_length(a3),d0
	bge.s .taille_buf_sup_buf
	move.l buffer_length(a3),d0
.taille_buf_sup_buf:
	cmp.l #20*1024,d0
	ble.s .taille_buf_inf_20ko
	move.l #20*1024,d0
 .taille_buf_inf_20ko:

	move.l d0,buffer_search_length(a3)
	save.l a0/a3
	bsr reserve_buffer
	load.l a0/a3
	tst d7
	bmi cancel_search
	move.l d0,ad_buffer_search(a3)

	move.l pos_curseur(a3),d0
	lsr.l #1,d0
	move.l d0,offset_search_fichier(a3)

continue_search:

	save.l a0/a3

	move.l GWVA_WIND_OBJ_SPEC_PTR(a0),a1
	move.w GWVA_WFORM_OBJ_FORM_IDX(a1),d0
	move.w GWVA_WFORM_OBJ_IS_CLONE_FORM(a1),d1
	move.l GWVA_WFORM_OBJ_CLONE_FORM_SAVE(a1),a0
	bsr GWVA_WFORM_OBJ_PRG_SAVE_FORM		; sauvegarde l'etat du formulaire si OK

	move.w #FORM_SEARCH,d0
	move.w #FSCHG_BTON_STOP,d1
	move.w #0,d2		; enable
	bsr GWVA_ENABLE_DISABLE_OBJECT

	move.w #FORM_SEARCH,d0
	move.w #FSCH_BTON_SEARCH,d1
	move.w #1,d2		; disable
	bsr GWVA_ENABLE_DISABLE_OBJECT

	move.w #FORM_SEARCH,d0
	move.w #FSCH_BTON_CONT,d1
	move.w #1,d2		; disable
	bsr GWVA_ENABLE_DISABLE_OBJECT

	movem.l (sp),a0/a3

	move.w #FSCH_REDRAW,d0
	moveq #3,d1
	moveq #0,d2
	bsr GWVA_FORM_WIND_OBJ_PRG_REDRAW_PART	; n‚cessite a0

	load.l a0/a3

	save.l a3
	move.l a0,d0		; a0 : fenetre de recherche
	clr.l d1			; d0
	move.l #search_in_file_for_a_window,d2	; routine
	move.l #1,d3		; timer
	moveq #0,d4			; priorit‚
	clr d5			; flag
*	bset #GWVA_WIND_THREAD_FLAG_BIT_REAL_TIME,d5
	bsr GWVA_WIND_THREAD_CREATE
	load.l a3

	tst d7
	bmi.s .erreur

	move.w d7,pid_thread_search(a3)
.erreur:
	rts

*-----------------------------------------------------------------------------*
*                            Bouton Continue                                  *
*-----------------------------------------------------------------------------*

continue_search_item:
	move.l GWVA_WIND_OBJ_USER_PTR2(a0),a3	; structure look

	move.l source_length(a3),d0	; longueur du fichier
	divu.l #10,d0		; on prend un buffer 10 fois plus petit que la taille du fichier
				; et max de 20 ko pour acc‚lerer la recherche
	cmp.l buffer_length(a3),d0
	bge.s .taille_buf_sup_buf
	move.l buffer_length(a3),d0
.taille_buf_sup_buf:
	cmp.l #20*1024,d0
	ble.s .taille_buf_inf_20ko
	move.l #20*1024,d0
 .taille_buf_inf_20ko:
	move.l d0,buffer_search_length(a3)
	save.l a0/a3
	bsr reserve_buffer
	load.l a0/a3
	tst d7
	bmi cancel_search
	move.l d0,ad_buffer_search(a3)

	move.l pos_curseur(a3),d0
	lsr.l #1,d0
	add.l #1,d0
	move.l d0,offset_search_fichier(a3)

	bra continue_search

*-----------------------------------------------------------------------------*
*                            Bouton Cancel                                    *
*-----------------------------------------------------------------------------*
* sert aussi … l'arret d'une recherche
cancel_search:
	save.l a0

	move.w #FORM_SEARCH,d0
	move.w #FSCHG_BTON_STOP,d1
	move.w #1,d2		; disable
	bsr GWVA_ENABLE_DISABLE_OBJECT

	move.w #FORM_SEARCH,d0
	move.w #FSCH_BTON_CONT,d1
	move.w #1,d2		; disable
	bsr GWVA_ENABLE_DISABLE_OBJECT

	move.w #FORM_SEARCH,d0
	move.w #FSCH_BTON_SEARCH,d1
	move.w #0,d2		; enable
	bsr GWVA_ENABLE_DISABLE_OBJECT

	load.l a0

	move.l GWVA_WIND_OBJ_USER_PTR2(a0),a1	; structure look associ‚e

	clr.w longueur_chaine_search(a1)		; la recherche ne peut etre relanc‚ (continue)
	move.l ad_buffer_search(a1),d0
	beq.s .not_searching
	save.l a0-a1
	MFREE d0
	load.l a0-a1
	clr.l ad_buffer_search(a1)
.not_searching:

	move.l GWVA_WIND_OBJ_USER_PTR1(a0),a2	; fenetre look associ‚e
	
	sub.w #1,GWVA_WIND_OBJ_TOPABLE_STATE(a2)
	bsr GWVA_WIND_OBJ_PRG_DELETE_ONE_WIND	; on efface la fenetre de recherche
					; le thread est automatiquement effac‚
*	move.w #-1,d0
*	move.l a0,d1	; on delete le thread de la fenetre
*	bsr GWVA_WIND_THREAD_DELETE

	rts

stop_searching:
	save.l a0

	move.w #FORM_SEARCH,d0
	move.w #FSCH_BTON_CONT,d1
	move.w #0,d2		; enable
	bsr GWVA_ENABLE_DISABLE_OBJECT

	load.l a0

stop_searching_bton:
	save.l a0

	move.w #FORM_SEARCH,d0
	move.w #FSCHG_BTON_STOP,d1
	move.w #1,d2		; disable
	bsr GWVA_ENABLE_DISABLE_OBJECT

	move.w #FORM_SEARCH,d0
	move.w #FSCH_BTON_SEARCH,d1
	move.w #0,d2		; enable
	bsr GWVA_ENABLE_DISABLE_OBJECT

	load.l a0

	move.l GWVA_WIND_OBJ_SPEC_PTR(a0),a1
	move.l GWVA_WFORM_OBJ_FORM_PTR(a1),a2
	move.w #FSCH_BTON_SEARCH,d0
	mulu #L_OBJECT,d0
	move.w #FSCH_BTON_CONT,d1
	mulu #L_OBJECT,d1
	btst #DISABLED,ob_state+1(a2,d1.l)	; Continue est-il disponible
	bne.s .pas_de_continue
	bclr #DEFAULT,ob_flags+1(a2,d0.l)
	bset #DEFAULT,ob_flags+1(a2,d1.l)	; on passe l'attribut d‚faut … CONTINUE
	bra.s .defaut_continue
.pas_de_continue:
	bclr #DEFAULT,ob_flags+1(a2,d1.l)
	bset #DEFAULT,ob_flags+1(a2,d0.l)	; on passe l'attribut d‚faut … SEARCH
.defaut_continue:

	save.l a0
	move.w #FSCH_REDRAW,d0
	moveq #3,d1
	moveq #0,d2
	bsr GWVA_FORM_WIND_OBJ_PRG_REDRAW_PART
	load.l a0

	move.l GWVA_WIND_OBJ_USER_PTR2(a0),a1	; structure look
	move.l offset_fichier(a1),offset_search_fichier(a1)
	move.l pos_curseur(a1),pos_search_curseur(a1)

	move.l table_obj(a1),a2
	lea struct_searching_slider-fenetre_search(a0),a3
	move.l offset_search_fichier(a1),d0
	divu.l #8+8,d0
	move.l d0,GWVA_FORM_SLIDER_OBJ_POS(a3)
	move.w f_num_line(a2),d0
	ext.l d0
	move.l d0,GWVA_FORM_SLIDER_OBJ_SIZE(a3)

	save.l a0-a1
	move.l GWVA_WIND_OBJ_SPEC_PTR(a0),a1
	move.l a3,a2
	bsr GWVA_SLIDER_OBJ_PRG_SET_SLIDER
	load.l a0-a1

	move.l GWVA_WIND_OBJ_USER_PTR2(a0),a1	; structure look
	move.l ad_buffer_search(a1),d0
	clr.l ad_buffer_search(a1)
	save.l a0
	MFREE d0
	load.l a0

	move.w #-1,d0
	move.l a0,d1		; on delete le thread de la fenetre
	bsr GWVA_WIND_THREAD_DELETE

	rts

*******************************************************************************
*             le thread de recherche pour chaque fenˆtre                      *
*******************************************************************************
; -> a0 : fenetre de recherche
search_in_file_for_a_window:
	move.l GWVA_WIND_OBJ_USER_PTR2(a0),a1	; structure look

	save.l a0-a1
	bsr GWVA_WIND_OBJ_PRG_UPDATE_TOOLB_AND_FORM_POS	; pour acc‚der aux champs et structures du clone
	load.l a0-a1

	move.l table_obj(a1),a2
	lea struct_searching_slider-fenetre_search(a0),a3
	move.l offset_search_fichier(a1),d0
	divu.l #8+8,d0
	move.l d0,GWVA_FORM_SLIDER_OBJ_POS(a3)
	move.w f_num_line(a2),d0
	ext.l d0
	move.l d0,GWVA_FORM_SLIDER_OBJ_SIZE(a3)

	save.l a0-a1
	move.l GWVA_WIND_OBJ_SPEC_PTR(a0),a1
	move.l a3,a2
	bsr GWVA_SLIDER_OBJ_PRG_SET_SLIDER
	load.l a0-a1

	save.l a0
	bsr load_buffer_search
	load.l a0
	tst.w d7
	bne stop_searching

	move.l d0,d3	; longueur du buffer r‚ellement lu

	move.l ad_buffer_search(a1),a3

	sub.l #1,d0
	bmi .fin_de_fichier

	lea chaine_search(a1),a4
	move.w longueur_chaine_search(a1),d2
	sub.w #1,d2

.compare1:	move.l a4,a2
	move.w d2,d1
.compare2:	sub.l #1,d0

	cmp.b (a2)+,(a3)+
	beq.s .comp_ok

	tst.l d0
	bpl.s .compare1

.fin_de_buffer:
	cmp.l buffer_search_length(a1),d3
	bne .fin_de_fichier

	move.l buffer_search_length(a1),d0
	add.l d0,offset_search_fichier(a1)

	rts

.comp_ok:	tst.l d0
	bmi.s .fin_de_buffer_a_cheval
	dbf d1,.compare2

; la comparaison des deux chaines est exacte
.comparaison_exacte:
	move.l a3,d0
	sub.l ad_buffer_search(a1),d0
	move.w longueur_chaine_search(a1),d1
	ext.l d1
	sub.l d1,d0
	bpl.s .sur_ce_buffer
	add.l buffer_search_length(a1),d0
.sur_ce_buffer:
	add.l offset_search_fichier(a1),d0

	add.l d0,d0
	sub.l pos_curseur(a1),d0

	move.w #0,d1
	save.l a0-a1
	move.l GWVA_WIND_OBJ_USER_PTR1(a0),a0	; pointeur fenetre qui a fait le search
	bsr update_position_curs
	load.l a0-a1

	save.l a0-a1
	move.l GWVA_WIND_OBJ_USER_PTR1(a0),a1	; pointeur fenetre qui a fait le search
	lea GWVA_APP_OBJ_MSG_EXT_BUF,a2
	move.w #WM_TOPPED,(a2)+		; type de message
	move.w global+_AESapid,(a2)+
	clr.w (a2)+
	move.w GWVA_WIND_OBJ_GEM_HANDLE(a1),(a2)+
	appl_write global+_AESapid,#16,#GWVA_APP_OBJ_MSG_EXT_BUF
	load.l a0-a1

	bra stop_searching

.fin_de_buffer_a_cheval:
	tst d1
	beq.s .comparaison_exacte

	cmp.l buffer_search_length(a1),d3
	bne.s .fin_de_fichier

	move.l buffer_search_length(a1),d0
	add.l d0,offset_search_fichier(a1)

	save.l a0
	bsr load_buffer_search
	load.l a0
	tst.w d7
	bne stop_searching
	
	move.l d0,d3

	move.l ad_buffer_search(a1),a3
	sub.l #1,d0
	bmi .fin_de_fichier

	dbf d1,.compare2	; au moins un tour
	illegal		; ne doit jamais sortir a ce niveau
	rts

.fin_de_fichier:
	save.l a0-a1
	move.l GWVA_WIND_OBJ_USER_PTR1(a0),a1	; pointeur fenetre qui a fait le search
	lea GWVA_APP_OBJ_MSG_EXT_BUF,a2
	move.w #WM_TOPPED,(a2)+		; type de message
	move.w global+_AESapid,(a2)+
	clr.w (a2)+
	move.w GWVA_WIND_OBJ_GEM_HANDLE(a1),(a2)+
	appl_write global+_AESapid,#16,#GWVA_APP_OBJ_MSG_EXT_BUF
	load.l a0-a1

	save.l a0-a1
	move.w #ALERT_NO_MATCH,d0
	move.w #1,d1
	bsr RSC_ALERT_BOX
	load.l a0-a1

	bra stop_searching_bton

load_buffer_search:
	save.l a1
	FILE_OPEN read,source_pathname(a1),d7
	load.l a1
	tst d7
	ble .erreur_open

	save.l a1
	FSEEK #0,d7,offset_search_fichier(a1)
	move.l (sp),a1
	FREAD ad_buffer_search(a1),buffer_search_length(a1),d7
	move.l (sp),a1

	save.l d0
	FCLOSE d7
	load.l d0

	load.l a1

	tst.l d0
	blt .erreur_read

	clr.w d7
	rts
.erreur_open:
	save.l a1
	move.w #ALERT_OPEN_FILE,d0
	move.w #1,d1
	bsr RSC_ALERT_BOX
	load.l a1
	move.w #GWVA_ERROR_GENERIC,d7
	rts
.erreur_read:
	save.l a1
	move.w #ALERT_READ_FILE,d0
	move.w #1,d1
	bsr RSC_ALERT_BOX
	load.l a1
	move.w #GWVA_ERROR_GENERIC,d7
	rts
