* mock_cauta_alfa_dialog.prg - inlocuieste DOAR PROCEDURE cauta_alfa (COMUN\programe\cauta_alfa.prg,
* linia 16), NU cauta_nom_articole/XML2ListaIDDescriere/do_adauga_articol - acelea raman REALE,
* neatinse. Se incarca PRIMUL (inaintea "SET PROCEDURE TO cauta_alfa ADDITIVE") - la nume duplicat
* de procedura VFP foloseste fisierul incarcat PRIMUL (vezi docs/testare-ui-vfp.md capcana j).
*
* De ce: cauta_alfa() reala populeaza cursorul din Oracle prin gencursor->ca_baza.afisare(), care
* foloseste This.CursorFill() (CursorAdapter/conexiune reala) - nu goExecutor, deci nu poate fi
* mock-uit ca restul infrastructurii (vezi COMUN\clase\decabaza.vc2:36-99). Acest shadow inlocuieste
* DOAR sursa de date (Oracle -> cursor mock pre-populat de test) si bucla de asteptare modala
* (WindowType=1, Show() blocheaza pana la Release -> WindowType=0 + actiuni conduse programatic
* dupa Show(), vezi docs/testare-ui-vfp.md capcana g). Formularul e clasa REALA cauta_alfa_form
* (COMUN\clase\cauta_alfa_forms.vcx), metodele apelate (do_alege, do_termin, do_renunt) sunt cele
* REALE, neschimbate - doar interactiunea utilizatorului e simulata in loc de bucla de evenimente.
*
* IMPORTANT (capcana l, docs/testare-ui-vfp.md): CREATEOBJECT apelat DINTR-O PROCEDURA (nu din
* programul principal) intoarce un obiect stricat in acest runtime headless (verificat empiric -
* "OFORM_CAUTARE is not an object" la prima folosire). De aceea formularele NU se creeaza aici -
* testul principal le PRE-CONSTRUIESTE inline (goDlgA/goDlgB/goDlgC) INAINTE sa apeleze
* do_adauga_articol, iar acest shadow doar SELECTEAZA obiectul potrivit dupa gcTestScenariu si ii
* apeleaza metodele reale (asta e simpla dispecerizare de metoda, nu CREATEOBJECT - functioneaza
* din procedura fara probleme).
*
* Control test (setate de testul principal INAINTE de fiecare apel):
*   goDlgA / goDlgB / goDlgC - formularele REALE pre-construite (vezi test_picker_real_212.prg)
*   gcTestScenariu           - 'A' (marcheaza BULDOEXCAVATOR + OK), 'B' (nimic marcat + OK),
*                               'C' (dublu-click pe denumire), altfel Cancel
* Rezultat expus (citit de testul principal dupa apel):
*   gcTestGnButon, gcTestXML, gcTestLenXML, gcTestCAles, gcTestPcAles, gcTestRandiuriMarcate

Procedure cauta_alfa
	Parameters tcselect,tcfiltru,tcschema,tcorder,tccoloana,tcTitlu,tcTitluColoane, ;
		tcNume_Proc,tl_AllInList,tcFiltruOriginal,tcPrimaColoana, tnPornire, tnTipReturn, ;
		tcIdColumn, tlDesktop, tcGroup, tcGridDynamicBackColor, tcGridToolTip, tlModParam, tcStringCriterii, ;
		tcProceduraVerifica, tcProceduraCopiaza,tcLocate

	LOCAL lcCursor, lcCursorXML, lcCAlesDupaMarcare
	LOCAL oForm_cautare, oReturnScattObj
	Private pcAles
	pcAles = ""
	gcTestRandiuriMarcate = 0

	IF USED('crsReturnAlfa')
		USE IN ('crsReturnAlfa')
	ENDIF

	*-- === selecteaza obiectul PRE-CONSTRUIT (vezi capcana l mai sus - fara CREATEOBJECT aici) ===
	DO CASE
	CASE gcTestScenariu == 'A'
		oForm_cautare = goDlgA
	CASE gcTestScenariu == 'B'
		oForm_cautare = goDlgB
	CASE gcTestScenariu == 'C'
		oForm_cautare = goDlgC
	OTHERWISE
		oForm_cautare = goDlgA
	ENDCASE
	lcCursor = oForm_cautare.crs_cursor

	*-- pcAles trebuie sa reflecte marcajul curent INAINTE de a incepe (formularul e deja afisat,
	*-- creat in main); il sincronizez manual cu cAles-ul formularului la pornire, exact cum face
	*-- BINDEVENT(Thisform,"lAles",...) + do_alege() in fluxul real (do_alege scrie in AMBELE,
	*-- Thisform.cAles si pcAles - vezi cauta_alfa_forms.vc2:405-418).
	pcAles = oForm_cautare.cAles

	*-- === FAZA 1: marcare - simuleaza interactiunea utilizatorului cu formularul REAL ===
	*-- IMPORTANT: NU se atinge oForm_cautare dupa do_termin()/do_renunt() - acele metode fac
	*-- this.Release, care DISTRUGE efectiv formularul VFP (verificat empiric: accesarea unei
	*-- proprietati dupa Release da eroare 1924 "is not an object", chiar daca alta variabila
	*-- (goDlgA) inca "tine" referinta) - de-aia cauta_alfa.prg REAL insusi nu mai citeste nimic
	*-- de pe oForm_cautare dupa .Show() decat prin pcAles/gnButon (variabile libere, nu proprietati
	*-- de obiect). Orice diagnostic despre cAles trebuie capturat AICI, inainte de faza 2.
	DO CASE
	CASE gcTestScenariu == 'A'
		*-- marcheaza randul BULDOEXCAVATOR prin mecanismul real (echivalentul click pe denumire /
		*-- SPACE): do_alege() citeste RECNO() curent al cursorului si toggle-uie cAles la acea pozitie.
		SELECT (lcCursor)
		LOCATE FOR ALLTRIM(denumire) == 'BULDOEXCAVATOR'
		IF FOUND()
			oForm_cautare.do_alege()
		ENDIF
		lcCAlesDupaMarcare = oForm_cautare.cAles
		IF TYPE('gcUILog') = 'C'
			DO HarnessStep WITH 1, 'scenariul A: BULDOEXCAVATOR marcat (Thisform.cAles=[' + lcCAlesDupaMarcare + ']), inainte de OK real'
		ENDIF

	CASE gcTestScenariu == 'B'
		*-- nimic marcat
		SELECT (lcCursor)
		GO TOP
		lcCAlesDupaMarcare = oForm_cautare.cAles

	CASE gcTestScenariu == 'C'
		*-- "dublu-click pe denumire": in modul multi-select (lAles=.T., cazul cauta_nom_articole),
		*-- BindEvent(dblClick->do_termin) NU se armeaza (cauta_alfa_forms.vc2:652 "If !Thisform.lales"),
		*-- deci dublu-click = 2x acelasi Click -> do_alege() de 2 ori (marcheaza, apoi demarcheaza) -
		*-- NU exista submit rapid pe dublu-click in acest dialog. Simulez exact gestul (2 click-uri pe
		*-- Column1.Text1, handler-ul REAL) si documentez ca cursorul ramane nemarcat.
		SELECT (lcCursor)
		LOCATE FOR ALLTRIM(denumire) == 'BULDOEXCAVATOR'
		IF FOUND()
			oForm_cautare._GRID1.Column1.Text1.Click()
			oForm_cautare._GRID1.Column1.Text1.Click()
		ENDIF
		lcCAlesDupaMarcare = oForm_cautare.cAles
		IF TYPE('gcUILog') = 'C'
			DO HarnessLog WITH 'scenariul C: dupa 2x Click (dublu-click simulat) cAles=[' + lcCAlesDupaMarcare + '] (astept ramas needecis, fara submit automat)'
		ENDIF

	OTHERWISE
		lcCAlesDupaMarcare = oForm_cautare.cAles
	ENDCASE

	*-- diagnostic cerut de team lead: pcAles (variabila PRIVATE folosita mai jos in filtrul WHERE al
	*-- XML-ului) vs Thisform.cAles (marcajul vizual/albastrit vazut de Marius) - trebuie sa fie
	*-- SINCRONE la acest punct, INAINTE de faza 2 (inchidere), pentru ca acolo se pierde accesul.
	gcTestPcAlesInainte = pcAles
	gcTestCAlesInainte = lcCAlesDupaMarcare

	*-- === FAZA 2: inchidere - butonul OK/Cancel REAL (this.Release -> oForm_cautare devine inert) ===
	DO CASE
	CASE gcTestScenariu == 'A' OR gcTestScenariu == 'B' OR gcTestScenariu == 'C'
		oForm_cautare.do_termin()		&& butonul OK REAL (_frm_base.do_termin: gnButon=1, Release)
	OTHERWISE
		oForm_cautare.do_renunt()
	ENDCASE
	DOEVENTS FORCE

	*-- === de aici incolo: cod IDENTIC cu cauta_alfa.prg original (COMUN\programe\cauta_alfa.prg,
	*-- liniile 218-249) - aceeasi conditie, acelasi filtru (pcAles), acelasi CURSORTOXML. NU se mai
	*-- atinge oForm_cautare (a fost Release-uit de do_termin/do_renunt mai sus). ===
	lcCursorXML = ""
	SELECT (lcCursor)
	IF gnButon=1
		Do Case
			Case tnTipReturn = 0
				Scatter Name oReturnScattObj Memo
			Otherwise
				Select * From (lcCursor) With (Buffering = .T.) Where Substr(pcAles,Recno(),1) = 'X' ;
					INTO Cursor crsReturnAlfa
				Cursortoxml("crsReturnAlfa", "lcCursorXML", 2, 0+2+8, 0, "1")
				gcTestRandiuriMarcate = RECCOUNT('crsReturnAlfa')
				Use In crsReturnAlfa
		Endcase
	Else
		Do Case
			Case tnTipReturn = 0
				Scatter Name oReturnScattObj Blank
			Otherwise
				lcCursorXML = ""
		Endcase
	Endif

	*-- expus pentru diagnostic in testul principal (cAles luat din snapshot-ul de dinainte de
	*-- Release - vezi FAZA 1 - NU de pe oForm_cautare, care e deja inert dupa do_termin/do_renunt)
	gcTestGnButon = gnButon
	gcTestXML = lcCursorXML
	gcTestLenXML = LEN(m.lcCursorXML)
	gcTestCAles = lcCAlesDupaMarcare
	gcTestPcAles = pcAles

	*-- NU dau Release aici (obiectul e deja Release-uit de do_termin/do_renunt mai sus)
	Use In (lcCursor)

	Do Case
		Case tnTipReturn = 0
			Return oReturnScattObj
		Otherwise
			Return lcCursorXML
	Endcase

Endproc && cauta_alfa (shadow test)
