//  phonfmt2.js
//  Written:  2005-08-05 by James Alarie <jalarie@umich.edu>
//    http://spruce.flint.umich.edu/~jalarie/
//
//  Call PhonFmt2 with a phone number to be formatted, local Area Code, 
//  and format-out code.  Valid format-out codes are:
//
//    format code         description                                         example
//    ------------------- --------------------------------------------------- -----------------
//    #######             seven digits.  (default)  . . . . . . . . . . . . . 7623123
//    #######x?           seven digits plus extension . . . . . . . . . . . . 7623123x21
//    ###-####            seven digits with separator . . . . . . . . . . . . 762-3123
//    ###-####x?          seven digits, separator, extension  . . . . . . . . 762-3123x21
//    ##########          ten digits  . . . . . . . . . . . . . . . . . . . . 8107623123
//    ##########x?        ten digits plus extension . . . . . . . . . . . . . 8107623123x21
//    ###-###-####        ten digits with separators  . . . . . . . . . . . . 810-762-3123
//    ###-###-####x?      ten digits, separators, extension . . . . . . . . . 810-762-3123x21
//    ###-#######         ten digits, single separator  . . . . . . . . . . . 810-7623123
//    ###-#######x?       ten digits, single separator, extension . . . . . . 810-7623123x21
//    (###)#######        ten digits, area code in parens . . . . . . . . . . (810)7623123
//    (###)#######x?      ten digits, area code in parens, extension  . . . . (810)7623123x21
//    (###)###-####       ten digits, area code in parens, separator  . . . . (810)762-3123
//    (###)###-####x?     ten digits, a/c in parens, separator, extension . . (810)762-3123x21
//    (###) ###-####      ten digits, a/c parens, space, separator  . . . . . (810) 762-3123
//    (###) ###-####x?    ten digits, a/c parens, space, separator, ext.  . . (810) 762-3123x21
//    1##########         eleven digits . . . . . . . . . . . . . . . . . . . 18107623123
//    1##########x?       eleven digits plus extension  . . . . . . . . . . . 18107623123x21
//    1-###-###-####      eleven digits with separators . . . . . . . . . . . 1-810-762-3123
//    1-###-###-####x?    eleven digits, separators, extension  . . . . . . . 1-810-762-3123x21
//    1-###-#######       eleven digits, two separators . . . . . . . . . . . 1-810-7623123
//    1-###-#######x?     eleven digits, two separators, extension  . . . . . 1-810-7623123x21
//    1-##########        eleven digits, single separator . . . . . . . . . . 1-8107623123
//    1-##########x?      eleven digits, single separator, extension  . . . . 1-8107623123x21
//    1(###)#######       eleven digits, area code in parens  . . . . . . . . 1(810)7623123
//    1(###)#######x?     eleven digits, a/c in parens, extension . . . . . . 1(810)7623123x21
//    1(###)###-####      eleven digits, area code in parens, separator . . . 1(810)762-3123
//    1(###)###-####x?    eleven digits, a/c in parens, separator, ext. . . . 1(810)762-3123x21
//    +1##########        plus, 11 digits . . . . . . . . . . . . . . . . . . +18107623123
//    +1##########x?      plus, 11 digits plus extension  . . . . . . . . . . +18107623123x21
//    +1-###-###-####     plus, 11 digits with separators . . . . . . . . . . +1-810-762-3123
//    +1-###-###-####x?   plus, 11 digits, separators, extension  . . . . . . +1-810-762-3123x21
//    +1-###-#######      plus, 11 digits, two separators . . . . . . . . . . +1-810-7623123
//    +1-###-#######x?    plus, 11 digits, two separators, extension  . . . . +1-810-7623123x21
//    +1-##########       plus, 11 digits, single separator . . . . . . . . . +1-8107623123
//    +1-##########x?     plus, 11 digits, single separator, extension  . . . +1-8107623123x21
//    +1(###)#######      plus, 11 digits, area code in parens  . . . . . . . +1(810)7623123
//    +1(###)#######x?    plus, 11 digits, a/c in parens, extension . . . . . +1(810)7623123x21
//    +1(###)###-####     plus, 11 digits, area code in parens, separator . . +1(810)762-3123
//    +1(###)###-####x?   plus, 11 digits, a/c in parens, separator, ext. . . +1(810)762-3123x21
//    idd                 plus, numerics  . . . . . . . . . . . . . . . . . . +61079385
//
//  Examples:
//
//    Phone_out=PhonFmt2(input_phone_number,'810','(###)###-####x?');
//
//  Notes:
//    All of the above example telephone numbers would be recognized as valid 
//      NANP (North American Numbering Plan) input.  Extra dashes and other 
//      special characters are ignored.  Change PH_Null to 'no' to make null 
//      inputs produce an error message.
//    Input separators are not checked.
//    Any UPPER-CASE letters will be replaced with the appropriate telephone 
//      keypad numbers.  The letters 'Q' and 'Z' become '1' and '0' respectively.
//    Extensions must be marked by a lower-case 'x' to be recognized.
//    Output extension formats must have exactly one question (?) mark even though 
//      the length of the output extension will be the entire entered value.
//    If the format-out code has a comma, whatever is after the comma will be used
//      in place of the dashes in the output value.
//    The default Area Code is three blanks.
//    Any non-NANP input number which begins with a plus (+) sign will force the 
//      output format to be in "idd" form.
    
        function PhonFmt2 (IPhone,PFix,FormatO) {
          PH_Null='allow';
          
          PH_PFix=PFix;                             // prefix string
          PH_IPhone=IPhone;                         // phone number to format
          PH_FormatO=FormatO;                       // desired output format
          
          if ((!PH_IPhone) && (PH_Null == 'allow')) { return ''; }
          if (!PH_PFix)    { PH_PFix='   '; }
          if (!PH_FormatO) { PH_FormatO='#######'; }
          PH_Dash='-';
          if ((PH_ix1=PH_FormatO.indexOf(',')) > -1) {
            PH_Dash=PH_FormatO.substring(PH_ix1+1);
            PH_FormatO=PH_FormatO.substring(0,PH_ix1);
          }
          
          PH_IPhone=PH_IPhone.replace(/[ABC]/g,'2');
          PH_IPhone=PH_IPhone.replace(/[DEF]/g,'3');
          PH_IPhone=PH_IPhone.replace(/[GHI]/g,'4');
          PH_IPhone=PH_IPhone.replace(/[JKL]/g,'5');
          PH_IPhone=PH_IPhone.replace(/[MNO]/g,'6');
          PH_IPhone=PH_IPhone.replace(/[PRS]/g,'7');
          PH_IPhone=PH_IPhone.replace(/[TUV]/g,'8');
          PH_IPhone=PH_IPhone.replace(/[WXY]/g,'9');
          PH_IPhone=PH_IPhone.replace(/Q/g,    '1');
          PH_IPhone=PH_IPhone.replace(/Z/g,    '0');
          
          PH_IPhone=PH_IPhone.replace(/[\ -\*]/g,''); // printables before +
          PH_IPhone=PH_IPhone.replace(/[\,-\/]/g,''); // between + and 0
          PH_IPhone=PH_IPhone.replace(/[\:-\@]/g,''); // between 9 and A
          PH_IPhone=PH_IPhone.replace(/[\[-\`]/g,''); // between Z and a
          PH_IPhone=PH_IPhone.replace(/[\{-\~]/g,''); // printables after z
          
          if (PH_FormatO == 'idd') {
            if (PH_IPhone.substring(0,1) != '+') {
              PH_IPhone='+'+PH_IPhone;
            }
            return PH_IPhone;
          }
          if ((PH_IPhone.substring(0,1) == '+')
          &&  (PH_IPhone.substring(0,2) != '+1')) {
            return PH_IPhone;
          }
          
          PH_Work='';  PH_Ext='';
          if ((PH_ix1=PH_IPhone.indexOf('x')) > -1) {
            PH_Ext=PH_IPhone.substring(PH_ix1);
            PH_IPhone=PH_IPhone.substring(0,PH_ix1);
          }
          
          PH_L1=PH_IPhone.length;                   // how long is it?
          PH_N1=10-PH_L1;                           // need more digits
          PH_IPhone=PH_PFix.substring(0,PH_N1)+PH_IPhone;
          PH_IPhone=PH_IPhone.replace(/\ /g,'');    // drop any spaces

// seven digits [extension]: 
// ex: 7623123 or 7623123x21
          if (PH_IPhone.match(/^[2-9][0-9]{6}$/)) {
            PH_Work=''+'   '+PH_IPhone;
          }
// ten digits [extension]: 
// ex: 8107623123 or 8107623123x21
          if (PH_IPhone.match(/^[2-9][0-9]{2}[2-9][0-9]{6}$/)) {
            PH_Work=''+PH_IPhone;
          }
// eleven digits [extension]: 
// ex: 18107623123 or 18107623123x21
          if (PH_IPhone.match(/^1[2-9][0-9]{2}[2-9][0-9]{6}$/)) {
            PH_Work=''+PH_IPhone.substring(1);
          }
// plus, 11 digits [extension]: 
// ex: +18107623123 or +18107623123x21
          if (PH_IPhone.match(/^\+1[2-9][0-9]{2}[2-9][0-9]{6}$/)) {
            PH_Work=''+PH_IPhone.substring(2);
          }
          
          if (PH_Work == '') {
            alert('Invalid NANP telephone number.');
            return PH_IPhone;                       // output=input
          }

//  At this point we have ten digits with possible extension, and we can
//  process the output formatting.

          if ((PH_ix1=PH_FormatO.indexOf('x')) == -1) {
            PH_Ext='';
          } else {
            PH_FormatO=PH_FormatO.substring(0,PH_ix1);
          }
          
          PH_Out='';
          if (PH_FormatO == '#######') {            // seven digits.  (default)
            PH_Out=''+PH_Work.substring(3,10);
          }
          if (PH_FormatO == '###-####') {           // seven digits with separator.
            PH_Out=''+PH_Work.substring(3,6)+PH_Dash+PH_Work.substring(6,10);
          }
          if (PH_FormatO == '##########') {         // ten digits.
            PH_Out=''+PH_Work.substring(0,10);
          }
          if (PH_FormatO == '###-###-####') {       // ten digits with separators.
            PH_Out=''+PH_Work.substring(0,3)+PH_Dash+PH_Work.substring(3,6)+PH_Dash+PH_Work.substring(6,10);
          }
          if (PH_FormatO == '###-#######') {        // ten digits, single separator.
            PH_Out=''+PH_Work.substring(0,3)+PH_Dash+PH_Work.substring(3,10);
          }
          if (PH_FormatO == '(###)#######') {       // ten digits, area code in parens.
            PH_Out=''+'('+PH_Work.substring(0,3)+')'+PH_Work.substring(3,10);
          }
          if (PH_FormatO == '(###)###-####') {      // ten digits, area code in parens, separator.
            PH_Out='('+PH_Work.substring(0,3)+')'+PH_Work.substring(3,6)+PH_Dash+PH_Work.substring(6,10);
          }
          if (PH_FormatO == '(###) ###-####') {     // ten digits, a/c parens, space, separator.
            PH_Out='('+PH_Work.substring(0,3)+') '+PH_Work.substring(3,6)+PH_Dash+PH_Work.substring(6,10);
          }
          if (PH_FormatO == '1##########') {        // eleven digits.
            PH_Out=''+'1'+PH_Work.substring(0,10);
          }
          if (PH_FormatO == '1-###-###-####') {     // eleven digits with separators.
            PH_Out=''+'1'+PH_Dash+PH_Work.substring(0,3)+PH_Dash+PH_Work.substring(3,6)+PH_Dash+PH_Work.substring(6,10);
          }
          if (PH_FormatO == '1-###-#######') {     // eleven digits, two separators.
            PH_Out=''+'1'+PH_Dash+PH_Work.substring(0,3)+PH_Dash+PH_Work.substring(3,10);
          }
          if (PH_FormatO == '1-##########') {      // eleven digits, single separator.
            PH_Out=''+'1'+PH_Dash+PH_Work.substring(0,10);
          }
          if (PH_FormatO == '1(###)#######') {      // eleven digits, area code in parens.
            PH_Out=''+'1('+PH_Work.substring(0,3)+')'+PH_Work.substring(3,10);
          }
          if (PH_FormatO == '1(###)###-####') {     // eleven digits, area code in parens, separator.
            PH_Out=''+'1('+PH_Work.substring(0,3)+')'+PH_Work.substring(3,6)+PH_Dash+PH_Work.substring(6,10);
          }
          if (PH_FormatO == '+1##########') {       // plus, 11 digits.
            PH_Out=''+'+1'+PH_Work.substring(0,10);
          }
          if (PH_FormatO == '+1-###-###-####') {     // plus, 11 digits with separators.
            PH_Out=''+'+1'+PH_Dash+PH_Work.substring(0,3)+PH_Dash+PH_Work.substring(3,6)+PH_Dash+PH_Work.substring(6,10);
          }
          if (PH_FormatO == '+1-###-#######') {     // plus, 11 digits, two separators.
            PH_Out=''+'+1'+PH_Dash+PH_Work.substring(0,3)+PH_Dash+PH_Work.substring(3,10);
          }
          if (PH_FormatO == '+1-##########') {      // plus, 11 digits, single separator.
            PH_Out=''+'+1'+PH_Dash+PH_Work.substring(0);
          }
          if (PH_FormatO == '+1(###)#######') {     // plus, 11 digits, area code in parens.
            PH_Out=''+'+1('+PH_Work.substring(0,3)+')'+PH_Work.substring(3,10);
          }
          if (PH_FormatO == '+1(###)###-####') {    // plus, 11 digits, area code in parens, separator.
            PH_Out=''+'+1('+PH_Work.substring(0,3)+')'+PH_Work.substring(3,6)+PH_Dash+PH_Work.substring(6,10);
          }
          
          if (PH_Out == '') {
            alert('Invalid format requested: '+PH_FormatO+'.');
            PH_IPhone=IPhone;                       // restore to original
            return PH_IPhone;                       // output=input
          }

          PH_Out=PH_Out+PH_Ext;
          return PH_Out;
        } // PhonFmt2
