<commit_before>// Copyright 2002-2013, University of Colorado Boulder

/**
 * The navigation bar at the bottom of the screen.
 * For a single-screen sim, it shows the name of the sim at the far left and the PhET button at the far right.
 * For a multi-screen sim, it additionally shows buttons for each screen, and a home button.
 *
 * @author <NAME>
 * @author <NAME> (PixelZoom, Inc.)
 */
define( function( require ) {
  'use strict';

  // modules
  var HomeButton = require( 'JOIST/HomeButton' );
  var inherit = require( 'PHET_CORE/inherit' );
  var NavigationBarScreenButton = require( 'JOIST/NavigationBarScreenButton' );
  var Node = require( 'SCENERY/nodes/Node' );
  var PhetButton = require( 'JOIST/PhetButton' );
  var PhetFont = require( 'SCENERY_PHET/PhetFont' );
  var Rectangle = require( 'SCENERY/nodes/Rectangle' );
  var Text = require( 'SCENERY/nodes/Text' );

  // constants
  var TITLE_LEFT_MARGIN = 10;
  var TITLE_RIGHT_MARGIN = 20;
  var PHET_BUTTON_LEFT_MARGIN = TITLE_RIGHT_MARGIN;
  var HOME_BUTTON_LEFT_MARGIN = 20;
  var SCREEN_BUTTON_SPACING = 0;

  /**
   * Creates a nav bar.
   * @param {Dimension2} barSize initial dimensions of the navigation bar
   * @param {Sim} sim
   * @param {Screen[]} screens
   * @param {Object} [options]
   * @constructor
   */
  function NavigationBar( barSize, sim, screens, options ) {

    options = _.extend( {
      tandem: null
    }, options );

    //TODO #263 this requirement is disabled until we decide how to address it, since several sims violate it
    //if ( screens.length > 1 ) {
    //  assert && assert( _.findIndex( screens, function( screen ) {
    //      return ( screen.navigationBarIcon.width !== screens[ 0 ].navigationBarIcon.width ) || ( screen.navigationBarIcon.height !== screens[ 0 ].navigationBarIcon.height );
    //    } ) === -1,
    //    'all navigation bar icons must have the same size' );
    //}

    this.screens = screens;

    Node.call( this );

    // The bar's background
    this.background = new Rectangle( 0, 0, barSize.width, barSize.height );
    sim.lookAndFeel.navigationBarFillProperty.linkAttribute( this.background, 'fill' );
    this.addChild( this.background );

    // Sim title
    var title = new Text( sim.name, {
      font: new PhetFont( 18 )
    } );
    sim.lookAndFeel.navigationBarTextFillProperty.linkAttribute( title, 'fill' );
    this.titleParent = new Node( { children: [ title ] } ); // wrap in a parent node, so we can scale the parent without affecting title.maxWidth
    this.addChild( this.titleParent );

    // PhET button
    this.phetButton = new PhetButton( sim, sim.lookAndFeel.navigationBarFillProperty, sim.lookAndFeel.navigationBarTextFillProperty, {
      tandem: options.tandem ? options.tandem.createTandem( 'phetButton' ) : null
    } );
    this.addChild( this.phetButton );

    if ( screens.length === 1 ) {
      /* single-screen sim */

      // title can occupy all space to the left of the PhET button
      title.maxWidth = this.background.width - TITLE_LEFT_MARGIN - TITLE_RIGHT_MARGIN - this.phetButton.width - PhetButton.HORIZONTAL_INSET;
    }
    else {
      /* multi-screen sim */

      // title can occupy this percentage of the bar
      title.maxWidth = 0.3 * this.background.width;

      // Create the home button
      this.homeButton = new HomeButton( barSize.height, sim.lookAndFeel.navigationBarFillProperty, {
        listener: function() {
          sim.showHomeScreen = true;
        }
      } );
      this.addChild( this.homeButton );

      // Allocate remaining horizontal space equally for screen buttons, assuming they will be centered in the navbar.
      // available width left of center
      var availableLeft = ( this.background.width / 2 ) - TITLE_LEFT_MARGIN - this.titleParent.width - TITLE_RIGHT_MARGIN;
      // available width right of center
      var availableRight = ( this.background.width / 2 ) - HOME_BUTTON_LEFT_MARGIN - this.homeButton.width - PHET_BUTTON_LEFT_MARGIN - this.phetButton.width - PhetButton.HORIZONTAL_INSET;
      // total available width for the screen buttons when they are centered
      var availableTotal = 2 * Math.min( availableLeft, availableRight );
      // width per screen button
      var screenButtonWidth = ( availableTotal / screens.length ) - ( ( screens.length - 1 ) * SCREEN_BUTTON_SPACING );

      var screenButtons = _.map( screens, function( screen ) {
        return new NavigationBarScreenButton(
          sim.lookAndFeel.navigationBarFillProperty,
          sim.screenIndexProperty,
          sim.screens,
          screen,
          barSize.height, {
            maxTextWidth: screenButtonWidth, //TODO #241 this is closer, but not quite right, since it doesn't account for the button highlight
            tandem: options.tandem && options.tandem.createTandem( screen.tandemScreenName + 'Button' )
          } );
      } );

      // Layout out screen buttons horizontally, with equal distance between their centers
      var maxScreenButtonWidth = Math.max( 50, _.max( screenButtons, function( button ) { return button.width; } ).width );
      for ( var i = 1; i < screenButtons.length; i++ ) {
        screenButtons[ i ].centerX = screenButtons[ i - 1 ].centerX + maxScreenButtonWidth + SCREEN_BUTTON_SPACING;
      }

      // Put all screen buttons under a parent, to simplify layout
      this.screenButtonsParent = new Node( {
        children: screenButtons,
        maxWidth: availableTotal // in case we have so many screens that the screen buttons need to be scaled down<commit_msg>#241 remove magic number in computation of maxScreenButtonWidth, increase SCREEN_BUTTON_SPACING<commit_after>// Copyright 2002-2013, University of Colorado Boulder

/**
 * The navigation bar at the bottom of the screen.
 * For a single-screen sim, it shows the name of the sim at the far left and the PhET button at the far right.
 * For a multi-screen sim, it additionally shows buttons for each screen, and a home button.
 *
 * @author <NAME>
 * @author <NAME> (PixelZoom, Inc.)
 */
define( function( require ) {
  'use strict';

  // modules
  var HomeButton = require( 'JOIST/HomeButton' );
  var inherit = require( 'PHET_CORE/inherit' );
  var NavigationBarScreenButton = require( 'JOIST/NavigationBarScreenButton' );
  var Node = require( 'SCENERY/nodes/Node' );
  var PhetButton = require( 'JOIST/PhetButton' );
  var PhetFont = require( 'SCENERY_PHET/PhetFont' );
  var Rectangle = require( 'SCENERY/nodes/Rectangle' );
  var Text = require( 'SCENERY/nodes/Text' );

  // constants
  var TITLE_LEFT_MARGIN = 10;
  var TITLE_RIGHT_MARGIN = 20;
  var PHET_BUTTON_LEFT_MARGIN = TITLE_RIGHT_MARGIN;
  var HOME_BUTTON_LEFT_MARGIN = 20;
  var SCREEN_BUTTON_SPACING = 10;

  /**
   * Creates a nav bar.
   * @param {Dimension2} barSize initial dimensions of the navigation bar
   * @param {Sim} sim
   * @param {Screen[]} screens
   * @param {Object} [options]
   * @constructor
   */
  function NavigationBar( barSize, sim, screens, options ) {

    options = _.extend( {
      tandem: null
    }, options );

    //TODO #263 this requirement is disabled until we decide how to address it, since several sims violate it
    //if ( screens.length > 1 ) {
    //  assert && assert( _.findIndex( screens, function( screen ) {
    //      return ( screen.navigationBarIcon.width !== screens[ 0 ].navigationBarIcon.width ) || ( screen.navigationBarIcon.height !== screens[ 0 ].navigationBarIcon.height );
    //    } ) === -1,
    //    'all navigation bar icons must have the same size' );
    //}

    this.screens = screens;

    Node.call( this );

    // The bar's background
    this.background = new Rectangle( 0, 0, barSize.width, barSize.height );
    sim.lookAndFeel.navigationBarFillProperty.linkAttribute( this.background, 'fill' );
    this.addChild( this.background );

    // Sim title
    var title = new Text( sim.name, {
      font: new PhetFont( 18 )
    } );
    sim.lookAndFeel.navigationBarTextFillProperty.linkAttribute( title, 'fill' );
    this.titleParent = new Node( { children: [ title ] } ); // wrap in a parent node, so we can scale the parent without affecting title.maxWidth
    this.addChild( this.titleParent );

    // PhET button
    this.phetButton = new PhetButton( sim, sim.lookAndFeel.navigationBarFillProperty, sim.lookAndFeel.navigationBarTextFillProperty, {
      tandem: options.tandem ? options.tandem.createTandem( 'phetButton' ) : null
    } );
    this.addChild( this.phetButton );

    if ( screens.length === 1 ) {
      /* single-screen sim */

      // title can occupy all space to the left of the PhET button
      title.maxWidth = this.background.width - TITLE_LEFT_MARGIN - TITLE_RIGHT_MARGIN - this.phetButton.width - PhetButton.HORIZONTAL_INSET;
    }
    else {
      /* multi-screen sim */

      // title can occupy this percentage of the bar
      title.maxWidth = 0.3 * this.background.width;

      // Create the home button
      this.homeButton = new HomeButton( barSize.height, sim.lookAndFeel.navigationBarFillProperty, {
        listener: function() {
          sim.showHomeScreen = true;
        }
      } );
      this.addChild( this.homeButton );

      // Allocate remaining horizontal space equally for screen buttons, assuming they will be centered in the navbar.
      // available width left of center
      var availableLeft = ( this.background.width / 2 ) - TITLE_LEFT_MARGIN - this.titleParent.width - TITLE_RIGHT_MARGIN;
      // available width right of center
      var availableRight = ( this.background.width / 2 ) - HOME_BUTTON_LEFT_MARGIN - this.homeButton.width - PHET_BUTTON_LEFT_MARGIN - this.phetButton.width - PhetButton.HORIZONTAL_INSET;
      // total available width for the screen buttons when they are centered
      var availableTotal = 2 * Math.min( availableLeft, availableRight );
      // width per screen button
      var screenButtonWidth = ( availableTotal / screens.length ) - ( ( screens.length - 1 ) * SCREEN_BUTTON_SPACING );

      var screenButtons = _.map( screens, function( screen ) {
        return new NavigationBarScreenButton(
          sim.lookAndFeel.navigationBarFillProperty,
          sim.screenIndexProperty,
          sim.screens,
          screen,
          barSize.height, {
            maxTextWidth: screenButtonWidth, //TODO #241 this is closer, but not quite right, since it doesn't account for the button highlight
            tandem: options.tandem && options.tandem.createTandem( screen.tandemScreenName + 'Button' )
          } );
      } );

      // Layout out screen buttons horizontally, with equal distance between their centers
      var maxScreenButtonWidth = _.max( screenButtons, function( button ) { return button.width; } ).width;
      for ( var i = 1; i < screenButtons.length; i++ ) {
        screenButtons[ i ].centerX = screenButtons[ i - 1 ].centerX + maxScreenButtonWidth + SCREEN_BUTTON_SPACING;
      }

      // Put all screen buttons under a parent, to simplify layout
      this.screenButtonsParent = new Node( {
        children: screenButtons,
        maxWidth: availableTotal // in case we have so many screens that the screen buttons need to be scaled down
{'fraction_non_alphanumeric': 0.10088701729235731, 'fraction_numerical': 0.007526207329092375, 'mean_word_length': 2.955350815024805, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '69839', 'n_tokens_mistral': 3384, 'n_tokens_neox': 3225, 'n_words': 994}