/*------------------------------------------------------------------------
   File        : dynamicformImplImpl
   Purpose     : 
   Syntax      : 
   Description : 
   Author(s)   : walter.riechsteiner
   Created     : Wed Nov 19 13:23:38 CET 2025
   Notes       : 
 ----------------------------------------------------------------------*/


BLOCK-LEVEL ON ERROR UNDO, THROW.

USING OpenEdge.Core.String                          FROM PROPATH.

USING OpenEdge.Net.HTTP.IHttpResponse               FROM PROPATH.
USING OpenEdge.Net.HTTP.StatusCodeEnum              FROM PROPATH.

USING OpenEdge.Web.IWebRequest                      FROM PROPATH.
USING OpenEdge.Web.WebResponseWriter                FROM PROPATH.
USING OpenEdge.Web.WebHandler                       FROM PROPATH.

USING Progress.Json.ObjectModel.ObjectModelParser   FROM PROPATH.
USING Progress.Json.ObjectModel.JsonObject          FROM PROPATH.
USING Progress.Json.ObjectModel.JsonArray           FROM PROPATH.
USING Progress.Lang.ParameterList                   FROM PROPATH.

USING src.ch.adprime.gemis.WebHandlerUtilities      FROM PROPATH.

USING utilities.selectboxHandler                    FROM PROPATH.
USING utilities.utilitiesHandler                    FROM PROPATH.

CLASS admin.dynamicformImpl INHERITS WebHandler: 

    DEFINE VARIABLE oResponse            AS IHttpResponse        NO-UNDO.         
    DEFINE VARIABLE oJsonData            AS JsonObject           NO-UNDO.
    DEFINE VARIABLE oWriter              AS WebResponseWriter    NO-UNDO.
    DEFINE VARIABLE oBody                AS STRING               NO-UNDO.
    DEFINE VARIABLE cDefautlCharSet      AS CHARACTER            NO-UNDO INIT 'UTF-8'.
    DEFINE VARIABLE oParser              AS ObjectModelParser    NO-UNDO.           
    DEFINE VARIABLE cCorralationID       AS CHARACTER            NO-UNDO.
    DEFINE VARIABLE cContent-Type        AS CHARACTER            NO-UNDO.
    DEFINE VARIABLE cQueryString         AS CHARACTER            NO-UNDO.
    
    DEFINE VARIABLE lcJsonString         AS LONGCHAR             NO-UNDO.
    DEFINE VARIABLE lcString             AS LONGCHAR             NO-UNDO.    
    DEFINE VARIABLE cString              AS CHARACTER            NO-UNDO.
    
    DEFINE VARIABLE ccompany             AS CHARACTER            NO-UNDO.
    DEFINE VARIABLE cUser_Name           AS CHARACTER            NO-UNDO.
    DEFINE VARIABLE cAnzeigeName         AS CHARACTER            NO-UNDO.
    DEFINE VARIABLE ilanguage_id         AS INTEGER              NO-UNDO.
    DEFINE VARIABLE cSessionToken        AS CHARACTER            NO-UNDO.
    DEFINE VARIABLE cFunction            AS CHARACTER            NO-UNDO.
    DEFINE VARIABLE cFormId              AS CHARACTER            NO-UNDO.
    DEFINE VARIABLE cProgram             AS CHARACTER            NO-UNDO.
    DEFINE VARIABLE cFormUser            AS CHARACTER            NO-UNDO.
    DEFINE VARIABLE cFormColumns         AS CHARACTER            NO-UNDO.
    DEFINE VARIABLE cFileName            AS CHARACTER            NO-UNDO.
    DEFINE VARIABLE cFieldName           AS CHARACTER            NO-UNDO.
    DEFINE VARIABLE cUsers               AS CHARACTER            NO-UNDO INIT 'user,admin'.
    DEFINE VARIABLE cMaxHeight           AS CHARACTER            NO-UNDO.
    DEFINE VARIABLE iItemsPage           AS INTEGER              NO-UNDO.
    
    DEFINE VARIABLE cActiveSelection     AS CHARACTER            NO-UNDO.
    DEFINE VARIABLE lCompany             AS LOGICAL              NO-UNDO.
    DEFINE VARIABLE lActive              AS LOGICAL              NO-UNDO.
    DEFINE VARIABLE lWordindex           AS LOGICAL              NO-UNDO.
    DEFINE VARIABLE lSendChange          AS LOGICAL              NO-UNDO.
    
    DEFINE VARIABLE lcMessage            AS LONGCHAR             NO-UNDO.
    DEFINE VARIABLE cErrorNo             AS CHARACTER            NO-UNDO.
    DEFINE VARIABLE cLogFile             AS CHARACTER            NO-UNDO.
    
    DEFINE VARIABLE hError               AS HANDLE               NO-UNDO.
    DEFINE VARIABLE hBuffer              AS HANDLE               NO-UNDO.
    DEFINE VARIABLE hField               AS HANDLE               NO-UNDO.
    
    DEFINE VARIABLE cMethode             AS CHARACTER            NO-UNDO.
    DEFINE VARIABLE cClass               AS CHARACTER            NO-UNDO.
    DEFINE VARIABLE rClass               AS Progress.Lang.Class.
    DEFINE VARIABLE oHandler             AS Progress.Lang.Object NO-UNDO.
    DEFINE VARIABLE oParam               AS ParameterList        NO-UNDO.
    
    DEFINE VARIABLE oJsonIdent           AS JsonObject           NO-UNDO.
    DEFINE VARIABLE oJsonActiveSelectBox AS JsonObject           NO-UNDO.
    DEFINE VARIABLE oJsonMessageBox      AS JsonObject           NO-UNDO.
    DEFINE VARIABLE oJsonResponse        AS JsonObject           NO-UNDO.
        
    DEFINE VARIABLE outilitiesHandler    AS utilitiesHandler     NO-UNDO.
    DEFINE VARIABLE oselectboxHandler    AS selectboxHandler     NO-UNDO.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    CONSTRUCTOR PUBLIC dynamicformImpl (  ):
        SUPER ().
        
        hError            = ERROR-STATUS:HANDLE.
                
        outilitiesHandler = NEW utilitiesHandler().
        oselectboxHandler = NEW selectboxHandler().
        
        CATCH e AS Progress.Lang.Error:

        END CATCH.

        FINALLY:

        END FINALLY.

    END CONSTRUCTOR.


    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC VOID createJsonIdent(
        INPUT poRequest AS IWebRequest
        ):
            
        DEFINE VARIABLE cUser     AS CHARACTER NO-UNDO.
        
        DEFINE VARIABLE httBuffer AS HANDLE    NO-UNDO.
        
        outilitiesHandler:getHeaderData(
            INPUT  poRequest    ,
            OUTPUT ccompany     ,
            OUTPUT cUser_Name   ,
            OUTPUT cAnzeigeName ,
            OUTPUT ilanguage_id ,
            OUTPUT cSessionToken,
            OUTPUT cFunction    ,
            OUTPUT oJsonIdent   
            ).
        cFormId   = oJsonIdent:GetCharacter('formId').
        cFileName = ENTRY(1, cFormId, '_').
        //
        //  mögliche Benutzer für das durchsuchen von HTML-Dokumenten und Labeltexten ...
        //
        cUser = oJsonIdent:GetCharacter('H_user_name') NO-ERROR.
        IF NOT ERROR-STATUS:ERROR AND LOOKUP(cUser, cUsers, ',') = 0 THEN cUsers = cUser + ',' + cUsers.
        cUser = oJsonIdent:GetCharacter('user_name') NO-ERROR.
        IF NOT ERROR-STATUS:ERROR AND LOOKUP(cUser, cUsers, ',') = 0 THEN cUsers = cUser + ',' + cUsers.
        oJsonIdent:ADD('cUsers', cUsers).
        //
        //  Wenn ein UI Multi-Tab hat, wird es hier erstellt
        //
        RETURN.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC VOID createMultiTab(
        OUTPUT oJsonTabs    AS JsonArray
        ):
            
        DEFINE VARIABLE cTabGroup            AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE cHtmlUser            AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE ii                   AS INTEGER    NO-UNDO.
        
        DEFINE VARIABLE cTabProgram          AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE cHtmlFileName        AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE cKeyField            AS CHARACTER  NO-UNDO.
        
        DEFINE VARIABLE oJsonTab             AS JsonObject NO-UNDO.
        DEFINE VARIABLE oJsonMasterKeyFields AS JsonArray  NO-UNDO.
MESSAGE 'START MULTITAB'.                
        oJsonTabs = NEW JsonArray().

        FIND programs NO-LOCK 
            WHERE programs.formId = cFormId NO-ERROR.
        cTabGroup = programs.tab_group.
        cProgram  = programs.program.
            
        DO ii = 1 TO NUM-ENTRIES(cUsers, ','):
            cHtmlUser = ENTRY(ii, cUsers, ',').
            FIND FIRST htmldokumente
                WHERE htmldokumente.company     = ccompany
                AND   htmldokumente.user_name   = cHtmlUser
                AND   htmldokumente.language_id = ilanguage_id
                AND   htmldokumente.program     = cProgram NO-ERROR.
            IF AVAILABLE htmldokumente THEN LEAVE.
        END.                
            
        oJsonTab = NEW JsonObject().
        oJsonTab:ADD('tabIndex'   , 1). 
        oJsonTab:ADD('formId'     , htmldokumente.formId). 
        oJsonTab:ADD('title'      , htmldokumente.formtitle). 
        oJsonTab:ADD('programName', cprogram). 
        oJsonTab:ADD('isMain'     , programs.isMain).
        oJsonTabs:ADD(oJsonTab).
             
        FOR EACH programs NO-LOCK 
            WHERE programs.tab_group = cTabGroup
            AND   programs.tab_index > 1
                
            BY programs.tab_index:

            cTabProgram = programs.program.
            MESSAGE 'Tab-Gruppe' cTabGroup '-' cTabProgram.
            DO ii = 1 TO NUM-ENTRIES(cUsers, ','):
                cHtmlUser = ENTRY(ii, cUsers, ',').
                FIND FIRST htmldokumente
                    WHERE htmldokumente.company     = ccompany
                    AND   htmldokumente.user_name   = cHtmlUser
                    AND   htmldokumente.language_id = ilanguage_id
                    AND   htmldokumente.program     = cTabProgram NO-ERROR.
                IF AVAILABLE htmldokumente THEN LEAVE.
            END.
                
            cHtmlFileName = ENTRY(1, htmldokumente.formId, '_').
                                 
            oJsonTab = NEW JsonObject().
            oJsonTab:ADD('tabIndex'   , programs.tab_index). 
            oJsonTab:ADD('formId'     , htmldokumente.formId). 
            oJsonTab:ADD('title'      , htmldokumente.formtitle). 
            oJsonTab:ADD('programName', htmldokumente.program). 
            oJsonTab:ADD('isMain'     , programs.isMain).
            oJsonTab:ADD('tabType'    , programs.tabtype).
            oJsonTab:ADD('allowCreate', programs.allowCreate).
            oJsonTab:ADD('allowEdit'  , programs.allowedit).
            oJsonTab:ADD('allowDelete', programs.allowDelete).
            oJsonTab:ADD('allowCopy'  , programs.allowCopy).

            cKeyField = SUBSTITUTE('&1_address_id', 'addresses' /*cHtmlFileName*/).            
            oJsonMasterKeyFields = NEW JsonArray().
            oJsonMasterKeyFields:ADD(cKeyField).
            oJsonTab:ADD('masterKeyFields', oJsonMasterKeyFields).
                
            oJsonTabs:ADD(oJsonTab).
        END.
            
        // oJsonTabs:WRITE(lcString).
        MESSAGE 'ENDE MULTITAB'.        
        RETURN.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/
    
    METHOD OVERRIDE PROTECTED INTEGER HandleDelete(INPUT poRequest AS IWebRequest):
        
        DEFINE VARIABLE oJsonResult AS JsonObject NO-UNDO.

        DEFINE VARIABLE lRetVal     AS LOGICAL    NO-UNDO.
        DEFINE VARIABLE iRetVal     AS INTEGER    NO-UNDO.
        DEFINE VARIABLE ii          AS INTEGER    NO-UNDO.
        
        WebHandlerUtilities:getJsonFromRequest(INPUT poRequest, OUTPUT oJsonData) NO-ERROR.

        DO WHILE TRUE:
            iRetVal = processingInitFunction(
                INPUT  poRequest    ,
                OUTPUT oJsonResponse
                ).
            IF iRetVal =  0 THEN RETURN 0.
            IF iRetVal = -1 THEN LEAVE.
                
            IF iRetVal = 1 THEN responseOK(
                    INPUT oJsonResponse
                    ).
            RETURN 0.
        END.

        REPEAT TRANSACTION WHILE cFunction = 'delete' ON ERROR UNDO, LEAVE:
            rClass = Progress.Lang.Class:GetClass(cClass) NO-ERROR.
            oJsonIdent:Write(lcJsonString, FALSE).
            IF VALID-OBJECT(rClass) THEN 
            DO:
                oParam = NEW ParameterList(2).
                oParam:SetParameter(1, 'longchar' , 'INPUT', lcJsonString ) NO-ERROR.
                oParam:SetParameter(2, 'character', 'INPUT', cFunction    ) NO-ERROR.
                outilitiesHandler:evaluateErrorStatus(hError).

                oHandler = rClass:New(oParam) NO-ERROR.
                outilitiesHandler:evaluateErrorStatus(hError).
            END.
// oJsonData:WriteFile('C:\TEMP\dynamicform_delete_data.json', TRUE).                
            cMethode = 'deleteData'.
            lRetVal  = DYNAMIC-INVOKE ( oHandler, cMethode,
                INPUT  oJsonData   ,
                OUTPUT oJsonResult
                ) NO-ERROR.
            outilitiesHandler:evaluateErrorStatus(INPUT hError).
// MESSAGE lRetVal.
            oJsonResult:WRITE(lcString, FALSE).
//MESSAGE STRING(lcString).
            responseOK(
                INPUT oJsonResult
                ).
                
            RETURN 0.
        END.
                    
        oResponse             = NEW OpenEdge.Web.WebResponse().
        oResponse:StatusCode  = INTEGER(StatusCodeEnum:OK).
        oResponse:ContentType = "application/json;charset=utf-8".
                        
        oJsonResult:WRITE(lcJsonString, FALSE).
// oJsonResult:WriteFile(SUBSTITUTE('C:\TEMP\DYNAMIC_&1_Respons.json', cFunction), TRUE).
        
        oWriter = NEW WebResponseWriter(oResponse).
        oWriter:Open().
        oWriter:Write(lcJsonString).
        oWriter:Close().
    
        RETURN 0.
    
        CATCH e AS Progress.Lang.Error:
                
        END CATCH.
                
        FINALLY:
            DELETE OBJECT oHandler     NO-ERROR.
            DELETE OBJECT oResponse    NO-ERROR.
            DELETE OBJECT oWriter      NO-ERROR.
        END FINALLY.

    END METHOD.
    
    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD OVERRIDE PROTECTED INTEGER HandleGet (INPUT poRequest AS IWebRequest ):
        
        DEFINE VARIABLE oJsonSelectBoxes AS JsonObject NO-UNDO.
        DEFINE VARIABLE oJsonBox         AS JsonArray  NO-UNDO.
        DEFINE VARIABLE oJsonResult      AS JsonObject NO-UNDO.

        DEFINE VARIABLE cUser            AS CHARACTER  NO-UNDO.
        DEFINE VARIABLE lRetVal          AS LOGICAL    NO-UNDO.
        DEFINE VARIABLE ii               AS INTEGER    NO-UNDO.
        DEFINE VARIABLE iRetVal          AS INTEGER    NO-UNDO.
        
        DEFINE VARIABLE httBuffer        AS HANDLE     NO-UNDO.

        DO WHILE TRUE:
            iRetVal = processingInitFunction(
                INPUT  poRequest    ,
                OUTPUT oJsonResponse
                ).
            IF iRetVal =  0 THEN RETURN 0.
            IF iRetVal = -1 THEN LEAVE.
                
            IF iRetVal = 1 THEN responseOK(
                    INPUT oJsonResponse
                    ).
            RETURN 0.
        END.

        IF cFunction <> 'saveActiveFilter' THEN
        DO:
            outilitiesHandler:getActiveSelection(
                INPUT  oJsonIdent      ,
                INPUT  cFileName       ,
                OUTPUT cActiveSelection
                ).
            IF cActiveSelection <> '' THEN
            DO:
                IF NOT oJsonIdent:HAS('activeFilter') THEN oJsonIdent:ADD('activeFilter', cActiveSelection ).
                ELSE                                       oJsonIdent:SET('activeFilter', cActiveSelection ).
            END.
        END.

        DO WHILE cFunction = 'loaddata' AND cProgram <> '':
MESSAGE 'loaddata' cFileName.
            IF oJsonIdent:HAS('sortField') THEN 
            DO:
                DEFINE VARIABLE cSortField AS CHARACTER NO-UNDO.
                DEFINE VARIABLE cDirection AS CHARACTER NO-UNDO.
                    
                cSortField = oJsonIdent:GetCharacter('sortField').
                cDirection = oJsonIdent:GetCharacter('sortDirection').

                outilitiesHandler:writeSortfields(
                    INPUT  oJsonIdent   ,
                    INPUT  cFileName    ,
                    INPUT  cSortField   ,
                    INPUT  cDirection
                    ).
            END.

            rClass = Progress.Lang.Class:GetClass(cClass) NO-ERROR.
            oJsonIdent:Write(lcJsonString, FALSE).
            IF VALID-OBJECT(rClass) THEN 
            DO:
                oParam = NEW ParameterList(2).
                oParam:SetParameter(1, 'longchar',  'INPUT', lcJsonString ) NO-ERROR.
                oParam:SetParameter(2, 'character', 'INPUT', cFunction    ) NO-ERROR.
                outilitiesHandler:evaluateErrorStatus(hError).

                oHandler = rClass:New(oParam) NO-ERROR.
                outilitiesHandler:evaluateErrorStatus(hError).
            END.
                
            cMethode = 'getData'.
            lRetVal  = DYNAMIC-INVOKE ( oHandler, cMethode,
                OUTPUT oJsonResponse
                ) NO-ERROR.
            outilitiesHandler:evaluateErrorStatus(INPUT hError).
 
// oJsonResponse:WriteFile(SUBSTITUTE('C:\TEMP\Loaddata_response_&1.json', cProgram), TRUE).

            responseOK(
                INPUT oJsonResponse
                ).
                
            RETURN 0.
        END.

        DO WHILE cFunction = 'loaddataunique' AND cProgram <> '':
            MESSAGE 'START LOADDATAUNIQUE' cFileName.
            rClass   = Progress.Lang.Class:GetClass(cClass) NO-ERROR.
            oJsonIdent:Write(lcJsonString, FALSE).
            IF VALID-OBJECT(rClass) THEN 
            DO:
                oParam = NEW ParameterList(2).
                oParam:SetParameter(1, 'longchar',  'INPUT', lcJsonString ) NO-ERROR.
                oParam:SetParameter(2, 'character', 'INPUT', cFunction    ) NO-ERROR.
                outilitiesHandler:evaluateErrorStatus(hError).

                oHandler = rClass:New(oParam) NO-ERROR.
                outilitiesHandler:evaluateErrorStatus(hError).
            END.
                
            cMethode = 'getDataUnique'.
                // oHandler = rClass:NEW().
            lRetVal  = DYNAMIC-INVOKE ( oHandler, cMethode,
                OUTPUT oJsonResponse
                ) NO-ERROR.
// MESSAGE 'return from loaddataunique' lRetVal.
            outilitiesHandler:evaluateErrorStatus(INPUT hError).
 
// oJsonResponse:WriteFile('C:\TEMP\Loaddataunique_response.json', TRUE).
// oJsonResponse:ADD('selectOptionsFix', oJsonSelectBoxes).

            lRetVal = TRUE.
            LEAVE.
        END.

        DO WHILE cFunction = 'rebuild':
            rClass   = Progress.Lang.Class:GetClass(cClass) NO-ERROR.
            oJsonIdent:Write(lcJsonString, FALSE).
            IF VALID-OBJECT(rClass) THEN 
            DO:
                oParam = NEW ParameterList(2).
                oParam:SetParameter(1, 'longchar' , 'INPUT', lcJsonString ) NO-ERROR.
                oParam:SetParameter(2, 'character', 'INPUT', cFunction    ) NO-ERROR.
                outilitiesHandler:evaluateErrorStatus(hError).

                oHandler = rClass:New(oParam) NO-ERROR.
                outilitiesHandler:evaluateErrorStatus(hError).
            END.
                
            cMethode = 'rebuildData'.
            lRetVal  = DYNAMIC-INVOKE ( oHandler, cMethode,
                INPUT  oJsonData   ,
                OUTPUT oJsonResult
                ) NO-ERROR.
            outilitiesHandler:evaluateErrorStatus(INPUT hError).
MESSAGE 'Return bei rebuild' lRetVal.
            oJsonResult:write(lcString, FALSE).
MESSAGE STRING(lcString).
            responseOK(
                INPUT oJsonResult
                ).
                
            RETURN 0.

        END.
        
        DO WHILE cFunction = 'saveActiveFilter':
            cActiveSelection = oJsonIdent:GetCharacter('activeFilter').
// MESSAGE cFunction '-' cActiveSelection.
            outilitiesHandler:setActiveSelection(
                INPUT  oJsonIdent      ,
                INPUT  cFileName       ,
                INPUT  cActiveSelection
                ).
            
            oJsonResponse = NEW JsonObject().
            oJsonResponse:ADD('success', TRUE).
//                oJsonResponse:WRITE(lcJsonString, FALSE).
            
            lRetVal = TRUE.
            LEAVE.
        END.
        
        DO WHILE cFunction = 'lookup' AND cProgram <> '':
            cMethode = oJsonIdent:GetCharacter('lookupField') NO-ERROR.
            cMethode = REPLACE(cMethode, cFileName + '_', '').
            cClass   = 'utilities.lookupHandler'.
            
            ASSIGN
                rClass = Progress.Lang.Class:GetClass(cClass) NO-ERROR.

            oHandler = rClass:NEW() NO-ERROR.

            lRetVal = DYNAMIC-INVOKE ( oHandler, cMethode,
                INPUT  oJsonIdent  ,
                OUTPUT oJsonResult
                ) NO-ERROR.
            outilitiesHandler:evaluateErrorStatus(hError).
            oJsonResponse = oJsonResult.
            LEAVE.
        END.
                
        IF NOT lRetVal THEN 
        DO:
            lcString = oJsonMessageBox:GetLongchar('text').
            oJsonResponse = NEW JsonObject().
            oJsonResponse:ADD('success', FALSE).
            oJsonResponse:ADD('message', lcString).
            oJsonResponse:ADD('showMessage', oJsonMessageBox).
        END.

        oJsonResponse:WRITE(lcJsonString, FALSE).
        cContent-Type   = "application/json".
        cDefautlCharSet = 'utf-8'.
// IF cFunction = 'multitab' THEN oJsonResponse:WriteFile(SUBSTITUTE('C:\TEMP\dynamicform_get_response_&1.json', ETIME), TRUE).
        oBody = NEW STRING(lcJsonString) NO-ERROR.
        outilitiesHandler:evaluateErrorStatus(hError).
        WebHandlerUtilities:createHttpResponse(INPUT INTEGER(StatusCodeEnum:OK), INPUT oBody, INPUT cContent-Type, INPUT cDefautlCharSet, INPUT cCorralationID, OUTPUT oResponse) NO-ERROR.
        outilitiesHandler:evaluateErrorStatus(hError).
// oResponse:SetHeader(HttpHeaderBuilder:Build(cHeaderCorralationID):Value(cCorralationID):Header).

        
        oWriter = NEW WebResponseWriter(oResponse) NO-ERROR.
        outilitiesHandler:evaluateErrorStatus(hError).
        oWriter:Open() NO-ERROR. 
        outilitiesHandler:evaluateErrorStatus(hError).
        oWriter:Close(). 

        RETURN 0.
        
        CATCH e AS Progress.Lang.Error:

        END CATCH.

        FINALLY:
            DELETE OBJECT oHandler          NO-ERROR.
            DELETE OBJECT oSelectBoxHandler NO-ERROR.
            DELETE OBJECT oResponse         NO-ERROR.
            DELETE OBJECT oWriter           NO-ERROR.
            DELETE OBJECT oJsonSelectBoxes  NO-ERROR.
            DELETE OBJECT oJsonBox          NO-ERROR.
            DELETE OBJECT oParser           NO-ERROR.
            DELETE OBJECT oJsonResponse     NO-ERROR.
        END FINALLY.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD OVERRIDE PROTECTED INTEGER HandlePost(INPUT poRequest AS IWebRequest):
        
        DEFINE VARIABLE oJsonResult          AS JsonObject NO-UNDO.

        DEFINE VARIABLE lRetVal              AS LOGICAL    NO-UNDO.
        DEFINE VARIABLE iRetVal              AS INTEGER    NO-UNDO.
        DEFINE VARIABLE ii                   AS INTEGER    NO-UNDO.
        
        WebHandlerUtilities:getJsonFromRequest(INPUT poRequest, OUTPUT oJsonData) NO-ERROR.

        DO WHILE TRUE:
            iRetVal = processingInitFunction(
                INPUT  poRequest    ,
                OUTPUT oJsonResponse
                ).
            IF iRetVal =  0 THEN RETURN 0.
            IF iRetVal = -1 THEN LEAVE.
                
            IF iRetVal = 1 THEN responseOK(
                    INPUT oJsonResponse
                    ).
            RETURN 0.
        END.

        DO WHILE cFunction = 'change':
            rClass = Progress.Lang.Class:GetClass(cClass) NO-ERROR.
            oJsonIdent:Write(lcJsonString, FALSE).
            IF VALID-OBJECT(rClass) THEN 
            DO:
                oParam = NEW ParameterList(2).
                oParam:SetParameter(1, 'longchar' , 'INPUT', lcJsonString ) NO-ERROR.
                oParam:SetParameter(2, 'character', 'INPUT', cFunction    ) NO-ERROR.
                outilitiesHandler:evaluateErrorStatus(hError).

                oHandler = rClass:New(oParam) NO-ERROR.
                outilitiesHandler:evaluateErrorStatus(hError).
            END.
                
            cMethode = oJsonData:GetCharacter('changeAction').
// MESSAGE 'changeAction =' cMethode.
            lRetVal  = DYNAMIC-INVOKE ( oHandler, cMethode,
                INPUT  oJsonData    ,
                OUTPUT oJsonResponse
                ) NO-ERROR.
            outilitiesHandler:evaluateErrorStatus(INPUT hError).
            
            responseOK(
                INPUT oJsonResponse
                ).
                
            RETURN 0.
        END.

        REPEAT TRANSACTION WHILE cFunction = 'create' ON ERROR UNDO, LEAVE:
            rClass = Progress.Lang.Class:GetClass(cClass) NO-ERROR.
            oJsonIdent:Write(lcJsonString, FALSE).
            IF VALID-OBJECT(rClass) THEN 
            DO:
                oParam = NEW ParameterList(2).
                oParam:SetParameter(1, 'longchar' , 'INPUT', lcJsonString ) NO-ERROR.
                oParam:SetParameter(2, 'character', 'INPUT', cFunction    ) NO-ERROR.
                outilitiesHandler:evaluateErrorStatus(hError).

                oHandler = rClass:New(oParam) NO-ERROR.
                outilitiesHandler:evaluateErrorStatus(hError).
            END.
                
            cMethode = 'createData'.
// MESSAGE 'changeAction =' cMethode.
            lRetVal  = DYNAMIC-INVOKE ( oHandler, cMethode,
                INPUT  oJsonData    ,
                OUTPUT oJsonResponse
                ) NO-ERROR.
            outilitiesHandler:evaluateErrorStatus(INPUT hError).
            
            responseOK(
                INPUT oJsonResponse
                ).
                
            RETURN 0.

        END.
                    
        oResponse             = NEW OpenEdge.Web.WebResponse().
        oResponse:StatusCode  = INTEGER(StatusCodeEnum:OK).
        oResponse:ContentType = "application/json;charset=utf-8".
        
        oJsonResult:WRITE(lcJsonString, FALSE).
                            
        oWriter = NEW WebResponseWriter(oResponse).
        oWriter:Open().
        oWriter:Write(lcJsonString).
        oWriter:Close().
    
        RETURN 0.
    
        CATCH e AS Progress.Lang.Error:
                
        END CATCH.
                
        FINALLY:
            DELETE OBJECT oResponse     NO-ERROR.
            DELETE OBJECT oWriter       NO-ERROR.
            DELETE OBJECT oJsonResult   NO-ERROR.
        END FINALLY.

    END METHOD.
    
    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD OVERRIDE PROTECTED INTEGER HandlePatch(INPUT poRequest AS IWebRequest):
        
        DEFINE VARIABLE oJsonResult AS JsonObject NO-UNDO.

        DEFINE VARIABLE lRetVal     AS LOGICAL    NO-UNDO.
        DEFINE VARIABLE iRetVal     AS INTEGER    NO-UNDO.
        DEFINE VARIABLE ii          AS INTEGER    NO-UNDO.
        
        WebHandlerUtilities:getJsonFromRequest(INPUT poRequest, OUTPUT oJsonData) NO-ERROR.

        DO WHILE TRUE:
            iRetVal = processingInitFunction(
                INPUT  poRequest    ,
                OUTPUT oJsonResponse
                ).
            IF iRetVal =  0 THEN RETURN 0.
            IF iRetVal = -1 THEN LEAVE.
                
            IF iRetVal = 1 THEN responseOK(
                    INPUT oJsonResponse
                    ).
            RETURN 0.
        END.

        REPEAT TRANSACTION WHILE cFunction = 'update' ON ERROR UNDO, LEAVE:
            rClass   = Progress.Lang.Class:GetClass(cClass) NO-ERROR.
            oJsonIdent:Write(lcJsonString, FALSE).
            IF VALID-OBJECT(rClass) THEN 
            DO:
                oParam = NEW ParameterList(2).
                oParam:SetParameter(1, 'longchar' , 'INPUT', lcJsonString ) NO-ERROR.
                oParam:SetParameter(2, 'character', 'INPUT', cFunction    ) NO-ERROR.
                outilitiesHandler:evaluateErrorStatus(hError).

                oHandler = rClass:New(oParam) NO-ERROR.
                outilitiesHandler:evaluateErrorStatus(hError).
            END.
                
            cMethode = 'updateData'.
            lRetVal  = DYNAMIC-INVOKE ( oHandler, cMethode,
                INPUT  oJsonData   ,
                OUTPUT oJsonResult
                ) NO-ERROR.
            outilitiesHandler:evaluateErrorStatus(INPUT hError).
MESSAGE 'Return bri update' lRetVal.
oJsonResult:write(lcString, FALSE).
MESSAGE STRING(lcString).
            responseOK(
                INPUT oJsonResult
                ).
                
            RETURN 0.
        END.
                    
        oResponse             = NEW OpenEdge.Web.WebResponse().
        oResponse:StatusCode  = INTEGER(StatusCodeEnum:OK).
        oResponse:ContentType = "application/json;charset=utf-8".
                        
        oJsonResult:WRITE(lcJsonString, FALSE).
// oJsonResult:WriteFile(SUBSTITUTE('C:\TEMP\DYNAMIC_&1_Respons.json', cFunction), TRUE).
        
        oWriter = NEW WebResponseWriter(oResponse).
        oWriter:Open().
        oWriter:Write(lcJsonString).
        oWriter:Close().
    
        RETURN 0.
    
        CATCH e AS Progress.Lang.Error:
                
        END CATCH.
                
        FINALLY:
            
        END FINALLY.

    END METHOD.
    
    
    METHOD OVERRIDE PROTECTED INTEGER HandleNotAllowedMethod(INPUT poRequest AS IWebRequest):
        DEFINE VARIABLE result AS INTEGER NO-UNDO.
        MESSAGE "HandleNotAllowedMethod called" VIEW-AS ALERT-BOX.
        RETURN result.
    END METHOD.

    METHOD OVERRIDE PROTECTED INTEGER HandleNotImplemented(INPUT poRequest AS IWebRequest):
        DEFINE VARIABLE result AS INTEGER NO-UNDO.
        MESSAGE "HandleNotImplemented called" VIEW-AS ALERT-BOX.
        RETURN result.
    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC INTEGER processingInitFunction(
        INPUT  poRequest   AS IWebRequest, 
        OUTPUT oJsonReturn AS JsonObject
        ):
            
        DEFINE VARIABLE ii                   AS INTEGER    NO-UNDO.
        DEFINE VARIABLE cUser                AS CHARACTER  NO-UNDO.

        DEFINE VARIABLE oJsonBox             AS JsonArray  NO-UNDO.            
        DEFINE VARIABLE oJsonSelectBoxes     AS JsonObject NO-UNDO.            
        DEFINE VARIABLE oJsonTabs            AS JsonArray  NO-UNDO.
        DEFINE VARIABLE oJsonTab             AS JsonObject NO-UNDO.
        DEFINE VARIABLE oJsonMasterKeyFields AS JsonArray  NO-UNDO.

            
        DEFINE VARIABLE httBuffer            AS HANDLE     NO-UNDO.
        
        outilitiesHandler:getHeaderData(
            INPUT  poRequest    ,
            OUTPUT ccompany     ,
            OUTPUT cUser_Name   ,
            OUTPUT cAnzeigeName ,
            OUTPUT ilanguage_id ,
            OUTPUT cSessionToken,
            OUTPUT cFunction    ,
            OUTPUT oJsonIdent   
            ).
        cFormId   = oJsonIdent:GetCharacter('formId') NO-ERROR.
        cFileName = ENTRY(1, cFormId, '_').
        IF NOT oJsonIdent:has('user_name') THEN oJsonIdent:add('user_name', cUser_Name).
        //
        //  mögliche Benutzer für das durchsuchen von HTML-Dokumenten und Labeltexten ...
        //
        cUser = oJsonIdent:GetCharacter('H_user_name') NO-ERROR.
        IF NOT ERROR-STATUS:ERROR AND LOOKUP(cUser, cUsers, ',') = 0 THEN cUsers = cUser + ',' + cUsers.
        cUser = oJsonIdent:GetCharacter('user_name') NO-ERROR.
        IF NOT ERROR-STATUS:ERROR AND LOOKUP(cUser, cUsers, ',') = 0 THEN cUsers = cUser + ',' + cUsers.
        oJsonIdent:ADD('cUsers', cUsers).
        //
        //  Wenn ein UI Multi-Tab hat, wird es hier erstellt
        //
        DO WHILE cFunction='multitab':
            createMultiTab(
                OUTPUT oJsonTabs
                ).
                
            oJsonResponse = NEW JsonObject().
            oJsonResponse:ADD('tabs', oJsonTabs).
            responseOK(oJsonResponse). 
            RETURN 0.
        END.
        //
        //  wenn die Tabelle(File) das Feld active enthält, soll der activeFilter activiert werden
        //
        CREATE BUFFER hBuffer FOR TABLE cFilename NO-ERROR.
        hField = hBuffer:BUFFER-FIELD('active') NO-ERROR.
        IF  NOT ERROR-STATUS:ERROR AND 
            VALID-HANDLE(hField)   THEN lActive = TRUE.
        //
        //  wenn die Tabelle(File) das Feld wordindex enthält, muss am Ende der WordIndex aufgebaut werden
        //
        hField = hBuffer:BUFFER-FIELD('wordindex') NO-ERROR.
        IF  NOT ERROR-STATUS:ERROR AND 
            VALID-HANDLE(hField)   THEN lWordIndex = TRUE.
            
        DELETE OBJECT hBuffer.
        
        iItemsPage = 50.
        cMaxHeight = '250px'.
        cProgram = outilitiesHandler:getProgramName (
            INPUT        oJsonIdent  ,
            INPUT        cUsers      ,
            OUTPUT       cFormUser   ,
            OUTPUT       cformColumns,
            INPUT-OUTPUT iItemsPage  ,
            INPUT-OUTPUT cMaxHeight
            ).

        IF cProgram = '' THEN
        DO:
            cString = oJsonIdent:GetCharacter('formId').
            outilitiesHandler:createErrorBox(
                INPUT  oJsonIdent   ,
                INPUT  '2001'       ,
                INPUT  cString,  /* Parameters */
                OUTPUT oJsonMessageBox
                ).
            oJsonResponse = NEW JsonObject().
            oJsonResponse:ADD('showMessage', oJsonMessageBox).
            responseNOTOK(oJsonResponse). 
            RETURN 0.
        END.

        oJsonIdent:ADD('program'       , cProgram  ).
        oJsonIdent:ADD('itemsPerPage'  , iItemsPage).
        oJsonIdent:ADD('tableMaxHeight', cMaxHeight).
        oJsonIdent:ADD('formUser'      , cFormUser ).
        
        cErrorNo   = ''.

        FIND programs NO-LOCK 
            WHERE programs.program = cProgram NO-ERROR.
        IF NOT AVAILABLE programs THEN LEAVE.
            
        cClass      = programs.program_class.
        lSendChange = programs.sendChangeRecord.
        //
        //  Nur bei Function "init" müssen fixe Selectboxen
        //  und UI - Parameter ermittelt werden
        //        
        IF cFunction <> 'init' THEN RETURN -1.
        //
        //  Es sollen alle Fixen Selctboxen erstellet werden
        //
        oJsonSelectBoxes  = NEW JsonObject().
        FOR EACH selectboxfields NO-LOCK
            WHERE selectboxfields.company       = ccompany
            AND   selectboxfields.program       = cFormId
            AND   selectboxfields.user_name     = cFormUser
            AND   selectboxfields.boxfieldsFix <> '':

            DO ii = 1 TO NUM-ENTRIES(selectboxfields.boxfieldsFix, ';'):
                cFieldName = ENTRY(ii, selectboxfields.boxfieldsFix, ';').
                cFileName  = ENTRY(1, cFieldName, '_').

                IF cFieldName MATCHES('*company*') THEN 
                DO:
                    oJsonBox  = NEW JsonArray().
                    httBuffer = oSelectboxHandler:getSelboxCompany(INPUT cFileName).
                    httBuffer:WRITE-JSON ('JsonArray', oJsonBox).
                    oJsonSelectBoxes:ADD(cFieldName, oJsonBox).
                    NEXT.
                END.
            
                IF cFieldName MATCHES('*language_id*') THEN 
                DO:
                    oJsonBox  = NEW JsonArray().
                    httBuffer = oSelectboxHandler:getSelboxLanguage(INPUT cFileName) NO-ERROR.
                    httBuffer:WRITE-JSON ('JsonArray', oJsonBox) NO-ERROR.
                    oJsonSelectBoxes:ADD(cFieldName, oJsonBox) NO-ERROR.
                    NEXT.
                END.
                    
                IF cFieldName MATCHES('*user_name*') THEN 
                DO:
                    oJsonBox  = NEW JsonArray().
                    httBuffer = oSelectboxHandler:getSelboxUsers(INPUT cFileName).
                    httBuffer:WRITE-JSON ('JsonArray', oJsonBox).
                    oJsonSelectBoxes:ADD(cFieldName, oJsonBox).
                    NEXT.
                END.
                    
                IF cFieldName MATCHES('*table_name*') THEN 
                DO:
                    oJsonBox  = NEW JsonArray().
                    httBuffer = oSelectboxHandler:getSelboxTables(INPUT cFileName).
                    httBuffer:WRITE-JSON ('JsonArray', oJsonBox).
                    oJsonSelectBoxes:ADD(cFieldName, oJsonBox).
                    NEXT.
                END.
                        
                oselectboxHandler:getSelectBoxData(
                    INPUT  oJsonIdent,
                    INPUT  cFieldName,
                    OUTPUT oJsonBox
                    ).

                oJsonSelectBoxes:ADD(cFieldName, oJsonBox).
            END.
        END.

        oJsonReturn = NEW JsonObject().
        oJsonReturn:ADD('selectOptionsFix', oJsonSelectBoxes).
        oJsonReturn:ADD('tableMaxHeight'  , cMaxHeight      ).
        oJsonReturn:ADD('itemsPerPage'    , iItemsPage      ).
        oJsonReturn:ADD('formColumns'     , cFormColumns    ).
        oJsonReturn:ADD('lSearch'         , lWordIndex      ).
        oJsonReturn:ADD('hasRecordChange' , lSendChange     ).
        //
        //  Wenn die Tabelle das Feld active hat, wird die SelectBox für den activ-Filter gefüllt
        //
        IF lActive THEN 
        DO:
            outilitiesHandler:getActiveSelection(
                INPUT  oJsonIdent,
                INPUT  cFileName ,
                OUTPUT cActiveSelection
                ).
                
            oJsonReturn:ADD("activeFilter"    , cActiveSelection).
            oJsonReturn:ADD("hasActiveField"  , lActive         ).
                    
            oJsonActiveSelectBox = NEW JsonObject().
            FOR EACH labeltexte NO-LOCK 
                WHERE labeltexte.company     = ccompany
                AND   labeltexte.user_name   = cFormUser
                AND   labeltexte.program     = 'Labels'
                AND   labeltexte.table_name  = 'table'
                AND   labeltexte.field_name BEGINS 'LBL_FILTER'
                AND   labeltexte.language_id = ilanguage_id :
                oJsonActiveSelectBox:ADD(CAPS(labeltexte.field_name), labeltexte.headlabel).
            END.
            oJsonReturn:ADD('activeFilterLabels', oJsonActiveSelectBox).
            
        END.
        //
        //  Sortfelder auf start (keine Felder) stellen.
        //
        outilitiesHandler:writeSortfields(
            INPUT  oJsonIdent   ,
            INPUT  cFileName    ,
            INPUT  ''           ,   //  cSortField
            INPUT  ''               //  cDirection
            ) NO-ERROR.
                
// oJsonReturn:WriteFile(SUBSTITUTE('C:\Temp\dynamicform_init_&1_return.json', cProgram), TRUE).
        RETURN 1.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC VOID responseNOTOK(
        INPUT oJsonResponse AS JsonObject
        ):

        DEFINE VARIABLE oMessage AS JsonObject.
            
        oJsonResponse:ADD('success', FALSE).
        
        IF oJsonResponse:HAS('showMessage') THEN 
        DO:
            oMessage = oJsonResponse:GetJsonObject('showMesage').
            lcString = oMessage:GetLongchar('text').
            oJsonResponse:ADD('message', lcString).
        END.
        
        oResponse             = NEW OpenEdge.Web.WebResponse().
        oResponse:StatusCode  = INTEGER(StatusCodeEnum:OK).
        oResponse:ContentType = "application/json;charset=utf-8".
        oWriter               = NEW WebResponseWriter(oResponse).
        
        oJsonResponse:WRITE(lcJsonString, FALSE). 
        MESSAGE 'responsOK oResponse ->' STRING(lcJsonString).
        oWriter:Open().
        oWriter:Write(lcJsonString).
        oWriter:Close().
        
        RETURN.

    END METHOD.

    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/

    METHOD PUBLIC VOID responseOK(
        INPUT oJsonReturn AS JsonObject
        ):

        oResponse             = NEW OpenEdge.Web.WebResponse()   NO-ERROR.
        oResponse:StatusCode  = INTEGER(StatusCodeEnum:OK)       NO-ERROR.
        oResponse:ContentType = "application/json;charset=utf-8" NO-ERROR.
        oWriter               = NEW WebResponseWriter(oResponse) NO-ERROR.
        
        oJsonReturn:WRITE(lcJsonString, FALSE).

        oWriter:Open() NO-ERROR.
        outilitiesHandler:evaluateErrorStatus(hError).
        oWriter:Write(lcJsonString) NO-ERROR.
        outilitiesHandler:evaluateErrorStatus(hError).
        oWriter:Close().
        
        RETURN.

    END METHOD.

    DESTRUCTOR PUBLIC dynamicformImpl ( ):

        DELETE OBJECT oWriter       NO-ERROR.
        DELETE OBJECT oResponse     NO-ERROR.
        DELETE OBJECT oHandler      NO-ERROR.
            
    END DESTRUCTOR.

END CLASS.