//  Num_Word
//  Written:  2001-06-21 by James Alarie <jalarie@umich.edu>
//    http://spruce.flint.umich.edu/~jalarie/
//  Changed:  2003-04-18 by James Alarie
//    Moved from within a web page to a separate JavaScript function.
//    Extended to include decimal values.
//  Changed:  2005-12-01 by James Alarie
//    European format (reversed comma/periods) now allowed.
//    Commas in input value now allowed.

        function NumWords(What) {
          NW_V1=String(What);                       // the input string
          if (NW_V1.match(/^.*\.[0-9]{3}.*$/)) {    // reversed comma/periods
            NW_V1=NW_V1.replace(/\./g,'~');
            NW_V1=NW_V1.replace(/\,/g,'.');
            NW_V1=NW_V1.replace(/\~/g,',');
          }
          NW_V1=NW_V1.replace(/\,/g,'');            // drop all commas
          NW_Out='';                                // output string
          NW_I1=NW_V1.indexOf('.');                 // find a decimal point
          NW_F1='';                                 // no fraction yet
          if (NW_I1 > -1) {
            if (NW_I1 == NW_V1.length-1) {          // it's in the final position
              NW_V1=NW_V1.substring(0,NW_V1.length-1);
            } else {
              NW_F1=NW_V1.substring(NW_I1+1);       // save fraction for later
              NW_V1=NW_V1.substring(0,NW_I1);       // integer part
            }
          }
          NW_OI='';                                 // integer output
          NW_OF='';                                 // ...fractional part
          NW_O1=NumWords2(NW_V1);
          NW_OI=NW_O1;
          if ((NW_F1 != '') && (NW_O1.substring(0,1) != '*')) {
            NW_Names2=new Array(
              'Tenths','Hundredths','Thousandths','Ten Thousandths',
              'Hundred Thousandths','Millionths','Ten Millionths',
              'Hundred Millionths','Billionths'
            );
            if (NW_F1.length > NW_Names2.length) {  // too many digits
              NW_O1='*** Error: too many digits beyond decimal point.  Max='+NW_Names2.length+'.';
              return NW_O1;
            }
            NW_V1=NW_F1;
            NW_O1=NumWords2(NW_V1);
            NW_OF=' and '+NW_O1+' '+NW_Names2[NW_F1.length-1];
          }
          if (NW_OI == '') { NW_OI='Zero'; }
          NW_O1=''+NW_OI+NW_OF;
          return NW_O1;
        } // NumWords
        function NumWords2(NW_What) {
          NW_V2=NW_What;
          NW_Names=new Array('','Thousand','Million','Billion',
            'Trillion','Quadrillion','Quintillion','Sextillion',
            'Septillion','Octillion','Nonillion','Decillion',
            'Undecillion','Duodecillion','Tredecillion',
            'Quattuordecillion','Quindecillion','Sexdecillion',
            'Septendecillion','Octodecillion','Novemdecillion',
            'Vigintillion');                        // 66 digits!
          NW_Ones=new Array('','One','Two','Three','Four','Five',
            'Six','Seven','Eight','Nine');
          NW_Tens=new Array('','','Twenty','Thirty','Forty','Fifty',
            'Sixty','Seventy','Eighty','Ninety');
          NW_Teens=new Array('Ten','Eleven','Twelve','Thirteen','Fourteen',
            'Fifteen','Sixteen','Seventeen','Eighteen','Nineteen');          
          while (NW_V2.length%3 != 0) { NW_V2='0'+NW_V2; }
          if (NW_V2.length > (NV_Max=NW_Names.length*3)) {   // too big
            alert('I can not handle a number over '+NV_Max+' digits.');
            NW_O1='*** Error: too many digits.  Max='+NV_Max+'.';
            return NW_O1;
          }
          NW_O1='';                                 // work area
          while (NW_V2 != '') {
            NW_Name=NW_Names[NW_V2.length/3-1];     // 'million' etc.
            NW_V3=NW_V2.substring(0,3);             // first three digits
            NW_V2=NW_V2.substring(3);               // rest of string
            if (NW_V3 != '000') {
               NW_D1=NW_V3.substring(0,1);          // first digit
               NW_V3=NW_V3.substring(1);            // remaining digits
               if (NW_D1 != '0') {
                 NW_O1+=NW_Ones[NW_D1*1];
                 NW_O1+=' Hundred ';
               }
               NW_D1=NW_V3;
               NW_D2=NW_D1.substring(1);            // second digit
               NW_D1=NW_D1.substring(0,1);          // ...first
               if (NW_D1*1 > 1) {                   // twenty through ninety
                 NW_O1+=NW_Tens[NW_D1*1];
                 if (NW_D2 != 0) { NW_O1+=' '; }
                 NW_O1+=NW_Ones[NW_D2*1];
               } else {
                 if (NW_D1*1 == 1) {                // ten through nineteen
                   NW_D1=NW_D2;
                   NW_O1+=NW_Teens[NW_D2*1];
                 } else {                           // single digit
                   NW_D1=NW_D2;
                   NW_O1+=NW_Ones[NW_D1*1];
                 }
               }
               NW_O1+=' '+NW_Name+' ';
            }
          }
          NW_O1+='$';                               // killing trailing blanks
            NW_O1=NW_O1.replace(/ \$/,'$');
            NW_O1=NW_O1.replace(/ \$/,'$');
            NW_O1=NW_O1.replace(/ \$/,'$');
            NW_O1=NW_O1.replace(/\$/,'');
          return NW_O1;
        } // NumWords2
