//variables globales
var alg_cod;
var alp_cod;
var bas_cod;
var alg_crp;
var key_crp;
var inv_crp;
var bas_out;
var alp_out;
var renderer;
var type;
var javascript;
var bck;
var rgb = [];
var sphereOn = false;
var gyroscope = true;
var rotation = false;
var axes = false;

/*
 * A partir des parametres recus dans l'url et ceux lus dans le JSON, cree tous les param : dots, angle, ... 
 * et les retourne pour pouvoir afficher les liens etc. et dessiner
 */
function getParamJSON(tabGET) {

    //lecture du json tabGET (string -> objet)
    console.log("Je suis dans getParamJSON");
    var objGET = JSON.parse(tabGET);
    console.log("J'ai réussir à parser dans paramJSON")
//    alert(objGET.out);

    //AJAX necessaire pour lecture du fichier JSON
/*    var xhr = getXMLHttpRequest();

    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4 && (xhr.status === 200 || xhr.status === 0)) {
            var proprieteJSON = JSON.parse(xhr.responseText);
            createJSON(proprieteJSON, objGET);
        }
    };
    xhr.open("POST", "../json/sURLset.json", true);
    xhr.send(null);
*/
var proprieteJSON = JSON.parse(Android.loadJsonString());
createJSON(proprieteJSON, objGET);
}

/*
 * cree le json avec toutes les infos pour dessiner etc. et appelle l'initialisation de la page une fois qu'il est pret
 */
function createJSON(proprieteJSON, objGET) {
    var json; //le json a creer
    var blockSize = 128;
    var bas_crp = "b64c";
    var bas_bin = "b02c";
    var bas_dec = "b10c";

    var alp_crp = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    var alp_bin = "01";
    var alp_dec = "0123456789";

//    alert("test " + proprieteJSON.sURLSet.sURL[0].drw.alg_drw);

    //lecture des parametres : du generique au plus specifique
    //1 recuperer les infos generales trouve sans key
    enr_param(proprieteJSON.sURLSet.sURL[0]);
//    alert("1 " + bas_cod);

    for (var i = 1; i < proprieteJSON.sURLSet.sURL.length; i++) {

        var propriete = proprieteJSON.sURLSet.sURL[i];

        //2 ecraser avec les infos trouvees dans key dom
        if (propriete.key.dom === Android.loadDom() && !propriete.key.prf) {
            enr_param(propriete);
        }
        //3 ecraser avec les infos trouvees dans key dom+prf
        else if (propriete.key.dom === Android.loadDom() && propriete.key.prf === objGET.prf) {
            enr_param(propriete);
            i = proprieteJSON.sURLSet.sURL.length; //ATTENTION il faut que les donnees soient trouvees dans cet ordre dans le JSON
        }
    }
    
    //cod ne sera plus dans le json ?
    if(!bas_cod) {
        bas_cod['val'] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
        bas_cod['-id'] = "b64u";
    }

    //options choisies dans l'URL, ecrasent celles du JSON
    if (objGET.gyr) {
        (objGET.gyr === "true") ? gyroscope = true : gyroscope = false;
    }
    if (objGET.rgb || objGET.bck) { //changement couleur objet et/ou fond
        if (objGET.rgb) {
            var rgb_id = objGET.rgb;
        }
        else
            var rgb_id = null;
        if (objGET.bck) {
            var bck_id = objGET.bck;
        }
        else
            var bck_id = null;
        //Lecture du json palette
        var xhr = getXMLHttpRequest();

        xhr.open("GET", "../json/rgbSet.json", false);
        xhr.setRequestHeader('Content-Type', "application/x-www-form-urlencoded");
        xhr.send(null);

        if (xhr.readyState === 4 && (xhr.status === 200 || xhr.status === 0)) {
//                                    alert(xhr.responseText); //test
            var jsonRGB = JSON.parse(xhr.responseText);
            var lesRGB = jsonRGB.rgbSet.rgb;
            for (var i = 0; i < lesRGB.length; i++) {
                if (lesRGB[i]["-id"] === rgb_id) {
                    rgb["val"] = lesRGB[i].val;
                }
                if (lesRGB[i]["-id"] === bck_id) {
                    bck = lesRGB[i].val;
                    if (Array.isArray(bck)) {
                        bck = bck[0];
                    }
                }
            }

        }
        else {
            console.log("Error while reading rgbSet.json");
        }
    }
    if (objGET.rotation) {
        (objGET.rotation === "true") ? rotation = true : rotation = false;
    }
    if (objGET.axe) {
        (objGET.axe === "true") ? axes = true : axes = false;
    }
    if (objGET.sphere) {
        (objGET.sphere === "true") ? sphereOn = true : sphereOn = false;
    }

    //quel modele de dessin ?
    switch (javascript) {
        //3D (10 points avec 3 params : x, y et z) + angle 
        case "threeNoodleGyr" :
            var modele = "3D";
            break;
            //3D fixe sur un plan
        case "threeNoodle2D" :
            var modele = "2D";
            break;
            //2D svg
        case "svgNoodle" :
            var modele = "2D";
            break;
    }

    switch (modele) {
        case "3D":
            var NB_POINTS = 10; //nombre de points dans l'espace de la figure
            var NB_PARAM = 3; //chaque points a besoin de deux params : x, y et z 
            var BIT_PARAM = 4; //chaque param est code sur 4 bits
            var BIT_ANGLE = 8; //l'angle est cod� sur 8 bits
            var angle_tour = 0; //l'angle duquel la figure est tourne au depart <!> doit etre positif
            break;
        default:
        case "2D":
            var NB_POINTS = 12; //nombre de points dans l'espace de la figure
            var NB_PARAM = 2; //chaque points a besoin de deux params : x et y 
            var BIT_PARAM = 4; //chaque param est code sur 4 bits
            var BIT_ANGLE = 1; //l'angle est cod� sur 1 bit
            var angle_tour = 0; //l'angle duquel la figure est tourne au depart <!> doit etre positif  
            break;
    }

    var palette = [];

    //palette de couleurs
    if (rgb != false) {
        if (!Array.isArray(rgb.val)) {
            palette[0] = rgb.val;
        } else {
            var palette = rgb.val;
        }
    } else
        palette = null;

    var srv = objGET.srv; // serveur (jt.ag)
    var index = objGET.index; //indexX.php    
    var prf = objGET.prf; // Prefixe

    var out = objGET.out;   // Codé Base 75x	//LT 201506
    var crp = objGET.crp;   // Crypté 128, 192 ou 256 bits
    var cod = objGET.cod; // Codé Base 64u	//LT 201506
    var bin = objGET.bin; // Représentation Optimale Bin.
    var val = objGET.val; // Expression Décimale 

    console.log(out + crp + cod + bin + val);

    //DEBUT BLOC

    if (out) {
//        crp = changeBase(out, bas_out, bas_crp);
        console.log("j'ai out donc je vais changerdebase ");
        console.log("ce que je vais changer "+ out);
        crp = changeBaseAlpha(out, alp_out, alp_crp);
//        console.log("CRP : " + crp);
//        console.log('entree out \n');
    } // if out

    if (crp) {
//        console.log('entree crp \n');
        cod = decrypt(crp);
        //Si bug decrypt :
        if(!cod) {
            $("#txt_div").text("Crypted message invalid.");
            return;
        }
        
        
        if (!out) {
//            out = changeBase(crp, bas_crp, bas_out);
            out = changeBaseAlpha(crp, alp_crp, alp_out);
        }
    } // if crp

    if (cod) {
        console.log('--------> entree cod : '+cod+' <--------');
//        bin = changeBase(cod, bas_cod, bas_bin);
        bin = changeBaseAlpha(cod, alp_cod, alp_bin);
        bin = str_pad(bin, BIT_PARAM * NB_PARAM * NB_POINTS + BIT_ANGLE, "0");
        if (!crp) {
            crp = crypto(cod);
        }
        if (!out) {
//            out = changeBase(crp, bas_crp, bas_out);
            out = changeBaseAlpha(crp, alp_crp, alp_out);
        }
    } // if cod

    if (bin) {
//        console.log('entree bin \n');
        bin = str_pad(bin, BIT_PARAM * NB_PARAM * NB_POINTS, "0");
        var val = '';
        for (var i = 0; i < NB_POINTS; i++) {
            for (var j = 0; j < NB_PARAM; j++) {
//                str = substr(bin, BIT_PARAM * j + BIT_PARAM * NB_PARAM * i, BIT_PARAM);
                var str = bin.substr(BIT_PARAM * j + BIT_PARAM * NB_PARAM * i, BIT_PARAM);
//                var dec = changeBase(str, bas_bin, bas_dec);
                var dec = changeBaseAlpha(str, alp_bin, alp_dec).toString();
                if (dec === '')
                    dec = '0'; //bug, vide au lieu de 0
                val += dec;
                if (j < NB_PARAM - 1) {
                    val += '-';
                }
            }
            if (i < NB_POINTS - 1) {
                val += '_';
            }
        }
        //parametre angle
        var tmp = bin.substr(NB_POINTS * NB_PARAM * BIT_PARAM, BIT_ANGLE);
//        tmp = changeBase(tmp, bas_bin, bas_dec);
        tmp = changeBaseAlpha(tmp, alp_bin, alp_dec);
        if (tmp == 0) {
            if (modele === "2D") {
                val += '_' + 90; //angle 0
            } else if (modele === "3D") {
                val += 0; //evite un bug avec le string
            }
        } else {
            if (modele === "2D") {
                val += '_' + 180; //angle 180
            } else if (modele === "3D") {
                tmp = Number(tmp); //evite un bug avec le string
                val += '_' + tmp;
            }
        }

        if (!cod) {
//            cod = changeBase(bin, bas_bin, baseCod);
            cod = changeBaseAlpha(bin, alp_bin, alp_cod);
        }
        if (!crp) {
            crp = crypto(cod);
        }
        if (!out) {
            //version php
//            out = base_base2base(crp, baseCrp, baseOut);
//            out = changeBase(crp, baseCrp, baseOut);
            out = changeBaseAlpha(crp, alp_crp, alp_out);
        }
    } // if bin

    if (val) {
//        alert("val ok");
        var pts = val.split('_');
        var temp = [];
        var res = [];
        for (var i = 0; i < NB_POINTS; i++) {
            temp[i] = pts[i].split('-');

            for (var j = 0; j < NB_PARAM; ++j) {
                res[i * NB_PARAM + j] = temp[i][j];
            }
        } // for i
        //parametre angle
        if (pts.length == NB_POINTS + 1) {
            angle_tour = pts[NB_POINTS];
           /* if (modele === "2D" && angle_tour != 90) {
                angle_tour = 180;
            }*/
        }
        var dots = temp;

        if (!bin) {
            var tmp = '';
            var bin = '';
            for (var i = 0; i < NB_POINTS; i++) {
                for (var j = 0; j < NB_PARAM; j++) {
//                    tmp = changeBase(dots[i][j], bas_dec, bas_bin);
//                    console.log('tmp = changeBaseAlpha(' + dots[i][j] + ','+ alp_dec +','+ alp_bin+')');
                    tmp = changeBaseAlpha(dots[i][j], alp_dec, alp_bin);
                    tmp = str_pad(tmp, BIT_PARAM, "0");
                    bin += tmp;
//                    console.log("tmp : "+ tmp + " bin : "+bin);
                }
            }
            //angle
            if (modele === "2D") {
                if (angle_tour == 0) {
                    bin += "0";
                } else
                    bin += "1";
            }
            else if (modele === "3D") {
//                tmp = changeBase(angle_tour, bas_dec, bas_bin);
                tmp = changeBaseAlpha(angle_tour, alp_dec, alp_bin);
                bin += str_pad(tmp, BIT_ANGLE, "0");
            }
        } // if !bin
//        console.log("BIN : "+bin);
        if (!cod) {
//            cod = changeBase(bin, bas_bin, bas_cod);
            cod = changeBaseAlpha(bin, alp_bin, alp_cod);
        }
        if (!crp) {
            crp = crypto(cod);
        }
        if (!out) {
//            out = changeBase(crp, bas_crp, bas_out);
            out = changeBaseAlpha(crp, alp_crp, alp_out);
        }
    } // if val

    //Creation aleatoire
    if (!dots) {
//        alert("j'ai rien a foutre la ! :D");
        var pt_tmp = [];
        for (var i = 0; i < NB_POINTS; i++) {
            var val_tmp = [];
            for (var j = 0; j < NB_PARAM; j++) {
                val_tmp[j] = Math.floor(Math.random() * 15);
//                alert("dots[i][j] : "+dots[i][j]);
            }
            pt_tmp[i] = val_tmp;
        } // for
        var dots = pt_tmp;

        if (!val) {
            var tmp = '';
            for (var i = 0; i < NB_POINTS; i++) {
                for (var j = 0; j < NB_PARAM; j++) {
                    tmp += dots[i][j];
                    if (j < NB_PARAM - 1)
                        tmp += '-';
                }
                if (i < NB_POINTS - 1)
                    tmp += '_';
            }
            var val = tmp;
            //parametre angle
            if (modele === "2D") {
                angle_tour = 0;
            } else if (modele === "3D") {
                /*if (type != "pastille" && type != "disk" && type != "bubblewrap") {
                    angle_tour = Math.floor(Math.random() * 180);
                    ;
                } else
                    angle_tour = 90;*/
                    angle_tour = 0;
            }
            val += "_" + angle_tour;
        } // if !val 
        if (!bin) {
            var bin = '';
            for (var i = 0; i < NB_POINTS; i++) {
                for (var j = 0; j < NB_PARAM; j++) {
//                    tmp = changeBase(dots[i][j], bas_dec, bas_bin); // bug du ZERO corrigé
//                    console.log('tmp = changeBaseAlpha(' + dots[i][j] + ','+ alp_dec +','+ alp_bin+')');
                    var tmp = changeBaseAlpha(dots[i][j], alp_dec, alp_bin);
                    tmp = str_pad(tmp, BIT_PARAM, "0");

                    bin += tmp;
                }
            }
            //angle
            if (modele === "2D") {
                bin += "0";
            } else if (modele === "3D") {
//                tmp = changeBase(angle_tour, bas_dec, bas_bin);
                tmp = changeBaseAlpha(angle_tour, alp_dec, alp_bin);
                bin += str_pad(tmp, BIT_ANGLE, "0");
            }
        } // if !bin 		
        if (!cod) {
//            cod = changeBase(bin, bas_bin, bas_cod);
            cod = changeBaseAlpha(bin, alp_bin, alp_cod);
            console.log("--------> Aleatoire cod : "+cod+" <------------");
        }
        if (!crp) {
            crp = crypto(cod);
        }
        if (!out) {
//            out = changeBase(crp, bas_crp, bas_out);
            out = changeBaseAlpha(crp, alp_crp, alp_out);
        }
    } // dots

    //FIN BLOC

    if (objGET.ang) {
        angle_tour = objGET.ang;
    }
    if (objGET.rdr) {
        renderer = objGET.rdr;
    }

    // url courte
    url = encodeURIComponent('http://' + srv + '/' + prf + out);

    //creation du json de retour
    json = {"blockSize": blockSize, "baseOut": bas_out, "baseCrp": bas_crp, "baseCod": bas_cod, "out": out,
        "crp": crp, "cod": cod, "bin": bin, "val": val, "dots": dots, "angle": angle_tour, "renderer": renderer,
        "type": type, "palette": palette, "sphere": sphereOn, "gyroscope": gyroscope, "rotation": rotation, "axes": axes,
        "index": "indexM2", "url": url, "javascript": javascript, "bck": bck};

//    alert("TYPE " + type + " "+ json.type);
//    alert("dots " + dots[0]);

    initialiser(json);
}

/*
 * enregistre les parametres de propriete a partir d'un objet (du json) reçu
 */

function enr_param(obj) {
    if (obj.var) {

        if (obj.var.cod) {
            if (obj.var.cod.alg_cod)
                alg_cod = obj.var.cod.alg_cod;
            if (obj.var.cod.bas_cod)
                bas_cod = obj.var.cod.bas_cod["-id"];
            alp_cod = obj.var.cod.bas_cod["val"];
        }

        if (obj.var.crp) {
            if (obj.var.crp.alg_crp)
                alg_crp = obj.var.crp.alg_crp;
            if (obj.var.crp.key_crp)
                key_crp = obj.var.crp.key_crp;
            if (obj.var.crp.inv_crp)
                inv_crp = obj.var.crp.inv_crp;
        }

        if (obj.var.out) {
            if (obj.var.out.bas_out)
                bas_out = obj.var.out.bas_out["-id"];
            alp_out = obj.var.out.bas_out["val"];
        }

    }

    if (obj.drw) {

        if (obj.drw.rdr_drw)
            renderer = obj.drw.rdr_drw;
        if (obj.drw.alg_drw) {
            type = obj.drw.alg_drw;
//            alert("lu dans le json "+type);
        }
        if (obj.drw.typ_drw)
            javascript = obj.drw.typ_drw;
        if (obj.drw.bck_drw)
            bck = obj.drw.bck_drw;
        if (obj.drw.rgb_drw)
            rgb = obj.drw.rgb_drw;
        if (obj.drw.sph_drw) {
            (obj.drw.sph_drw === "true") ? sphereOn = true : sphereOn = false;
        }
        if (obj.drw.gyr_drw) {
            (obj.drw.gyr_drw === "true") ? gyroscope = true : gyroscope = false;
        }
        if (obj.drw.rot_drw) {
            (obj.drw.rot_drw === "true") ? rotation = true : rotation = false;
        }
        if (obj.drw.axe_drw) {
            (obj.drw.axe_drw === "true") ? axes = true : axes = false;
        }

    }
}

function crypto(msg) {
    //code js

    switch (alg_crp) {
        case "CryptoJS.AES" :
            createKey(key_crp);
            createIV(inv_crp);
            return encryptAES(msg).toString().replace(/\=/g,"");;
            break;
        default :
            return msg;
            break;
    }

//    return msg;
}

function decrypt(msg) {

    //code js
    switch (alg_crp) {
        case "CryptoJS.AES" :
            createKey(key_crp);
            createIV(inv_crp);
//            console.log("-------DECRYPTE : "+decryptAES(msg) +" --------");
            return decryptAES(msg);
            break;
        default :
            return msg;
            break;
    }
//    return msg;
}

/*
 * padding de 0 à gauche
 * n : message
 * z : caracetere pour pader ou rien
 */
function str_pad(n, width, z) {
    z = z || '0';
    n = n + '';
    return (n.length >= width) ? n : new Array(width - n.length + 1).join(z) + n;
}