// CreateBuildDirectory.js -- Build Directory Mirror
// Usage: cscript CreateBuildDirectory.js [source directory] [target directory]
//
// This script takes a source directory (containing all of the files you want
// to include in the installer) and recursively creates an identical target 
// directory structure except with all zero-byte dummy files. This makes the 
// test-build-verify cycle a hell of a lot faster by making the the compression 
// cycle negligible.
//
// Once you've finished building/testing the NSIS build script on the dummy files, 
// you copy it back to the original directory and run it against the full-size files.
//
// This script was created in a fit of irritation at the amount of time I 
// spent waiting for the Nullsoft installer compiler to compress files over
// and over again. To use it, you've got to have Windows Scripting Host 
// (2.0 or 5.6?).
//
// Variables
// ---------
// FSO                                              //  Standard FileSystemObject.
// SourceFolder
// DestFolder

var Out          =  WScript.StdOut;

function Usage(errno) 
{
    Out.WriteLine("Usage: cscript CreateBuildDirectory.js [source directory] [target directory]");
    Out.WriteLine();
    Out.WriteLine("Example:");
    Out.WriteLine("       cscript CreateBuildDirectory.js c:\\Source  c:\\Target");
    Out.WriteLine("or:    cscript CreateBuildDirectory.js c:\\Source\\   \\Target");
    Out.WriteLine();
    Out.WriteLine("Trailing backslashes '\\' are ok, relative paths are ok.");
    Out.WriteLine("The target directory will be non-recursively created if it does not exist.");
    Out.WriteLine("  e.g. if c:\\Foo\\Target is used, Foo must exist before Target can be created.");
    WScript.Quit(errno);
}

if (WScript.Arguments.length != 2) { 
    Usage(0);
}

var FSO    =  WScript.CreateObject("Scripting.FileSystemObject");
if (FSO.FolderExists(WScript.Arguments(0))) 
{
    WScript.Echo(WScript.Arguments(0) + " exists.");
}
else
{
    WScript.Echo(WScript.Arguments(0) + " doesn't exist.");
    Usage(1);
}
if (FSO.FolderExists(WScript.Arguments(1)))
{
    WScript.Echo(WScript.Arguments(1) + " exists.");
}
else
{
    WScript.Echo(WScript.Arguments(1) + " doesn't exist... creating");
    FSO.CreateFolder(WScript.Arguments(1));
}

var SourceFolder    =  FSO.GetFolder(WScript.Arguments(0));
var sfLength        =  SourceFolder.Path.length + 1;
var DestFolder      =  FSO.GetFolder(WScript.Arguments(1));

function DisplayCollection(Collection) {
    for ( ; !Collection.atEnd(); Collection.moveNext()) 
    {
        Out.WriteLine(Collection.item());
    }
}

function GetFiles(Folder) 
{
    FileList     =  new Enumerator(Folder.Files);
    return FileList;
}

function GetSubFolders(Folder) 
{
    FolderContents  =  new Enumerator(Folder.subFolders);
    return FolderContents;
}

function RecurseFolder(Folder)              // feed it the starting folder
{
    var FolderList  =  new Enumerator(Folder.subFolders);
    for ( ; !FolderList.atEnd(); FolderList.moveNext()) 
    {
       Out.WriteLine(FolderList.item());
       RecurseFolder(FSO.GetFolder(FolderList.item()));
    }
}

function MirrorFolder(Folder)               // feed it the starting folder
{
    var FolderList  =  new Enumerator(Folder.subFolders);
    for ( ; !FolderList.atEnd(); FolderList.moveNext()) 
    {
        currentFolder       =   FolderList.item();
        foldername          =   currentFolder.Path;
        foldername          =   foldername.slice(sfLength);
        destfoldername      =   DestFolder.Path + "\\" + foldername;
        Out.WriteLine("Folder: " + foldername + "--->" + destfoldername);
        if (!FSO.FolderExists(destfoldername)) 
        {
             FSO.CreateFolder(destfoldername);
        }
        
        MirrorFolder(FSO.GetFolder(currentFolder));

        FileList  =  GetFiles(currentFolder);
        for ( ; !FileList.atEnd(); FileList.moveNext())
        {
            file            =   FileList.item();       //  file.Path is the full path + filename
            filename        =   file.Path;              //  file.Name is just the filename
            filename        =   filename.slice(sfLength);
            destfilename    =   DestFolder.Path + "\\" + filename;
            Out.WriteLine("File: " + filename + "--->" + destfilename);
            FSO.CreateTextFile(destfilename, true);
        }
    }
    
    FileList  =  GetFiles(Folder);
    for ( ; !FileList.atEnd(); FileList.moveNext())
    {
        file            =   FileList.item();       //  file.Path is the full path + filename
        filename        =   file.Path;              //  file.Name is just the filename
        filename        =   filename.slice(sfLength);
        destfilename    =   DestFolder.Path + "\\" + filename;
        Out.WriteLine("File: " + filename + "--->" + destfilename);
        FSO.CreateTextFile(destfilename, true);
    }
}

Out.WriteLine("---SourceFolder Subdirectories---");
DisplayCollection(GetSubFolders(SourceFolder));

Out.WriteLine("---SourceFolder Recursive Subdirectories---");
Out.WriteLine(SourceFolder.Path);
RecurseFolder(SourceFolder);

Out.WriteLine("---Recurse and Mirror Source Directory---");
MirrorFolder(SourceFolder);