/**
 
GearsZipper - a utility function to generate zip files in Gears
(c) 2009 Franz Buchinger fbuchinger at gmail dot com
 
Licenced under the GPLv3 and the MIT licences
 
Usage:
    GearsZipper(fileArray, callback);
    
    fileArray = [
        {data: "A Javascript String", file: 'dir/file.ext'},
        {url: 'style.css'},                                     //relative url, stored under the same filename in the zip
        {url: 'js/jszip.js', file: 'js/javascript-zipper.js'},  //relative url, stored under a different filename
        {blob: GearsBlobObject, file: 'img/canvas.jpg'}         //a Gears Blob Object (e.g. encoded from a Gears canvas)
    ];

    callback = function (zipUrl){
            if (zipUrl !== null){
                //success
            }
            else {
                //failure
            }
        }
 
**/


function GearsZipper (inputFiles, callback){
    var localServer = google.gears.factory.create('beta.localserver');
    var blobBuilder = google.gears.factory.create('beta.blobbuilder');
    var zipStore = localServer.openStore('foobar2');
    var zip = new JSZip();
    var captureFiles = [];
    var url2filename = {};
    var captureCount = 0;
    var callback = callback

    if (zipStore == null){
        zipStore = localServer.createStore('foobar2');
    }
    
    for (var f=0; f < inputFiles.length; f++){
        var curFile = inputFiles[f];
        if (curFile.data && curFile.file){
            zip.add(curFile.file, curFile.data);
        }
        else if (curFile.url && curFile.file){ 
            captureFiles.push(curFile.url);
            url2filename[curFile.url] = curFile.file;
        }
        else if (curFile.blob && curFile.file){
            zip.add(curFile.file, _blob2bytes(curFile.blob));
        }
        else if (curFile.url){
            captureFiles.push(curFile.url);
            url2filename[curFile.url] = curFile.url;
        }
    }
    if (captureFiles.length === 0){
       _finalizeZip(); //we have no gears files to capture, so finish the zip
    }
    else {
        zipStore.capture(captureFiles, _urlCaptured);
    }
    
    
    function _urlCaptured (url, success, captureId){
        if (success === true){
            var fileBlob = zipStore.getAsBlob(url);
            var zipContent = '';
            var contentType = zipStore.getHeader(url,'Content-Type');
            var fileBytes = _blob2bytes(fileBlob);
            zip.add(url2filename[url], fileBytes);
        }
        captureCount++;
        if (captureCount === captureFiles.length){
            _finalizeZip();
        }
    }
    
    function _finalizeZip(){
        var content = zip.generate(true);
        for (var c = 0; c < content.length; c++){
            blobBuilder.append(content.charCodeAt(c));
        }
        var now = new Date();
        var zipUrl = now.getTime() + '.zip';
        zipStore.captureBlob(blobBuilder.getAsBlob(), zipUrl,'application/zip');
        callback (zipUrl);
    }
    
    function _blob2bytes (blob){
        var bytes = [];
        var byteString = '';
        var nBytes = blob.length;
        var nStep = 0;

        for (nStep = 0; nStep < nBytes; nStep += 1024) {
            var nLen = nBytes - nStep;
            if( nLen > 1024 ) nLen = 1024;
            bytes = blob.getBytes(nStep,nLen);
            for (var b = 0; b < nLen; b++){
                byteString += String.fromCharCode(bytes[b]);
            }
        }
        return byteString;
    }
    
    function _bytes2ascii (byteArr){
        var asciiStr = '';
        for (var b = 0; b < byteArr.length; b++){
            asciiStr += String.fromCharCode(byteArr[b]);
        }
        return asciiStr;
    }
}
