/**
 * This JS file contains the ZIP tools
 */
class ZipTool {
    constructor(parent) {
        this.parent = parent;
        
        this.zipCode;
    }

    set ZipCode(value) {
        this.zipCode = value;
    }

     
    addContentToZip (zip, name, url, replace, buffer, then) {
        if (url.substring(0, 5) == "data:" || url.substring(0, 5) == "http:" || url.substring(0, 5) == "blob:" || url.substring(0, 6) == "https:") {
            then();
            return;
        }

        var xhr = new XMLHttpRequest();

        xhr.open('GET', url, true);

        if (buffer) {
            xhr.responseType = "arraybuffer";
        }

        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4) {
                if (xhr.status === 200) {
                    var text;
                    if (!buffer) {
                        if (replace) {
                            var splits = replace.split("\r\n");
                            for (var index = 0; index < splits.length; index++) {
                                splits[index] = "        " + splits[index];
                            }
                            replace = splits.join("\r\n");

                            text = xhr.responseText.replace("####INJECT####", replace);
                        } else {
                            text = xhr.responseText;
                        }
                    }

                    zip.file(name, buffer ? xhr.response : text);

                    then();
                }
            }
        };

        xhr.send(null);
    };
    addTexturesToZip (zip, index, textures, folder, then) {

        if (index === textures.length || !textures[index].name) {
            then();
            return;
        }

        if (textures[index].isRenderTarget || textures[index] instanceof BABYLON.DynamicTexture || textures[index].name.indexOf("data:") !== -1) {
            this.addTexturesToZip(zip, index + 1, textures, folder, then);
            return;
        }

        if (textures[index].isCube) {
            if (textures[index].name.indexOf("dds") === -1 && textures[index].name.indexOf(".env") === -1) {
                if (textures[index]._extensions) {
                    for (var i = 0; i < 6; i++) {
                        textures.push({ name: textures[index].name + textures[index]._extensions[i] });
                    }
                } else if (textures[index]._files) {
                    for (var i = 0; i < 6; i++) {
                        textures.push({ name: textures[index]._files[i] });
                    }
                }
            }
            else {
                textures.push({ name: textures[index].name });
            }
            this.addTexturesToZip(zip, index + 1, textures, folder, then);
            return;
        }


        if (folder == null) {
            folder = zip.folder("textures");
        }
        var url;

        if (textures[index].video) {
            url = textures[index].video.currentSrc;
        } else {
            // url = textures[index].name;
            url = textures[index].url ? textures[index].url : textures[index].name;
        }

        var name = textures[index].name.replace("textures/", "");
        // var name = url.substr(url.lastIndexOf("/") + 1);

        if (url != null) {
            this.addContentToZip(folder,
                name,
                url,
                null,
                true,
                function () {
                    this.addTexturesToZip(zip, index + 1, textures, folder, then);
                }.bind(this));
        }
        else {
            this.addTexturesToZip(zip, index + 1, textures, folder, then);
        }
    };
    addImportedFilesToZip (zip, index, importedFiles, folder, then) {
        if (index === importedFiles.length) {
            then();
            return;
        }

        if (!folder) {
            folder = zip.folder("scenes");
        }
        var url = importedFiles[index];

        var name = url.substr(url.lastIndexOf("/") + 1);

        this.addContentToZip(folder,
            name,
            url,
            null,
            true,
            function () {
                this.addImportedFilesToZip(zip, index + 1, importedFiles, folder, then);
            }.bind(this));
    };
    getZip (engine) {
        if (engine.scenes.length === 0) {
            return;
        }

        var zip = new JSZip();

        var scene = engine.scenes[0];
        var textures = scene.textures;
        var importedFiles = scene.importedMeshesFiles;

        document.getElementById("statusBar").innerHTML = "Creating archive... Please wait.";

        var regex = /CreateGroundFromHeightMap\(".+", "(.+)"/g;

        do {
            let match = regex.exec(this.zipCode);            

            if (!match) {
                break;
            }

            textures.push({ name: match[1] });
        } while(true);


        this.addContentToZip(zip,
            "index.html",
            "/zipContent/index.html",
            this.zipCode,
            false,
            function () {
                this.addTexturesToZip(zip,
                    0,
                    textures,
                    null,
                    function () {
                        this.addImportedFilesToZip(zip,
                            0,
                            importedFiles,
                            null,
                            function () {
                                var blob = zip.generate({ type: "blob" });
                                saveAs(blob, "sample.zip");
                                document.getElementById("statusBar").innerHTML = "";
                            }.bind(this));
                    }.bind(this));
            }.bind(this));
    };
}