      **  CLAIM15R -- This is the insurance claim demo program, updated to use
      **              a GUI display, and to classify images with Watson
      **
      **  Requires HTTPAPI, YAJL and Profound UI.
      **
      **  This version uses the YAJL tree API. For the DATA-INTO version
      **  see CLAIM15R.
      **
     H DFTACTGRP(*NO)
     H BNDDIR('HTTPAPI': 'YAJL')

     FCLAIM15D  CF   E             WORKSTN
     F                                     SFile(CLAIMSFL : RRN)
     F                                     Handler('PROFOUNDUI(HANDLER)')

     FCLAIMSP   UF A E           K DISK
     FCLAIMS2L  IF   E           K DISK    Rename(CLAIMS : CLAIMS2)

      /copy HTTPAPI_H
      /copy YAJL_H
      /copy QRPGLEINC,IFSIO_H

     D rrn             S             10I 0
     D program         S             10A
     D action          S             10A   Varying
     D done            S               N

     D classify_t      ds                  qualified
     D                                     template
     D   code                        10i 0 inz(1)
     D   errMsg                     500a   varying inz('')
     D   class                      256a   varying inz('')
     D   score                        9p 7 inz(0)

     D obj             ds                  likeds(classify_t)

     C* Keep running until F3=Exit is used
     C                   Dow       Not *In03
     C
     C* Load claims subfile
     C                   ExSr      LoadSubfile
     C
     C* Show main claims subfile screen
     C                   Write     BOTTOM
     C                   ExFmt     CLAIMCTL
     C                   Eval      Action = ''
     C
     C* Test if a subfile record was selected by user
     C                   ReadC     CLAIMSFL
     C                   If        Not %Eof()
     C                   Select
     C                   When      Option = '2'
     C                   Eval      Action = 'change'
     C                   ExSr      LoadDetails
     C                   ExSr      ShowDetails
     C                   If        Not *In03 and Not *In12
     C                   ExSr      Save
     C                   EndIf
     C                   When      Option = '4'
     C                   Eval      Action = 'delete'
     C                   ExSr      LoadDetails
     C                   ExSr      DoDelete
     C                   When      Option = '5'
     C                   Eval      Action = 'display'
     C                   ExSr      LoadDetails
     C                   ExSr      ShowDetails
     C                   EndSL
     C                   EndIf
     C
     C* Add Record Processing
     C                   If        *In06
     C                   Eval      Action = 'add'
     C                   ExSr      NewRecord
     C                   ExSr      ShowDetails
     C                   If        Not *In03 and Not *In12
     C                   ExSr      Save
     C                   EndIf
     C                   EndIf
     C
     C                   EndDo
     C
     C                   Eval       *InLr = *On                                 End Program


     C*=======================================================================
     C* Load Claims Subfile
     C*=======================================================================
     C     LoadSubfile   BegSr
     C
     C* Clear Subfile
     C                   Eval      RRN = 0
     C                   SetOn                                        70        Clear Subfile
     C                   Write     CLAIMCTL
     C                   SetOff                                       70
     C
     C* Read first record
     C                   If        C1DESC = ''
     C     C1NUMBER      SetLL     CLAIMS
     C                   Read(n)   CLAIMS
     C                   Else
     C     C1DESC        SetLL     CLAIMS2
     C                   Read      CLAIMS2
     C                   EndIf
     C
     C                   Dow       Not %Eof()
     C* Write to subfile
     C                   Add       1             RRN
     C                   Eval      Option = ''
     C                   Eval      S1NUMBER = CMNUMBER
     C                   Eval      CMMDY = %Dec(CMDATE : *MDY)
     C                   Write     CLAIMSFL
     C
     C* Read next record
     C                   If        C1DESC = ''
     C                   Read(n)   CLAIMS
     C                   Else
     C                   Read      CLAIMS2
     C                   EndIf
     C                   EndDo
     C
     C                   EndSr


     C*=======================================================================
     C* Load Claim Details
     C*=======================================================================
     C     LoadDetails   BegSr
     C
     C                   If        Action = 'change'
     C     S1NUMBER      Chain     Claims
     C                   SetOff                                       80        No Protect
     C                   Else
     C                   SetOn                                        80        Protect
     C     S1NUMBER      Chain(n)  Claims
     C                   EndIf
     C
     C                   If        %Found()
     C                   Eval      CMTOTEST = CMEQEST + CMOTHEST + CMPROPEST
     C                   Eval      CMTOTCOST = CMEQCOST + CMOTHCOST + CMPROPCOST
     C                   Else
     C                   Eval      CMTOTEST = 0
     C                   Eval      CMTOTCOST = 0
     C                   EndIf
     C
     C                   Eval      CMMDY = %Dec(CMDATE : *MDY)
     C
     C                   Eval      imagefile = %Char(S1NUMBER) + '.jpg'
     C
     C                   EndSr


     C*=======================================================================
     C* Show Claim Details
     C*=======================================================================
     C     ShowDetails   BegSr
     C
     C                   Eval      Message = Action
     C
     C                   Dou       done = *On
     C
     C
     C                   Eval      Program = ''
     C                   Eval      UploadInfo = '000'
     C                   Eval      done = *on
     C                   ExFmt     DETAIL
     C
     C                   If        *In06                                        Damages
     C                   Eval      Program = 'CLAIM22R'
     C                   EndIf
     C
     C                   If        *In07                                        Work Orders
     C                   Eval      Program = 'CLAIM23R'
     C                   EndIf
     C
     C                   If        *In08                                        Injured
     C                   Eval      Program = 'CLAIM24R'
     C                   EndIf
     C
     C                   If        *In09                                        Police
     C                   Eval      Program = 'CLAIM25R'
     C                   EndIf
     C
     C                   If        *In10                                        Towing
     C                   Eval      Program = 'CLAIM26R'
     C                   EndIf
     C
     C                   If        *In11                                        Notes
     C                   Eval      Program = 'CLAIM27R'
     C                   EndIf
     C
     C                   If        *In14                                        Photos
     C                   Eval      Program = 'CLAIM28R'
     C                   EndIf
     C
     C                   If        *In15                                        Documents
     C                   Eval      Program = 'CLAIM29R'
     C                   EndIf
     C
     C                   If        Program <> ''
     C                   Eval      done = *off
     C                   Call      Program
     C                   Parm                    CMNUMBER
     C                   EndIf
     C
     C                   If        UploadInfo = '001'                           1 file uploaded
     C                   Eval      done = *Off

      // --------------------------------------------------------
      // New Code for recognizing image:
     C                   eval      cmmotor    = 'N'
     C                   eval      cmflattire = 'N'
     C                   eval      cmbrokenw  = 'N'
     C                   eval      cmvandal   = 'N'
     C                   eval      cmpedestr  = 'N'
     C
     C                   eval      obj = watson_classify(imagefile)
     C                   if        obj.score > 0.75
     C
     C                   select
     C                   when      obj.class = 'motorcycleaccident'
     C                   eval      cmmotor = 'Y'
     C                   when      obj.class = 'flattire'
     C                   eval      cmflattire = 'Y'
     C                   when      obj.class = 'brokenwindshield'
     C                   eval      cmbrokenw = 'Y'
     C                   when      obj.class = 'vandalism'
     C                   eval      cmvandal = 'Y'
     C                   when      obj.class = 'pedestrian'
     C                   eval      cmpedestr = 'Y'
     C                   endsl
      // End of New Code
      // --------------------------------------------------------

     C                   endif

     C
     C                   EndIf
     C
     C                   EndDo
     C
     C                   EndSr


     C*=======================================================================
     C* Save Changes
     C*=======================================================================
     C     Save          BegSr
     C
     C                   Eval      CMDATE = %Date(CMMDY : *MDY)
     C
     C                   If        Action = 'add'
     C                   Write     CLAIMS
     C                   EndIf
     C
     C                   If        Action = 'change'
     C                   Update    CLAIMS
     C                   EndIf
     C
     C                   EndSr


     C*=======================================================================
     C* Process Delete Option
     C*=======================================================================
     C     DoDelete      BegSr
     C
     C                   ExFmt     ConfirmDel
     C                   If        Not *In12
     C     CMNUMBER      Chain     CLAIMS
     C                   If        %Found()
     C                   Delete    CLAIMS
     C                   EndIf
     C                   EndIf
     C
     C                   EndSr


     C*=======================================================================
     C* Create New Record
     C*=======================================================================
     C     NewRecord     BegSr
     C
     C                   Eval      CMNUMBER = 0
     C     *HiVal        SetGT     CLAIMS
     C                   ReadP(n)  CLAIMS
     C                   Eval      S1NUMBER = CMNUMBER
     C                   Eval      CMNUMBER = S1NUMBER + 1
     C                   Eval      imagefile = %Char(CMNUMBER) + '.jpg'
     C
     C                   SetOff                                       80        No Protect
     C                   Eval      CMDATE = %Date()
     C                   Eval      CMMDY = %Dec(CMDATE : *MDY)
     C                   Time                    CMTIME
     C                   Eval      CMDESC     = ''
     C                   Eval      CMUNITS    = 0
     C                   Eval      CMINJURED  = 0
     C                   Eval      CMHITRUN   = 'N'
     C                   Eval      CMCOMPLETE = 'N'
     C                   Eval      CMACTYPE   = ''
     C                   Eval      CMCOUNTY   = ''
     C                   Eval      CMADDR2    = ''
     C                   Eval      CMADDR1    = ''
     C                   Eval      CMCITY     = ''
     C                   Eval      CMSTATE    = ''
     C                   Eval      CMZIP      = 0
     C                   Eval      CMEQEST    = 0
     C                   Eval      CMOTHEST   = 0
     C                   Eval      CMPROPEST  = 0
     C                   Eval      CMEQCOST   = 0
     C                   Eval      CMOTHCOST  = 0
     C                   Eval      CMPROPCOST = 0
     C                   Eval      CMMOTOR    = 'N'
     C                   Eval      CMFLATTIRE = 'N'
     C                   Eval      CMBROKENW  = 'N'
     C                   Eval      CMVANDAL   = 'N'
     C                   Eval      CMPEDESTR  = 'N'
     C
     C                   EndSr

       dcl-proc watson_classify;

          dcl-pi *n likeds(classify_t);
             imageName varchar(256) const;
          end-pi;

          dcl-c WATSON_API_KEY '< PUT YOUR API KEY HERE >';

          dcl-s imagePath   varchar(256);
          dcl-s params      varchar(256);
          dcl-s form        pointer;
          dcl-s contentType char(64);
          dcl-s tempFile    varchar(256);
          dcl-s rc          int(10);
          dcl-s docNode     like(yajl_val);
          dcl-s topClass    like(yajl_val);
          dcl-s node        like(yajl_val);
          dcl-s response    varchar(100000);
          dcl-s errMsg      varchar(500);
          dcl-s url         varchar(500);

          dcl-ds result likeds(classify_t) inz;
          http_debug(*on: '/tmp/watson-claim15r.txt');

          imagePath = '/www/profoundui/htdocs/profoundui/userdata/'
                    + 'images/claims/' + %trim(imageName);

          // Create a JSON document containing the
          //  parameters to the "classify" API:

          yajl_genOpen(*off);
          yajl_beginObj();                             // {
          yajl_beginArray('classifier_ids');           //   "classifier_ids": [
          yajl_addChar('insuranceclaims_2105717953');  //       "id-goes-here"
          yajl_endArray();                             //   ]
          yajl_endObj();                               // }
          params = yajl_copyBufStr();
          yajl_genClose();

          // Create a multipart/form-data form (like curl -F switch)
          // to contain both the image and the parameters
          // (this is created in a temporary IFS file)

          tempFile = http_tempfile();
          form = http_mfd_encoder_open( tempFile: contentType );
          http_mfd_encoder_addstmf( form
                                  : 'images_file'
                                  : imagePath
                                  : 'image/jpeg' );
          http_mfd_encoder_addvar_s( form: 'parameters': params );
          http_mfd_encoder_close(form);

          url = 'https://gateway.watsonplatform.net'
              + '/visual-recognition/api/v3/classify'
              + '?version=2018-03-19';

          http_setAuth( HTTP_AUTH_BASIC
                      : 'apikey'
                      : WATSON_API_KEY );

          rc = http_req( 'POST'
                       : url
                       : *omit: response
                       : tempFile: *omit
                       : %trim(contentType) );

          // delete temporary file -- no longer needed.
          unlink(tempFile);

          if rc <> 1;
             result.code = rc;
             result.errMsg = http_error();
             return result;
          endif;

          docNode = yajl_string_load_tree( response: errMsg);
          if errMsg <> '';
             result.errMsg = errMsg;
             result.code   = -999;
             return result;
          endif;

          // The result will be a list of images.
          //  Since we only asked for one image, the
          //  first image in the array is what we want:

          node = yajl_object_find(docNode: 'images');
          node = yajl_array_elem(node: 1);


          // Each image will have a list of classifiers
          // that it matches.  Since we only asked for one
          // classifier (insuranceclaims_1650517727) we want
          // the first one if it is found.  If not found,
          // it means watson couldn't classify it.

          node = yajl_object_find(node: 'classifiers');
          if node <>*null and yajl_array_size(node) >= 1;

             node = yajl_array_elem(node: 1);

             // The 'classes' array will list all of watson's
             // guesses within this classifier. The first one
             // is the highest ranked guess, or "top class".

             node = yajl_object_find(node: 'classes');
             topClass = yajl_array_elem(node: 1);


             // get the class name and score of the
             // top class for our return value

             node = yajl_object_find(topClass: 'class');
             result.class = yajl_get_string(node);
             node = yajl_object_find(topClass: 'score');
             result.score = yajl_get_number(node);

          endif;

          yajl_tree_free(docNode);

          return result;
       end-proc;
 