text: /**
   * @license
   * Copyright 2017 Google LLC
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *   http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  /**
   * @fileoverview Variable blocks for Blockly.
  
   * This file is scraped to extract a .json file of block definitions. The array
   * passed to defineBlocksWithJsonArray(..) must be strict JSON: double quotes
   * only, no outside references, no functions, no trailing commas, etc. The one
   * exception is end-of-line comments, which the scraper will remove.
   * @author duzc2dtw@gmail.com (Du Tian Wei)
   */
  'use strict';
  
  goog.provide('Blockly.Constants.VariablesDynamic');
  
  goog.require('Blockly');
  goog.require('Blockly.Blocks');
  goog.require('Blockly.FieldLabel');
  goog.require('Blockly.FieldVariable');
  
  
  /**
   * Unused constant for the common HSV hue for all blocks in this category.
   * @deprecated Use Blockly.Msg['VARIABLES_DYNAMIC_HUE']. (2018 April 5)
   */
  Blockly.Constants.VariablesDynamic.HUE = 310;
  
  Blockly.defineBlocksWithJsonArray([ // BEGIN JSON EXTRACT
    // Block for variable getter.
    {
      "type": "variables_get_dynamic",
      "message0": "%1",
      "args0": [{
        "type": "field_variable",
        "name": "VAR",
        "variable": "%{BKY_VARIABLES_DEFAULT_NAME}"
      }],
      "output": null,
      "style": "variable_dynamic_blocks",
      "helpUrl": "%{BKY_VARIABLES_GET_HELPURL}",
      "tooltip": "%{BKY_VARIABLES_GET_TOOLTIP}",
      "extensions": ["contextMenu_variableDynamicSetterGetter"]
    },
    // Block for variable setter.
    {
      "type": "variables_set_dynamic",
      "message0": "%{BKY_VARIABLES_SET}",
      "args0": [{
        "type": "field_variable",
        "name": "VAR",
        "variable": "%{BKY_VARIABLES_DEFAULT_NAME}"
      },
      {
        "type": "input_value",
        "name": "VALUE"
      }
      ],
      "previousStatement": null,
      "nextStatement": null,
      "style": "variable_dynamic_blocks",
      "tooltip": "%{BKY_VARIABLES_SET_TOOLTIP}",
      "helpUrl": "%{BKY_VARIABLES_SET_HELPURL}",
      "extensions": ["contextMenu_variableDynamicSetterGetter"]
    }
  ]); // END JSON EXTRACT (Do not delete this comment.)
  
  /**
   * Mixin to add context menu items to create getter/setter blocks for this
   * setter/getter.
   * Used by blocks 'variables_set_dynamic' and 'variables_get_dynamic'.
   * @mixin
   * @augments Blockly.Block
   * @package
   * @readonly
   */
  Blockly.Constants.VariablesDynamic.CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MIXIN = {
    /**
     * Add menu option to create getter/setter block for this setter/getter.
     * @param {!Array} options List of menu options to add to.
     * @this {Blockly.Block}
     */
    customContextMenu: function(options) {
      // Getter blocks have the option to create a setter block, and vice versa.
      if (!this.isInFlyout) {
        var opposite_type;
        var contextMenuMsg;
        var id = this.getFieldValue('VAR');
        var variableModel = this.workspace.getVariableById(id);
        var varType = variableModel.type;
        if (this.type == 'variables_get_dynamic') {
          opposite_type = 'variables_set_dynamic';
          contextMenuMsg = Blockly.Msg['VARIABLES_GET_CREATE_SET'];
        } else {
          opposite_type = 'variables_get_dynamic';
          contextMenuMsg = Blockly.Msg['VARIABLES_SET_CREATE_GET'];
        }
  
        var option = {enabled: this.workspace.remainingCapacity() > 0};
        var name = this.getField('VAR').getText();
        option.text = contextMenuMsg.replace('%1', name);
        var xmlField = Blockly.utils.xml.createElement('field');
        xmlField.setAttribute('name', 'VAR');
        xmlField.setAttribute('variabletype', varType);
        xmlField.appendChild(Blockly.utils.xml.createTextNode(name));
        var xmlBlock = Blockly.utils.xml.createElement('block');
        xmlBlock.setAttribute('type', opposite_type);
        xmlBlock.appendChild(xmlField);
        option.callback = Blockly.ContextMenu.callbackFactory(this, xmlBlock);
        options.push(option);
      } else {
        if (this.type == 'variables_get_dynamic' ||
         this.type == 'variables_get_reporter_dynamic') {
          var renameOption = {
            text: Blockly.Msg.RENAME_VARIABLE,
            enabled: true,
            callback: Blockly.Constants.Variables.RENAME_OPTION_CALLBACK_FACTORY(this)
          };
          var name = this.getField('VAR').getText();
          var deleteOption = {
            text: Blockly.Msg.DELETE_VARIABLE.replace('%1', name),
            enabled: true,
            callback: Blockly.Constants.Variables.DELETE_OPTION_CALLBACK_FACTORY(this)
          };
          options.unshift(renameOption);
          options.unshift(deleteOption);
        }
      }
    },
    /**
     * Called whenever anything on the workspace changes.
     * Set the connection type for this block.
     * @param {!Blockly.Events.Abstract} _e Change event.
     * @this {Blockly.Block}
     */
    onchange: function(_e) {
      var id = this.getFieldValue('VAR');
      var variableModel = Blockly.Variables.getVariable(this.workspace, id);
      if (this.type == 'variables_get_dynamic') {
        this.outputConnection.setCheck(variableModel.type);
      } else {
        this.getInput('VALUE').connection.setCheck(variableModel.type);
      }
    }
  };
  
  /**
    * Callback for rename variable dropdown menu option associated with a
    * variable getter block.
    * @param {!Blockly.Block} block The block with the variable to rename.
    * @return {!function()} A function that renames the variable.
    */
  Blockly.Constants.VariablesDynamic.RENAME_OPTION_CALLBACK_FACTORY = function(block) {
    return function() {
      var workspace = block.workspace;
      var variable = block.getField('VAR').getVariable();
      Blockly.Variables.renameVariable(workspace, variable);
    };
  };
  
  /**
   * Callback for delete variable dropdown menu option associated with a
   * variable getter block.
   * @param {!Blockly.Block} block The block with the variable to delete.
   * @return {!function()} A function that deletes the variable.
   */
  Blockly.Constants.VariablesDynamic.DELETE_OPTION_CALLBACK_FACTORY = function(block) {
    return function() {
      var workspace = block.workspace;
      var variable = block.getField('VAR').getVariable();
      workspace.deleteVariableById(variable.getId());
      workspace.refreshToolboxSelection();
    };
  };
  
  Blockly.Extensions.registerMixin('contextMenu_variableDynamicSetterGetter',
      Blockly.Constants.VariablesDynamic.CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MIXIN);
  