// Copyright 2013-2015, University of Colorado Boulder
/**
 * Launches a PhET Simulation, after preloading the specified images.
 *
 * @author Sam Reid (PhET Interactive Simulations)
 */
define( function( require ) {
  'use strict';

  // modules
  var checkNamespaces = require( 'JOIST/checkNamespaces' );
  var joist = require( 'JOIST/joist' );
  var Tandem = require( 'TANDEM/Tandem' );
  var Random = require( 'DOT/Random' );
  var Brand = require( 'BRAND/Brand' );

  // phet-io modules
  var SimIFrameAPI = require( 'ifphetio!PHET_IO/SimIFrameAPI' );
  var TPhETIO = require( 'ifphetio!PHET_IO/types/TPhETIO' );
  var phetio = require( 'ifphetio!PHET_IO/phetio' );

  var SimLauncher = {

    /**
     * Launch the Sim by preloading the images and calling the callback.
     *
     * @param callback the callback function which should create and start the sim, given that the images are loaded
     * @public - to be called by main()s everywhere
     */
    launch: function( callback ) {
      assert && assert( !window.phet.launchCalled, 'Tried to launch twice' );

      //Signify that the SimLauncher was called, see https://github.com/phetsims/joist/issues/142
      window.phet.joist.launchCalled = true;

      // image elements to remove once we are fully loaded
      var elementsToRemove = [];

      function doneLoadingImages() {

        window.phetLaunchSimulation = function() {

          // Register all of the static tandems.
          Tandem.launch();

          // Provide a global Random that is easy to use and seedable from phet-io for playback
          // phet-io configuration happens after SimLauncher.launch is called and before phetLaunchSimulation is called
          phet.joist.random = new Random( { staticSeed: true } );

          // Instantiate the sim and show it.
          callback();
        };

        // PhET-iO simulations support an initialization phase (before the sim launches)
        if ( Brand.phetioEnabled ) {
          new Tandem( 'phetio' ).addInstance( phetio, TPhETIO );
          SimIFrameAPI.initialize(); // calls back to window.phetLaunchSimulation
        }

        https://github.com/phetsims/phet-io/issues/1106        if ( phet.phetio && !phet.phetio.queryParameters.phetioStandalone ) {

          // Wait for phet-io to finish adding listeners. It will direct the launch from there.
        }
        else {
          window.phetLaunchSimulation();
        }
      }

      // if image dimensions exist, immediately fire the "all images loaded" event
      var loaded = 0;

      // Taken from http://stackoverflow.com/questions/1977871/check-if-an-image-is-loaded-no-errors-in-javascript
      function isImageOK( img ) {

        // During the onload event, IE correctly identifies any images that
        // weren’t downloaded as not complete. Others should too. Gecko-based
        // browsers act like NS4 in that they report this incorrectly.
        if ( !img.complete ) {
          return false;
        }

        // However, they do have two very useful properties: naturalWidth and
        // naturalHeight. These give the true size of the image. If it failed
        // to load, either of these should be zero.
        if ( typeof img.naturalWidth !== 'undefined' && img.naturalWidth === 0 ) {
          return false;
        }

        // No other way of checking: assume it’s ok.
        return true;
      }

      //For the images that were written to base64 format using requirejs, make sure they are loaded.
      //img.src = base64 is asynchronous on IE10 and OSX/Safari, so we have to make sure they loaded before returning.
      if ( window.phetImages ) {
        for ( var i = 0; i < window.phetImages.length; i++ ) {
          var phetImage = window.phetImages[ i ];

          // For built versions that use phet-io, the simulation may have already loaded all of the images, so
          // check them here before scheduling them for load.
          if ( isImageOK( phetImage ) ) {
            loaded++;
            if ( loaded === window.phetImages.length ) {
              doneLoadingImages();
            }
          }
          else {
            phetImage.onload = function() {
              loaded++;
              if ( loaded === window.phetImages.length ) {
                doneLoadingImages();
              }
            };
          }

        }
      }
      else {
        doneLoadingImages();
      }

      $( window ).load( function() {
        // if images were not loaded immediately, signal the "all images loaded" event

        // we wait for here to remove the images from the DOM, otherwise IE9/10 treat the images as completely blank!
        _.each( elementsToRemove, function( element ) {

          //TODO: Why is this null sometimes?  see https://github.com/phetsims/joist/issues/388
          if ( element.parentNode ) {
            element.parentNode.removeChild( element );
          }
        } );
      } );

      // Check namespaces if assertions are enabled, see https://github.com/phetsims/joist/issues/307.
      assert && checkNamespaces();
    }
  };

  joist.register( 'SimLauncher', SimLauncher );

  return SimLauncher;
} );
@@ -2122,63 +2122,8 @@
  %7D%0A%0A
-        https://github.com/phetsims/phet-io/issues/1106
     

migrate phet.chipper.brand to us phet.phetio to check for phetioEnabled, https://github.com/phetsims/phet-io/issues/1106