// -----------------------------------------------------------------------------
// Mauricio Portela (mauricio at portelainfo dot com)
// Compilar com: hbmk2 cnpj_v2.prg -l hbct.hbc
// -----------------------------------------------------------------------------

#define TRUE    .T.
#define FALSE   .F.

#define PI      3.1415

FUNCTION Main()
    LOCAL a, n, tmp, cCor
    LOCAL aTipos := {"EMPRESA XPTO 00.000.000/0001-91", ; // Caracteres
                     "ZZ.162.ZAB/TBAQ-WN", ;              // Caracteres
                     "12.ABC.345/01DE-35", ;              // Caracteres
                     "00.000.000/0001-91", ;              // Caracteres
                     "00.000.000/0001-92", ;              // Caracteres
                     "00000000000191", ;                  // Caracteres
                     "00000000000192", ;                  // Caracteres
                     "0000000000019",  ;                  // Caracteres
                     00000000000191, ;                    // Numerico
                     00000000000192, ;                    // Numerico
                     PI, ;                                // Numerico
                     ('M' > 'P'), ;                       // Logico
                     TRUE, ;                              // Logico
                     DATE(), ;                            // Data
                     @QOut(), ;                           // Symbol
                     hb_idleAdd(), ;                      // Ponteiro
                     TBrowse(), ;                         // Objeto
                     {"1", "2", ".", "a", "b", "C", ".", "3", "4", "5", "/", "0", "1", "d", "E", "-", "3", "5"}, ; // Array
                     {"1", "2", ".", "a", "b", "C", ".", "3", "4", "5", "/", "0", "1", "d", "E", "-", "3", "F"}, ; // Array
                     {"0", "0", ".", "0", "0", "0", ".", "0", "0", "0", "/", "0", "0", "0", "1", "-", "9", "1"}, ; // Array
                     {"0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "1", "9", "1"}}

    ? "TIPO   LOGICO       ENTRADA"
    FOR n := 1 TO LEN(aTipos)
        tmp := ""
        IF ValType(aTipos[n]) == "A"
            FOR a := 1 TO LEN(aTipos[n])
                tmp += aTipos[n,a]
            NEXT
        ENDIF
        cCor := SETCOLOR()
        SETCOLOR(iif(Validar_CNPJ(aTipos[n]), "r+", ""))
        ? ValType(aTipos[n]), "    ", ;
                iif(Validar_CNPJ(aTipos[n]), "Verdadeiro  ", "Falso       "), ;
                iif(empty(tmp), aTipos[n], tmp)
        SETCOLOR(cCor)
    NEXT
RETURN Nil


FUNCTION Validar_CNPJ(cnpj)
    LOCAL i := c := 0, cDataCNPJ := "", cTp := ValType(cnpj)
    DO CASE
        CASE cTp == "B" .OR. cTp == "D" .OR. cTp == "L" .OR. cTp == "M" ;
                        .OR. cTp == "O" .OR. cTp == "P" .OR. cTp == "S" ;
                        .OR. cTp == "U"
            RETURN FALSE
        CASE cTp == "N"
            cDataCNPJ := STRZERO(cnpj, 14)
        CASE cTp == "C"
            cDataCNPJ := STRTRAN(STRTRAN(STRTRAN(UPPER(cnpj), '.', ''), '-', ''), '/', '')
            FOR i := 1 to 12
                IF !(UPPER(SUBSTR(cDataCNPJ, i, 1)) $ "0123456789ABCDEFGHIJKLMNOPQRSTUWYXZ")
                    RETURN FALSE
                ENDIF
            NEXT
        CASE cTp == "A"
            cDataCNPJ := ""
            FOR c := 1 to len(cnpj)
                cDataCNPJ += cnpj[c]
            NEXT
            cDataCNPJ := STRTRAN(STRTRAN(STRTRAN(UPPER(cDataCNPJ), '.', ''), '-', ''), '/', '')
    ENDCASE
RETURN Calcula_DV(cDataCNPJ)


FUNCTION Calcula_DV(cnpj)
    LOCAL i, j, nSoma := nDV := nNum := 0, cDV
    IF EMPTY(cnpj) .OR. LEN(cnpj) != 14
        RETURN FALSE
    ELSE
        cDV  := ""
        nNum := 5
        FOR j := 1 to 2
            nSoma := 0
            FOR i := 1 to 12
                nSoma += (ASC(SUBSTR(cnpj, i, 1)) - 48) * nNum
                nNum--
                nNum := iif(nNum == 1, 9, nNum)
            NEXT
            nSoma += iif(j == 2, (2 * VAL(cDV)), 0)
            nDV := nSoma - (INT(nSoma / 11) * 11)
            cDV += iif((nDV== 0 .OR. nDV == 1), "0", STR(11 - nDV, 1))
            nNum := 6
        NEXT
    ENDIF
RETURN iif(cDV != SUBSTR(cnpj, 13, 2), FALSE, TRUE)
