* TUTOSETS.PRG
* Application's startup environment settings (shared by Web and LAN versions)
* C:\PROGRAM FILES (X86)\ABAQUE\FICSAMPLES\FICTUTO\PROGS\TUTOSETS.PRG (included in c:\program files (x86)\abaque\ficsamples\fictuto\fictutobs.exe)
* (378 lines before localization)
* ========================================================================================================================

#include ab.h

&& Instantiate an 'tutoSets' Class
&& this implementation restores initial environment using .Destroy() method

* ===================================================

DEFINE Class tutoSets AS awSets OF awPublic.prg
* ===================================================

* ---------------------

procedure Init
lparameters ;
result; && @ result of application startup - appears in .../foxincloud-status.tuto
, toAppHost as awAppHost of awAppHost.fxp && Web Application Host

local success as Boolean;
, lcDev, llDev;
, lcThisPrg;
, uException as Exception;
, hSQLconnect as Integer;
, iSQLversion as Integer;
, connectString as String;
, lConnected as Boolean;
, oDefault as abSet of abDev.prg;

* ==================================
success = DoDefault(; && sets various properties such as this.wlWeb and this.wlLAN
   @m.result;
  )
* ==================================

&& code shared by Desktop (LAN) and Web modes

* Before this code executes, FoxInCloud Application Server has set CurDir() to
* the application's main folder, where project resides
* (<<m.tcAppPath>>)
* All the following pathes are relative to this folder …
* <<m.tcAppPath>>)

#if .F. && intellisense
with this as awSets of awPublic.prg
#endif

lcDev = Iif(Directory('..\..\_Data\'), '..\', '') && in production, _Data\ is one level up
llDev = !Empty(m.lcDev)

SET PATH TO '';
  + Iif(m.llDev;
    , '';
    + '.\Progs\;';
    + '.\Progs\Bitmaps\;';
    + '.\Progs\Forms\;';
    + '.\Progs\Menus\' + Iif(this.wlLAN or m.toAppHost.BSlHTMLgen, 'bs\', '') + ';';
    + '..\Classe\;';
    + '..\..\Tastrade\Adapted\Form\;';
    ;
    , '..\_Images\;';
    );
  + m.lcDev + '..\_Data\;';
  + m.lcDev + '..\_Libs\FoxyPreviewer\;';
  + m.lcDev + '..\_Libs\xfrx\;';
  + m.lcDev + '..\_Libs\FRX2Any\;';
  ADDITIVE

IF !this.lAutomation

  ClassLibAdd(''; && avoids confusion between .vcx contained in awAdapter.app and those contained in aw.app && modify command abDev
    + 'ficSample.vcx,';
  + '_reportListener.vcx,'; && FFC\
  + '_gdiPlus.vcx';
  )
external class ficSample, _reportListener, _gdiPlus

  lcThisPrg = cModuleInfo(Sys(16), 'A')
  set procedure to (m.lcThisPrg) additive && class definitions below
ENDIF

if File('foxyPreviewer.app')
  set printer to default
  try
    oDefault = abSet('default', JustPath(FullPath('foxyPreviewer.app')))
    do foxyPreviewer.app
    _screen.oFoxyPreviewer.lSilent = !m.this.lDevMode
  catch to uException && possible error 'printer is not ready'
    uException = cException(m.uException)
    do case
    case this.wlLAN
      MessageBox([FoxyPreviewer could not load!] + CRLF2 + m.uException)
    case Vartype(m.toAppHost) == 'O'
      cResultAdd(@m.result, m.uException)
    endcase
  endtry
  oDefault = .null.
endif

local FRX2Any
FRX2Any = 'FRX2Any'
if File(m.FRX2Any + '.app')
  set classlib to &FRX2Any in FRX2Any.app additive
else
  cResultAdd(@m.result, 'FRX2Any.app could not be found')
endif

&& after libs to make sure we get the right settings

&& settings scoped to this datasession
&& note: this code executes in a private datasession provided by FoxInCloud;
&& FoxInCloud runs in its own, distinct private datasession

set collate to 'MACHINE'
set deleted off
set exact off
set exclusive off
set multilocks on
set reprocess to -2 && AUTOMATIC
set safety off
set sysformats on
set talk off

&& server-wide settings
&& note: FoxInCloud maintains its own settings so whatever setting here won't affect FiC

set nulldisplay to 'N/D'

public goApp
goApp = NewObject('ficCstApp', 'ficSample.vcx') && has .userProperty

local cAlias
if !File('ficEvent.dbf') or .F. and varSet(@m.cAlias, ExclusiveForce('ficEvent.dbf')) and Used(m.cAlias)
  use in select (Evl(m.cAlias, ''))
  try && safety in case of multiple servers
    CREATE TABLE ficEvent FREE (; && all server-side events are logged into this table
       ID I autoinc unique;
      , MODE C(1); && 'W'eb, 'D'esktop
      , userID C(10) null;
      , FORM C(50);
      , NAME C(50);
      , EVENT C(50);
      , baseClass C(50);
      , Class C(50);
      , lBufDirty L null;
      , timeStamp T;
      )
    index on userID tag userID collate 'general' && see eventLog.scx
    index on form tag form collate 'general'
    index on name tag name collate 'general'
    index on event tag event collate 'general'
    index on baseClass tag baseClass collate 'general'
    index on Class tag Class collate 'general'
    index on timeStamp tag timeStamp
    use
    StrToFile('', 'ficEvent' + Iif(m.this.wlWeb,'Web','Lan') + '.log') && clears text log file
    cResultAdd(@m.result, 'FoxInCloud Tutorial Event Table created')
  catch
  endtry
endif

&& code specific to desktop mode
IF m.this.wlLAN
  set escape off
  ADDPROPERTY(m.this, 'ON_SHUTDOWN', ON('shutdown'))
  ON SHUTDOWN CLEAR EVENTS
endif

open database tastrade

do case
case Sys(0) == "THN-W7-32 # ThierryNivelet" and m.this.lDevMode && SQLserver Express 2014 installed
  lConnected = .T.
case m.this.lDevMode
  SQLSetProp(0, "DispLogin", DB_PROMPTNEVER)
  for iSQLversion = 1 to 2
    connectString = "";
      + "Driver=SQL Server Native Client 11.0;";
      + "Server=" + Iif(m.iSQLversion = 1;
        , "(localdb)\MSSQLLocalDB"; && MS SQL server Express 2014 (version 12)
        , "localhost\SQLEXPRESS"; && MS SQL server Express 2017 (version 14)
        ) + ";";
      + "AttachDbFilename=";
       + DOS_AWSAMPLES_DATA + "SQLSERVER\";
       + Iif(m.iSQLversion = 1, '2014\', '');
       + "NorthWind.mdf;";
      + "Database=NorthWind_FiC;";
      + "Trusted_Connection=Yes;"; && + "Integrated Security=true;"
      + "Connect Timout=5;"; && default 15
      + "APP=FICtuto;";
      + ""
    hSQLconnect = SQLStringConnect(m.connectString)
    lConnected = m.hSQLconnect > 0
    if m.lConnected
      SQLDisconnect(m.hSQLconnect)
      DBSetProp('Northwind', "CONNECTION", "ConnectString", m.connectString)
      exit
    endif
  endfor
otherwise
  hSQLconnect = SQLconnect('Northwind') && avant de copier tastrade.dbc sur foxincloud.com : Driver=SQL Server Native Client 11.0;Server=ABAQUE;AttachDbFilename="C:\Program Files (x86)\Abaque\FICsamples\_Data\SQLSERVER\Northwind.mdf";Database=NorthWind_FiC;Trusted_Connection=Yes;APP=FICtuto; &&
  lConnected = m.hSQLconnect > 0 and (SQLdisconnect(m.hSQLconnect) > 0 or .T.)
endcase

cResultAdd(@m.result, "Connection to the 'Northwind' SQLserver database: " + Iif(m.lConnected, 'OK', 'KO -- ' + caError()))

= this.wlLAN;
or cResultAdd(@m.result, "This application is for learning and testing; some errors are intended and triggered purposedly... AVAILABILITY RATIO IS FAR BELOW what a regular production application usually gets.");
or cResultAdd(@m.result, "By default, this FoxInCloud Web Application Dashboard is protected by a secured authentication; it was made public in this very example for the purpose of demonstration.");
or .F.

if !(this.lDevMode and this.wlLAN)
  DO tuto.mpr && application menu (adapted)
endif

*!*  activate screen
*!*  ? m.toAppHost.uFormsLaunchAtStartup
*!*  wWAIT(m.toAppHost.uFormsLaunchAtStartup, 'WINDOW NOWAIT TIMEOUT 30')

return m.success
endproc

* ---------------------
PROCEDURE Destroy

IF m.this.wlLAN
  lcValue = m.this.ON_SHUTDOWN
  ON SHUTDOWN &lcValue
endif

release goApp

return DODEFAULT()

endproc

* ===================================================
ENDDEFINE && Class tutoSets
* ===================================================

* ===================================================

define Class ficGrc as awGrc of awPublic.prg && as Column
  headerClass = 'ficGrh' && see below
  headerClassLibrary = 'tutoSets.fxp' && 2016-05-26 thn -- {FiC V 2.21.1-beta.5} .HeaderClassLibrary does not really work as header class must be defined in *.prg (can't be defined visually in a .vcx) -- set procedure to (this program) is required
  FontName = "Consolas"
enddefine
* ---------------------------------------------------
define Class ficGrh as awGrh of awPublic.prg && as Header
  FontName = "Consolas"
  Alignment = 2 && center
enddefine
* ===================================================

* ----------------------------------------------------

function tutoNavigate(URL, newWindow)
return wNavigate(; && modify command awPublic
   Iif(wlLAN(), 'http://foxincloud.com/tutotest/', '') + m.URL;
  , lTrue(m.newWindow);
  )
endfunc

* ----------------------------------------------------
function fileDisplay(file)
return tutoNavigate(; && see above
   'fileDisplay.tuto?' + m.file; && modify command tutoServer > tutoProcess.fileDisplay()
  , .T.;
  )
endfunc

* ----------------------------------------------------
procedure custOrderReport && generates a customer-orders PDF report
lparameters ;
result; && @
, lcPDFout; && @
, customerID;
, lcPDFengine;

local success as Boolean

try

  lcPDFout = Textmerge([<<Addbs(Sys(2023))>>customer_<<Trim(m.customerID)>>_<<m.lcPDFengine>>.pdf]) && PDF > VFP temp folder
  lcPDFengine = Upper(Alltrim(Evl(m.lcPDFengine, 'XFRX')))

  do case
  
  * =================================================
  case m.lcPDFengine == Upper('XFRX')

    local oXFRXlistener as XFRXlistener of xfrx.app

    oXFRXlistener = Evaluate("xfrx('XFRX#LISTENER')")
    success = Vartype(m.oXFRXlistener) == 'O'
    if m.success

      result = m.oXFRXlistener.setParams(; && doc: https://eqeuscom.atlassian.net/wiki/display/DOC/Properties+and+methods+common+in+XFRXListener+and+XFRXSession+classes
         m.lcPDFout; && tcOutputName - name of the document to create.
        , ; && tcTempDirectory - [optional] directory where temporary files will be created. If blank, the temporary files will be created in the current directory
        , .T.; && tlNotOpenViewer - [optional] if set to .T., documents won't be opened after the generation
        , ; && tcCodePage - [optional] codepage of the generated document. If you don't specify this parameter, cpcurrent() is used
        , .T.; && tlSilent - [optional] if set to .T., no messages will be printed. This option is useful if your application is not in English and/or you would like to handle the Processing... message and error messages in your code.
        , ; && tlNewSession - [optional] This option is not used for PDF targets. If set to .T., the document will always be open in a new Word session. By default, word document will be open in the current Word session, if exists.
        , 'PDF'; && tcTarget - The output type to be generated. One of the values listed at XFRX Output Target Types.
        )
      success = Empty(m.result)
      if m.success

       * --------------------------------
       REPORT FORM customer;
         for customer_ID = m.customerID;
         object m.oXFRXlistener
       * --------------------------------

      else
        result = m.oXFRXlistener.ErrorMessage(m.result)
      endif
    else
      result = [could not instantiate XFRX report listener]
    endif

  * =================================================
  case m.lcPDFengine == Upper('FoxyPreviewer')
&& Though FoxyPreviewer works fine in desktop mode, you may face an issue in production / COM mode (see URL below)
&& https://foxypreviewer.codeplex.com/workitem/10921

    * --------------------------------
   REPORT FORM customer; && invokes foxyPreviewer PDF writer automatically
     for customer_ID = m.customerID;
     object type 10; && Regular PDF -- https://foxypreviewer.codeplex.com/documentation
     to file (m.lcPDFout)
    * --------------------------------
    success = .T.

  * =================================================
  case m.lcPDFengine == Upper('FRX2any')
&& Note: FRX2any demo version does not work in production (exe/COM) -- you can test it in the VFP IDE only (development mode)
    
    local loPDFfile as PDFfile of FRX2Any

    loPDFfile = CreateObject('FRX2Any.PDFfile')
    success = Vartype(m.loPDFfile) == 'O'
    if m.success
      with m.loPDFfile as PDFfile of FRX2Any
        .Unlock('xxxxxx-xxxxxx-xxxxxx-xxxxxx-xxxxxx-xxxxxx') && Unlocks FRX2Any demo version
        .cExportFileName = JustStem(m.lcPDFout) && loPDFfile.cExportFileName should not include file extension. For example: loPDFfile.cExportFileName = "ReportOutput"
        .cSaveFolder = JustPath(m.lcPDFout) && loPDFfile.cSaveFolder should contain only path to the output file. For example: loPDFfile.cSaveFolder = "c:\MyApp\MyOutPut\"
        .lTranslateFontStyle = .T. && Force FRX2ANY to use localized name of the font(s); Set this property to true if your OS uses translated font names (Arial Fett, Arial Negrita, Arial Italique)
        .cForExpression = Textmerge([customer_ID = "<<m.customerID>>"])
        * --------------------------------------
        result = .Save(FullPath('customer.frx'))
        * --------------------------------------
        success = Empty(m.result)
        result = Iif(m.success, '', Textmerge([FRX2Any returned error #<<m.result>>]))
        .Release
      endwith
    else
      result = [could not instantiate FRX2Any.PDFfile]
    endif
  * =================================================

  endcase

catch to m.result
  success = .F.
  result = cException(m.result)
endtry

return m.success
endproc