/******************************************************************************
   Description : Converts a Decimal value to a text string formatted as either
                 Decimal, Integer, Currency or Ordinal. "Ordinal" format 
                 phrases the last word in the string as you would in normal 
                 speech like first, second, third, etc.
                 EXAMPLE: "Eight Hundred Ninetieth" VS "Eight Hundred Ninty"
   Input Param : Number to convert as Decimal
                 Type of conversion: "Currency", "Integer", "Decimal", "Ordinal"
   Output Param: Character String
   Author......: Speedy Mercer code AT herohog.com
   Copyright...: Speedy Mercer 2004 - http://www.herohog.com
   Created.....: 7/1/2004
   NOTES.......: Based on code from: Marin Lazar
                              Sr. DB / UNIX Admin
                              Somerville
                       
                 Modified by Speedy Mercer from Check Format to output either 
                 Currency, Integer, Decimal or Ordinal syntax.
         
                 Using the "Integer" or "Ordinal" parameter rounds the number to 
                 an Integer value!

   USAGE.......: DEF VAR textamt AS CHARACTER FORMAT "x(120)" NO-UNDO.
      
                 RUN NumToText.p ("1234567890", "Ordinal", OUTPUT textamt).
      
                 DISPLAY textamt WITH WIDTH 125 NO-LABELS.
      
   RESULTS IN..:
                 "One Billion Two Hundred Thirty-Four Million Five Hundred 
                  Sixty-Seven Thousand Eight Hundred Ninetieth"
******************************************************************************/
DEFINE INPUT  PARAMETER pcAmount AS DECIMAL     NO-UNDO.
DEFINE INPUT  PARAMETER pcType   AS CHARACTER   NO-UNDO.
DEFINE OUTPUT PARAMETER vcResult AS CHARACTER   NO-UNDO.

DEFINE VARIABLE vcTextAmt1       AS CHARACTER   NO-UNDO.
DEFINE VARIABLE vcTextAmt2       AS CHARACTER   NO-UNDO.
DEFINE VARIABLE vdNumber         AS DECIMAL     NO-UNDO.
DEFINE VARIABLE viDecimalAmt     AS INTEGER     NO-UNDO.
DEFINE VARIABLE viCnt1           AS INTEGER     NO-UNDO.
DEFINE VARIABLE viCnt2           AS INTEGER     NO-UNDO.
DEFINE VARIABLE viCnt3           AS INTEGER     NO-UNDO.
DEFINE VARIABLE viCnt4           AS INTEGER     NO-UNDO.
DEFINE VARIABLE viCnt5           AS INTEGER     NO-UNDO.
DEFINE VARIABLE vlOrdinal        AS LOGICAL     NO-UNDO.
DEFINE VARIABLE vcTxt1           AS CHARACTER   NO-UNDO.
DEFINE VARIABLE vcTxt2           AS CHARACTER   NO-UNDO.
DEFINE VARIABLE vcTxtHUNDREDS    AS CHARACTER EXTENT 4 
   initial ["Billion", "Million", "Thousand", "Hundred"] NO-UNDO.
DEFINE VARIABLE viNumHUNDREDS AS INTEGER EXTENT 4 
   initial [1000000000, 1000000, 1000, 1]    NO-UNDO.
DEFINE VARIABLE vcTxtTENS AS CHARACTER EXTENT 10 
   initial ["", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", 
            "Eighty", "Ninety"] NO-UNDO.
DEFINE VARIABLE vcTxtUNITS AS CHARACTER EXTENT 20 
   initial ["Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", 
            "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", 
            "Fifteen", "Sixteen", "Seventeen","Eighteen", "Nineteen"] NO-UNDO.

/* "Ordinal" format is Integer only */
IF pcType = "Ordinal"
THEN ASSIGN 
   pcType = "Integer"
   vlOrdinal = TRUE.
ELSE vlOrdinal = FALSE.

IF pcType = "Integer"
THEN ASSIGN pcAmount = ROUND(pcAmount, 0).

/* Add ability to deal with negitive numbers */
ASSIGN vdNumber = pcAmount.

IF vdNumber < 0 
THEN ASSIGN 
   vcResult = vcResult + "Negative "
   vdNumber = - vdNumber.

ASSIGN 
   viDecimalAmt = (vdNumber - TRUNCATE(vdNumber, 0)) * 100
   vdNumber = TRUNCATE(vdNumber, 0).

IF vdNumber = 0 
THEN ASSIGN vcResult = vcResult + vcTxtUNITS[1] + " ".

DO viCnt1 = 1 TO 4:
   ASSIGN  viCnt2 = TRUNCATE(vdNumber / viNumHUNDREDS[viCnt1], 0).
    
   IF viCnt2 = 0 
   THEN DO:
      ASSIGN vdNumber = vdNumber MOD viNumHUNDREDS[viCnt1].
      next.
   END.

   ASSIGN 
   viCnt3 = TRUNCATE(viCnt2 / 100, 0)
   viCnt2 = viCnt2 MOD 100
   viCnt4 = TRUNCATE(viCnt2 / 10, 0)
   viCnt5 = viCnt2 MOD 10.

   IF viCnt4 = 1 
   THEN ASSIGN 
      viCnt5 = viCnt5 + 10
      viCnt4 = 0.

   IF viCnt3 > 0 
   THEN ASSIGN vcResult = vcResult + vcTxtUNITS[viCnt3 + 1] + " " 
                        + vcTxtHUNDREDS[4] + " ".

   IF viCnt4 > 0 
   THEN ASSIGN 
      vcResult = vcResult + vcTxtTENS[viCnt4 + 1]
      vcResult = vcResult + IF viCnt5 > 0 
                            THEN "-"
                            ELSE " ".

   IF viCnt5 > 0 
   THEN ASSIGN vcResult = vcResult + vcTxtUNITS[viCnt5 + 1] + " ".

   IF viCnt1 < 4 
   THEN ASSIGN vcResult = vcResult + vcTxtHUNDREDS[viCnt1] + " ".

   ASSIGN vdNumber = vdNumber MOD viNumHUNDREDS[viCnt1].
END.

/* Format the strings as needed */
CASE pcType:
   WHEN "Currency"
      THEN DO:
         ASSIGN vcResult = vcResult + "Dollars AND ".
   
         IF viDecimalAmt = 0 
         THEN ASSIGN vcResult = vcResult + "No Cents".
         ELSE ASSIGN vcResult = vcResult + string(viDecimalAmt, "99") 
                              + " Cents".   
       END.
   WHEN "Integer"
      THEN /* Do nothing */.
   WHEN "Decimal"
      THEN ASSIGN vcResult = vcResult + " POINT " + string(viDecimalAmt, "99").
END CASE. /* pcType */

ASSIGN vcResult = TRIM(vcResult).

/* Convert the last word to the proper Ordinal form */
IF vlOrdinal
THEN DO:
   ASSIGN
      /* Replace any hyphens with a space so we can get each element of the string */
      vcTxt2 = REPLACE(vcResult,"-"," ")
      /* Grab the last entry */
      vcTxt2 = ENTRY(NUM-ENTRIES(vcTxt2, " "), vcTxt2, " ")
      /* remove the last entry from the orignal string */
      vcTxt1 =  SUBSTRING(vcResult, 1, LENGTH(vcResult) - LENGTH(vcTxt2)).

   /* Replace the last word in the string with the proper form of the word */
   CASE vcTxt2:
      WHEN "One"        THEN ASSIGN vcResult = vcTxt1 + "First".
      WHEN "Two"        THEN ASSIGN vcResult = vcTxt1 + "Second".
      WHEN "Three"      THEN ASSIGN vcResult = vcTxt1 + "Third".
      WHEN "Four"       THEN ASSIGN vcResult = vcTxt1 + "Fourth".
      WHEN "Five"       THEN ASSIGN vcResult = vcTxt1 + "Fifth".
      WHEN "Six"        THEN ASSIGN vcResult = vcTxt1 + "Sixth".
      WHEN "Seven"      THEN ASSIGN vcResult = vcTxt1 + "Seventh".
      WHEN "Eight"      THEN ASSIGN vcResult = vcTxt1 + "Eighth".
      WHEN "Nine"       THEN ASSIGN vcResult = vcTxt1 + "Ninth".
      WHEN "Ten"        THEN ASSIGN vcResult = vcTxt1 + "Tenth".
      WHEN "Eleven"     THEN ASSIGN vcResult = vcTxt1 + "Eleventh".
      WHEN "Twelve"     THEN ASSIGN vcResult = vcTxt1 + "Twelfth".
      WHEN "Thirteen"   THEN ASSIGN vcResult = vcTxt1 + "Thirteenth".
      WHEN "Fourteen"   THEN ASSIGN vcResult = vcTxt1 + "Fourteenth".
      WHEN "Fifteen"    THEN ASSIGN vcResult = vcTxt1 + "Fifteenth".
      WHEN "Sixteen"    THEN ASSIGN vcResult = vcTxt1 + "Sixteenth".
      WHEN "Seventeen"  THEN ASSIGN vcResult = vcTxt1 + "Seventeenth".
      WHEN "Eighteen"   THEN ASSIGN vcResult = vcTxt1 + "Eighteenth".
      WHEN "Nineteen"   THEN ASSIGN vcResult = vcTxt1 + "Nineteenth".
      WHEN "Twenty"     THEN ASSIGN vcResult = vcTxt1 + "Twentieth".
      WHEN "Thirty"     THEN ASSIGN vcResult = vcTxt1 + "Thirtieth".
      WHEN "Forty"      THEN ASSIGN vcResult = vcTxt1 + "Fortieth".
      WHEN "Fifty"      THEN ASSIGN vcResult = vcTxt1 + "Fiftieth".
      WHEN "Sixty"      THEN ASSIGN vcResult = vcTxt1 + "Sixtieth".
      WHEN "Seventy"    THEN ASSIGN vcResult = vcTxt1 + "Seventieth".
      WHEN "Eighty"     THEN ASSIGN vcResult = vcTxt1 + "Eightieth".
      WHEN "Ninety"     THEN ASSIGN vcResult = vcTxt1 + "Ninetieth".
      WHEN "Hundred"    THEN ASSIGN vcResult = vcTxt1 + "Hundredth".
      WHEN "Thousand"   THEN ASSIGN vcResult = vcTxt1 + "Thousandth".
      WHEN "Million"    THEN ASSIGN vcResult = vcTxt1 + "Millionth".
      WHEN "Billion"    THEN ASSIGN vcResult = vcTxt1 + "Billionth".
   END CASE.
END.

RETURN.