// VTR_Demo.cpp : Defines the entry point for the console application.
//

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <memory.h>
#include <assert.h>
#include <string.h>


char base64_Coding[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',  
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', "="
};

/*
void WriteVecBASE62(FILE* file, double* vec, int N) {
    int i;
    float *f;
    int _6a, _6b, _6c, _6d;
    char* p;
    unsigned int g;
    int NEND;


    f = (float*) malloc(sizeof(float)*(N+10));
    memset(f,0,sizeof(float)*(N+10));
    for( i = 0; i < N; i++) {
        f[i+1] = (float)vec[i];
    }
    memcpy(f,&N,sizeof(int));


    fflush(file);

    i = 0;
    p = (char*)f;

    N++;
    NEND= N*sizeof(float);
    //NENDpp=NEND; while(NENDpp%3 != 0) NENDpp++;
    
    while( i < NEND) {
        g = 0u;
        memcpy(&g,p,sizeof(char)*3);
        _6a = (g & 0x0000003F);
        _6b = (g & 0x00000FC0) >> 6;
        _6c = (g & 0x0003F000) >> 12;
        _6d = (g & 0x00FC0000) >> 18;

        if(i+2 >= NEND) 
            _6c = 64;
        if(i+3 >= NEND) 
            _6d = 64;

        assert(_6a >= 0 && _6a < 64);
        assert(_6b >= 0 && _6b < 64);
        assert(_6c >= 0 && _6c <= 64);
        assert(_6d >= 0 && _6d <= 64);

        fprintf(file,"%c%c%c%c",base64_Coding[_6a],base64_Coding[_6b],base64_Coding[_6c],base64_Coding[_6d]);

        i += 3;
        p += 3;
    }

    fprintf(file,"\n");

    fflush(file);
}*/

unsigned int Base64_Decode[256];

void initDecode() {
    int i;

    memset(Base64_Decode,-1,sizeof(unsigned int)*256);

    for( i = 0; i < 64; i++) {
        Base64_Decode[base64_Coding[i]] = i;
    }

    Base64_Decode['='] = 0;
}

void* DecodeBase64(char* code, int Len, int* OutSize) {
    unsigned int _6a, _6b, _6c, _6d;
    int c0, c1, c2;
    int i, *r;
    char* ret;

    assert(Len%4 == 0);
    *OutSize = (sizeof(char)*Len*3)/4;
    ret = (char*) malloc((sizeof(char)*Len*3)/4);
    r = (int*) ret;
    memset(ret,0,(sizeof(char)*Len*3)/4);

    for( i = 0; i < Len; i+=4) {

        _6a = Base64_Decode[code[i]];
        _6b = Base64_Decode[code[i+1]];
        _6c = Base64_Decode[code[i+2]];
        _6d = Base64_Decode[code[i+3]];

        //_6a = (_6a) << 0;
        //_6b = (_6b) << 6;
        //_6c = (_6c) << 12;
        //_6d = (_6d) << 18;

        //comb = _6a | _6b | _6c | _6d;

        //*( (unsigned int*) ret) |= comb;

        c0 = (_6a << 2) | ((_6b & 0x30) >> 4);
        c1 = ((_6b & 0xf) << 4) | ((_6c & 0x3c) >> 2);
        c2 = ((_6c & 0x3) << 6) | _6d;

        ret[0] = (char)c0;
        ret[1] = (char)c1;
        ret[2] = (char)c2;

        ret += 3;
    }

    return r;
}


//void Decode_test() {
void main() {
    float asFloat[1000];
    int asInt[1000];
    char aschar[1000];

    // test from http://de.wikipedia.org/wiki/Base64#Beispiel
    //char test[] = "UG9seWZvbiB6d2l0c2NoZXJuZCBhw59lbiBNw6R4Y2hlbnMgVsO2Z2VsIFLDvGJlbiwgSm9naHVydCB1bmQgUXVhcms=";
    
    // exported from Paraview (should be three values (within the range -1 to 1?))
    char test[] = "DAAAAAAAgL8AAACAAACAPw==";

    // exported from Paraview (should be 27 values)
    //char test[] = "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";

    int  Sz;
    void *dec;

    initDecode();


    memset(asFloat,0,sizeof(asFloat));
    memset(asInt,0,sizeof(asInt));
    memset(aschar,0,sizeof(aschar));

    dec = DecodeBase64(test,strlen(test),&Sz);
    memcpy(asFloat,dec,Sz);
    memcpy(asInt,dec,Sz);
    memcpy(aschar,dec,Sz);


    printf("%d %f %f %f \n",asInt[0],asFloat[1], asFloat[2], asFloat[3]);


    printf("As string: ");
    printf(aschar);

}

