nsresult
nsDOMWorkerScriptLoader::LoadScripts(JSContext* aCx,
                                     const nsTArray<nsString>& aURLs,
                                     PRBool aForWorker)
{
  NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
  NS_ASSERTION(aCx, "Null context!");

  mTarget = NS_GetCurrentThread();
  NS_ASSERTION(mTarget, "This should never be null!");

  if (mCanceled) {
    return NS_ERROR_ABORT;
  }

  mForWorker = aForWorker;

  mScriptCount = aURLs.Length();
  if (!mScriptCount) {
    return NS_ERROR_INVALID_ARG;
  }

  // Do all the memory work for these arrays now rather than checking for
  // failures all along the way.
  PRBool success = mLoadInfos.SetCapacity(mScriptCount);
  NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY);

  // Need one runnable per script and then an extra for the finished
  // notification.
  success = mPendingRunnables.SetCapacity(mScriptCount + 1);
  NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY);

  for (PRUint32 index = 0; index < mScriptCount; index++) {
    ScriptLoadInfo* newInfo = mLoadInfos.AppendElement();
    NS_ASSERTION(newInfo, "Shouldn't fail if SetCapacity succeeded above!");

    newInfo->url.Assign(aURLs[index]);
    if (newInfo->url.IsEmpty()) {
      return NS_ERROR_INVALID_ARG;
    }

    success = newInfo->scriptObj.Hold(aCx);
    NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
  }

  // Don't want timeouts, etc., from queuing up while we're waiting on the
  // network or compiling.
  AutoSuspendWorkerEvents aswe(this);

  nsresult rv = DoRunLoop(aCx);
  if (NS_FAILED(rv)) {
    return rv;
  }

  // Verify that all scripts downloaded and compiled.
  rv = VerifyScripts(aCx);
  if (NS_FAILED(rv)) {
    return rv;
  }

  rv = ExecuteScripts(aCx);
  if (NS_FAILED(rv)) {
    return rv;
  }

  return NS_OK;
}
int main(int argc, char* argv[])
{
    std::wstring blenderPath;

    if (argc == 1)
    {
        // no arguments were provided -- user probably just tried to run it
        // we'll provide the opportunity to change the directory through this,
        // even if it was already valid.
        if (!DoesFileExist(DIRECTORY_FILE_NAME))
        {
            int result = MessageBox(NULL, L"It looks like Blender hasn't been located yet by this program.  Would you like to do this now?",
                L"First time setup", MB_YESNOCANCEL | MB_ICONINFORMATION);
            if (result == IDYES)
            {
                PromptForBlender(blenderPath);
            }
            return 0;
        }

        ReadFromFile(DIRECTORY_FILE_NAME, blenderPath);

        if (!DoesFileExist(blenderPath))
        {
            int result = MessageBox(NULL, L"Valid blender install not found.  Would you like to do this now?",
                L"First time setup", MB_YESNOCANCEL | MB_ICONINFORMATION);
            if (result == IDYES)
            {
                PromptForBlender(blenderPath);
            }
            return 0;
        }

        int result = MessageBox(NULL, L"Looks like a blender install has already been located.  Do you wish to change it?",
            L"Change blender location", MB_YESNOCANCEL | MB_ICONINFORMATION);
        if (result == IDYES)
        {
            PromptForBlender(blenderPath);
        }
        
        if (!VerifyXmlEntries())
        {
            std::wstring message = L"There was a problem verifying that " + XmlFileName + L" contains the correct "
                L"entries to make Builder work with this utility.";
            MessageBox(NULL, message.c_str(), L"Error", MB_OK | MB_ICONERROR);
        }

        if (!VerifyScripts())
        {
            MessageBox(NULL, L"One or more scripts are missing and replacing them failed.", L"Error", MB_OK | MB_ICONERROR);
        }
        return 0;
    }
    
    if (!EnsureValidBlenderDirectory(blenderPath))
    {
        std::cerr << "Blender directory invalid!  Cannot proceed." << std::endl;
        return 1;
    }

    if (argc > 2)
    {
        std::cerr << "Too many arguments!" << std::endl;
        return 1;
    }

    if (!VerifyScripts())
    {
        std::cerr << "One or more scripts are missing and replacing them failed." << std::endl;
        return 1;
    }

    // first argument is of course the execution directory of this file.
    // second argument should be the location of the .blend file they wish to compile.

    std::wstring blendFile = sToW(argv[1]);
    std::wstring command;
    std::wstring programDir = sToW(getCurrentPath());

    command = L"\"\"" + blenderPath + L"\" -b \"" + blendFile + L"\" -P " + SCRIPTS_DIRECTORY + SCRIPT_FILE_NAME + L" -- \"" + programDir + SCRIPTS_DIRECTORY + L"\"";

    _wsystem(command.c_str());

    return 0;
}