****************** Copyright (c) 2000 - Ackley Systems ********************
*                                                                         *
*  This information is provided as-is, with no warranty or guarantee of   *
*               usability for any application or purpose.                 *
*  Rights are granted for registered owners of League Administration      *
*     Software  to use the information in this document to develop custom *
*     "Plug-in" applications to be used with LAS.                         *
*                                                                         *
*             Copyright (c) 2000 by All American SportsWare               *
*                        All Rights Reserved.                             *
*                                                                         *
L eague     A dministration     C omponent     E nvironment

    P L U G - I N   D E V E L O P M E N T   D O C U M E N T A T I O N
    ----------------------------------------------------------------       
    
               Table of Contents 
               
         (1) - General Overview - What Is A Plug-In?
         (2) - How Does A Plug-In Work?
         (3) - Interface with LAS
            (a) Routines that must exist in the plug-in
            (b) Files on the Plug-in Distribution (release) disk
            (c) Definable Hooks
               
         (4) - Utility Routines avaiable for use
         (5) - General Routines for Plug-ins to use
            (a) Plug-in Specific Routines
            (b) General LACE Routines
            
         (6) - Building a VFP .APP File
            (a) Including External Routines
         (7) - Plug-in Abbreviations

--------------------------------------------------------------------------

                                   - 1 -                       Back to Top
                                   
                                   
(1) General Overview - What Is A Plug-In? 
    ------------------------------------- 

    Starting with version 7, League Administration Software now is the
    most extensible package in the industry.  By using LACE plug-ins, 
    you, us, or anyone else may extend the functionality of LAS.
    
    Basically, a LACE Plug-In is a small program, written to the 
    LAS Component Environment interface (LACE interface) specification, 
    that can add functionality to LAS.  The new function could
    be a report, shortcut keys for the registration screen to accomplish
    complicated tasks, specialty export formats, a new Table (database) 
    with editing and reporting features, or even a full scheduling package.
    
    
    Technically, a LACE Plug-In is a Microsoft FoxPro v2.6 generated .FXP 
    file that has been renamed with a .PLD extension (in DOS) or
    a Microsoft Visual Foxpro generated .APP file renamed with a
    .PLG extension (in Windows).
    The Foxpro versions used to build the plugin need to match the Foxpro
    versions used to build LAS itself; here is a build table:

    
             DOS/Win                  FoxPro Ver          Lace Version    
           Las Dos v7.00+           FoxPro Dos v2.6          1.00
           Las Dos v8.00+           FoxPro Dos v2.6
           LasWin v9.00 -- v9.19    MS Visual Foxpro v3
           LasWin v9.20 -- v9.29    MS Visual Foxpro v5
           LasWin v9.30+            MS Visual Foxpro v6      1.05
    
    ( a plus (+) next to a version means that this applies for the rest
    of that major version, or up to the present (Jan 2000) if the major
    version number is still current ) 

    This .PLD or .PLG file must contain certain standard
    routines which constitue part of LACE, the Interface Environment.

    These routines are named starting with "plg", for example: plgInstall,
    plgUnInst, plgName, plgVersion, etc.  This applies to the
    single PRG file in the DOS plugins, and to the "main" PRG file
    in the application for Windows Plugins.

    LACE allows LAS to easily interact with the plugin.
    
    
    
--------------------------------------------------------------------------


                                   - 2 -                       Back to Top

(2) How Does A LACE Plug-In Work?
    -----------------------------  
    
    (To be written: Explain the installation process )
    
    (To be written: Explain the working process      )
    
    (To be written: Explain the un-install process   )


--------------------------------------------------------------------------


                                   - 3 -                       Back to Top
                                   

(3) Interface with LAS:
    ------------------- 

  (a) Routines that must exist in the plug-in:
      ----------------------------------------
      
      These routines must exist in the Foxpro program/procedure file
        so that they can be executed from within LAS.
      
      plgName()         - Name of the Plugin
      plgVer()          - Version of Plugin
      plgInstall(cPath) - Install the plugin
               cPath = path to copy additional files from
      plgUnInst()       - Un-Install the plugin
      plgComp()         - LAS min compatible version
      plgOptions()      - Setup Plugin Options
      plgIndex( func )  - ReIndex Plug
                func = COUNT   : return # to add to bar (returned in _tally)
                func = REINDEX : do plugin's reindex

      plgReg()          - Register Plugin; Called from UpHardwr

   Only used internally, but always needed:
      plgFile()         - Full path to plugin file

  (b) Files on the Plug-in Distribution (release) disk:
      -------------------------------------------------

   (XXXXXXXX is the plugin name)

        XXXXXXXX.pld  -- Fpd26 .FXP executable module -\___and/or
        XXXXXXXX.plg  -- Vfp3  .FXP executable module -/
        YYYYYYYY.fr?  -- *.frx and *.frt that constitutes all of the
                           plugin's report files.  (for simplicity,
                           if there is only one report, name it the
                           same as the plugin, ie. XXXXXXXX.FRX, and
                           XXXXXXXX.FRT)

        XXXXXXXX.DBL/DBF/FPT/DBW/etc. --- Whatever support files the
                           plugin needs to use.  NOTE: DBF files should
                           not be copied in, but rather created by
                           the XXXXXXXX.PLD:plgIndex("REINDEX") routine.
                           Be careful not to use DBFs that LAS already
                           uses.   If you are extending the function of
                           an existing DBF, (ie. adding DISTRICT to the
                           SCHOOL.DBF file), you can (in plgindex):
                              Copy the SCHOOL.DBF into the .\REINDEX\ subdir.
                              Create the new format SCHOOL.DBF using SQL command.
                              Append from .\REINDEX\SCHOOL
                              Re-create all the needed LAS indexes plus
                                all the indexes you need.

/ only in official AAS plugins:
|       XXXXXXXX.REG  -- League Registration File for the plugin file
\


  (c)  Definable Hooks:
       --------- ------
  
    Hooks To Replace Functions ... (you may just create a new "front end", 
                                    then still call the predefined functions)
    Hooks To Add Functionality:... (These don't replace existing functionality, 
                                    they only allow calling custom code at 
                                    predefined Hook points, in addition to
                                    the existing code)


             -------------Las v7.00 Beta 2----------------
    
    Hooks For Replacing Functions:
      
    __Viewfile = "VIEWFILE"      ==    Called to View a file.
        Syntax:  do &__ViewFile with cFileNameAndPath
                                       
    __Pf_Filtr = "PF_FILTR"      ==    Called to Select Players.
        Syntax:  _for = &__Pf_Filtr( cForString, cDivVar, cTeamVar )
        
        Parameters: 
            cForString  -  Character expression that evaluates to a
                             valid logical .t. or .f. when used as
                             the "SET FILTER TO &cForString" on the
                             current Alias (Player or PlyReg)
            cDivVar     -  The Character Field name of the division
                             to filter by; ie. "PF_DIV" or "PF_LASTDIV"
                             or "PF_AS_DIV"
            cTeamVar    -  Similar to cDivVar; ie. "PF_TEAM", "PF_LASTEAM"
                             or "PF_AS_TEAM"
        
        Restrictions:   The __Pf_Filtr plugin must be the name of the
                        .fxp file in the LAS subdirectory, so that
                        it can be called directly as a function, rather
                        than "IN" a procedure file.
                             
    Hooks To Add Functionality:................................

    __ReadIt   = ""  ==  Called In Readit (if not empty) after the 
                           parameters have been processed to reveal 
                           valid values for the buttons to be displayed, 
                           but before the buttons are created.
    __PrePEd   = ""  ==  Called Before player information is edited.
                           (After all the @ Gets, before the READ)
    __PostPEd  = ""  ==  Called After player information is edited.
                           (After the READ, before the save)
    __PreMEd   = ""  ==  Called Before member information is edited.
                           (After all the @ Gets, before the READ)
    __PostMEd  = ""  ==  Called After member information is edited.
                           (After the READ, before the GATHER)
    __HelpKeys = ""  ==  Called Inside HelpKeys after F1 is set.
                           (Your routine must accept one parameter,
                              ="ON" or ="OFF" )
                              
    Notes on using Player & Member Information Screen Hooks............
    ...................................................................
    ReadWindows  - C ==  This is a comma seperated list of additional
                           windows to allow to be active during a 
                           Player/Member Information READ.  If this 
                           variable is not empty, its first character 
                           must be a comma.
    Changed      - L ==  This is a status variable, initialized false
                           before the Player/Member edit.  Set this
                           to true if you want the player/member saved
                           on pgup/pgdn/OK.
                           
    In LACE ver 1.05+ __PostPEd and __PostMEd are always executed.
    Check the status of the "SaveRecs" logical variable for whether
    things should be saved or not.


         

--------------------------------------------------------------------------


                                   - 4 -                       Back to Top
(4) Utility Routines:
    -----------------  
  
     Parameter Types:
       cXXXXX  =   Character String
       csXXXX  =   Character String signifying an Alias
       cvyXXX  =   Character Name of the variable to change (ie. by referance)
                     where "y" is the type of the data in the variable
       nXXXXX  =   Numeric
       aXXXXX  =   Array
       vyXXXX  =   Variable of type "y" passed by referance
     
    FindProg.....( cName )
                 Look in standard places to find a windows word processor
    GetDBW.......( cDBWName )
                 USE EXCLUSIVE a temporary copy of the requested .DBW file
    CloseDBW.....( cDBWName )
                 This routine will Close a DBW file (not necessarily opened
                                                     using GetDBW) 
                 (If the actual file name ends in .TMP instead of .DBW,
                  this routine also will delete the file and return .t.
                  and, if a .CDX exists at the same path, with the same
                  base filename, it is also deleted)
    Exist........( cSkeleton )
                 This routine tells if any files exist using a given skeleton
    UnqTMP.......()
                 Find a unique file name ("LAS?????.TMP")
                 (either in the getenv("TEMP") directory or 
                  "TMP" or C:\TEMP or current)
    AddToArray...( vaArr, vnTot, cE1, cE2, cE3, cE4, cE5, cE6, cE7, cE8, cE9 )
                 Add all elements in a row to an array and update length value
                 (if array isn't long enough, this also re-dimensions it)
                 Any Specified "cEx" values are put into the array in the
                   new row.
    Calendar.....Calendar  Support  Routines  .. see code for parameters
    FG...........Takes a color pair and returns the foreground
    BG...........Takes a color pair and returns the Background
    MessageBox...Puts up a message box with choice of message & buttons
    SalvageRec...( cW1,cW2,cW3,cW4,cW5,cW6,cW7,cW8,cW9,cW10 )
                 In Non-Exclusive mode, this looks for a deleted record,
                   recalls it, and blanks it.
                 Only if there are no deleted records does it Append a Blank
                 Any Specified "cWx" parameters are in the format:
                   "fieldname WITH value" and are executed in a REPLACE
    ExistIn......( cLookIn, cFor1, cFor2, cFor3... )
                 This is alot like "InList" only uses "$" instead of "="
    NextID.......( csTable )
                 This routine looks in NEXTID.DBF for csTable and inc's & 
                 returns the Next ID value to use!
    JustFName....( cFullPath ) Trim path off of File name
    JustPath.....( cFullPath ) Trim file name off of path 
    StrDel.......( cSrce, cDel1, cDel2... ) 
                 Delete multiple strings out of Srce
    IsTag........( cTagName )  Is this a valid tag name?
    TagNum.......( cTagName )  Valid Tag Number (0 if not valid)
    Exec.........( c1,c2,c3,c4,c5,c6,c7,c8,c9 )  Up to 9 commands to execute
    IsLocked.....( csArea ) 
                 Returns .t. if the current record in AREA is locked by someone 
                 else. DOES NOT disturb current locks.
    EndsWith.....( cSrce, cEnding1, cEnding2... )
                 if the source ends with any of the strings, return .t.
    EndsWithC....( cSrce, cEnding1, cEnding2... )
                 Case Insensitive EndsWith
    MonStr.......( nMonth ) Returns the Month Name 
    MonNum.......( cMonth ) Returns the Month Number 
    
    
    - For Windows LACE Plug-ins:
    MakeFox2x....()  Change the currently selected VFP table into a Fox2x Table
    


--------------------------------------------------------------------------


                                   - 5 -                       Back to Top


(5) General Routines for Plug-ins to use
    ------------------------------------  
    
    LAS provides many general routines to make writing LACE components
    easier, some of which are specifically designed to make it easier
    to write plug-ins.  A few are only meant to be used in the plgInstall
    and plgUnInst routines, though they are not forcibly restricted to
    this scope.
    
    Check the LACE version before using any routines marked as "Available 
    in LACE vX.xx"
    
    

  (a) Plug-in Specific Routines
      -------------------------

    AddPlgRec( cName, cFile )
    
       - Add the plug-in's record to the PLUGIN.DBF file. 
         Calling this function with the parameters plgName() and plgFile()
         is the main task of the plgInstall routine.  


         
 Available in LACE v1.04:
    AddPlgHelp( cHlpFile ) 
      cHlpFile    - This is the base name of the plugin's help file.
                    Use this in PlgInstall
                    EG: Pass "MERGE" to import "MERGE.CNT" which
                        refers to "MERGE.HLP"
    RemPlgHelp( cHlpFile ) 
      cHlpFile    - This is the base name of the plugin's help file.
                    Use this in PlgUnInst
         
 Available in LACE v1.03:
    AddMnuItem ( cMenuID, cAbb, cItemString, cDo, cMsg, nAccLevel )
      cMenuID     -	Name of menu to put item on
      cAbb        -	3 Char Plugin Abbreviation    
      cItemString -	Item's Display string (as it appears on menu)
      cDo         -	String to "DO ..."  (this string gets macro replaced
      				next to the characters "DO ", so it should start with
      				your plug-in's routine name. )
      cMsg		  -	The message to display at the bottom of the screen
      				when this item is highlighted
      nAccLevel   -	Min. Access Level necessary to see item (0 for any)
        
        
    The following routines are "To Be Written":
 NotYet:   
    NewSubMenu ( cSubMenuID, cTitle, nRow, nCol ) 
      - Create a free-standing menu

       
 Available in LACE v1.02:
    AddSubMenu ( cMenuID, cSubMenuID, cSubMenu, cAbb, 
                 cTitle, nRow, nCol, cMsg, nAccLevel, nScheme )
      - Create a menu as a submenu 
          item from another menu
          
      cMenuID     -	ID of menu to put submenu on
      cSubMenuID  -	ID of Submenu to Create
      cSubMenu    -	Submenu Item's Display string (as it appears on menu)
      cAbb        -	3 Char Plugin Abbreviation    
      cTitle      - Title to appear at top of Sub Menu
      nRow
      nCol
      cMsg		  -	The message to display at the bottom of the screen
      				when this item is highlighted
      nAccLevel   -	Min. Access Level necessary to see item (0 for any)
      nScheme     -	Scheme Number                 (optional Default=22)
      

 NotYet:   
    DelMnuItem ( cMenu, cItemString, cDo )
      - Only Two Parameters need to be non-blank
      
 NotYet:   
    DelSubMenu ( cSubMenu )
      - All referances to the submenu will be removed (including items
        on other menues that load the submenu)



  (b) General LACE Routines
      ---------------------
    
    These routines are used extensively throughout LAS and, now as
    part of the LACE specification, are expected to be very useful in
    writing Plug-ins.
    

    wExplode( cName, nSROW, nSCOL, nEROW, nECOL, cTITLE, nScheme, lborder, lhide, lshadow )

           cName  - Window name to create.
           nSROW  - starting row   
           nSCOL  - starting column
           nEROW  - ending row     
           nECOL  - ending column  
           cTITLE - window title   
           
      These parameters are optional:
           nScheme- Color scheme to use (optional)
           lBorder- (defa: .t.) causes raised look border for 3D look.
           lHide  - (defa: .t.) causes an "ACTIVATE...NOSHOW"         
           lshadow- (defa: .t.) causes no shadow                      
           
     - wExplode creates a window for you (optionally with LAS's chiseled 
         border).  It also maintains the current help line window (MSGWINx)
         and other color status variables.  In order not to mess up higher
         level windows, any routine that uses wExplode need to call 
         certain stack maintenance routines:
               do ProcEnter - Call First
               do ProcExit  - Call Last 
                    (ProcExit can take as a parameter the name of a window
                     to close; tolerant of window not existing)

     
    SetPrim( cPrimaryFile )
    
           cPrimaryFile - the file to make the Parent in the several 
                          Relations necessary for multi-season support
                          
                          Values: "PLAYER"
                                  "PLYREG"  - Most commonly used
                                  "MEMBER"
                                  "MEMREG"
                                  
           Note: 1) This routine sets filters, indexes and relations on
                 ALL FOUR tables to reflect the proper cascading of 
                 relations.  
                 
                 2) If you "DO SETPRIM with 'PLAYER'", (or "MEMBER")
                 issue a "SET FILTER TO" before using PLAYER (or MEMBER) 
                 as the target of a relation.  The default filter does not
                 work as a target because it tries to limit Player 
                 (or Member) to only those in this season (thus relying 
                 on PLYREG or MEMREG to 'track' with it) and, since Foxpro
                 doesn't cascade the relation before the filter is evaluated
                 for a record, the filter always fails, and no records 
                 show up.
                 
--------------------------------------------------------------------------


                                   - 6 -                       Back to Top


(6) Building a VFP .APP File
    ------------------------  
    
    To build the .APP to rename .PLG for you VFP LAS plugin, you need first
    to have a project that tells VFP what to include in the application
    .APP file.  Projects are stored in files .PJX & .PJT, which constitute 
    the table and memo file that store the information about a project.  
    
    To create a project, use the command:  MODIFY PROJECT projectname
    
    If you don't already have a project by that name, it will be created.  
    You then must go to the Code..Programs part of the hierarchy and "Add" your
    main .PRG file, along with any other procedure files, reports (.FRX & .FRT) 
    or read-only tables, etc. that you might have.  
    
    After you have the project created, you can create the .APP file with
    the command: BUILD APP appfilename FROM projectfilename
    We usually create a program called "RELEASE.PRG" for each plugin which
    assembles all the important pieces, then builds the APP and renames it,
    and so on.
    
    Using the .APP packaging method, you can really create quite complicated 
    plugins that take full advantage of the VFP environment!
    
  (a) Including External Routines
      ---------------------------
      
      The Visual Foxpro compiler will complain when trying to build an .APP
      if it references routines that don't exist in the .PRG files.  The only 
      way to resolve these errors (so that you can see only the errors you 
      care about) is by making a stub procedure file which contains dummy 
      procedures for all the routines you want to use.  Include this "header"
      program in your project, and mark it "excluded" (so that when actually
      running, your plugin uses the LACE routines instead).  In our
      development, we usually use the "Release" program as this stub file,
      and list the stub routines at the end.
                 
                 
--------------------------------------------------------------------------


                                   - 6 -                       Back to Top


(7) Plug-in Abbreviations
    ---------------------  
    
    All American SportsWare plug-ins each get a three character 
    abbreviation for identification.  This identification is used 
    in various areas and tables to identify additions made by specific 
    plug-ins.  Some of these areas are the MENUES.DBL menu table, the 
    MENUITEM.DBL menu items table, the LAS.HLP help file, and the 
    PLUGINS.DBF plug-in register.  The abbreviation is ususally 
    entered into a field called "TAG" (or similar) in the format 
    "PLUGIN-"+abbreviation.  Some of the AAS abbreviations follow:
    
      LEX - League Explorer
      MRG - Merge
      PAS - Player Passes
      TIP - Tip of the Day
      FON - Phone Tree Generator
      USH - USA Hockey Roster
      QIF - Quicken Export
      PID - Picture IDs