text: /**
   * @license
   * Visual Blocks Editor
   *
   * Copyright 2012 Google Inc.
   * https://developers.google.com/blockly/
   *
   * 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 Logic blocks for Blockly.
   * @author q.neutron@gmail.com (Quynh Neutron)
   */
  'use strict';
  
  goog.provide('Blockly.Blocks.logic');
  
  goog.require('Blockly.Blocks');
  
  
  /**
   * Common HSV hue for all blocks in this category.
   */
  Blockly.Blocks.logic.HUE = 210;
  
  Blockly.Blocks['controls_if'] = {
    /**
     * Block for if/elseif/else condition.
     * @this Blockly.Block
     */
    init: function() {
      this.setHelpUrl(Blockly.Msg.CONTROLS_IF_HELPURL);
      this.setColour(Blockly.CAT_LOGIC_RGB);
      this.appendValueInput('IF0')
          .setCheck('Boolean')
          .appendField(Blockly.Msg.CONTROLS_IF_MSG_IF);
      this.appendStatementInput('DO0')
          .appendField(Blockly.Msg.CONTROLS_IF_MSG_THEN);
      this.setPreviousStatement(true);
      this.setNextStatement(true);
      this.setMutator(new Blockly.Mutator(['controls_if_elseif',
                                           'controls_if_else']));
      // Assign 'this' to a variable for use in the tooltip closure below.
      var thisBlock = this;
      this.setTooltip(function() {
        if (!thisBlock.elseifCount_ && !thisBlock.elseCount_) {
          return Blockly.Msg.CONTROLS_IF_TOOLTIP_1;
        } else if (!thisBlock.elseifCount_ && thisBlock.elseCount_) {
          return Blockly.Msg.CONTROLS_IF_TOOLTIP_2;
        } else if (thisBlock.elseifCount_ && !thisBlock.elseCount_) {
          return Blockly.Msg.CONTROLS_IF_TOOLTIP_3;
        } else if (thisBlock.elseifCount_ && thisBlock.elseCount_) {
          return Blockly.Msg.CONTROLS_IF_TOOLTIP_4;
        }
        return '';
      });
      this.elseifCount_ = 0;
      this.elseCount_ = 0;
    },
    /**
     * Create XML to represent the number of else-if and else inputs.
     * @return {Element} XML storage element.
     * @this Blockly.Block
     */
    mutationToDom: function() {
      if (!this.elseifCount_ && !this.elseCount_) {
        return null;
      }
      var container = document.createElement('mutation');
      if (this.elseifCount_) {
        container.setAttribute('elseif', this.elseifCount_);
      }
      if (this.elseCount_) {
        container.setAttribute('else', 1);
      }
      return container;
    },
    /**
     * Parse XML to restore the else-if and else inputs.
     * @param {!Element} xmlElement XML storage element.
     * @this Blockly.Block
     */
    domToMutation: function(xmlElement) {
      this.elseifCount_ = parseInt(xmlElement.getAttribute('elseif'), 10) || 0;
      this.elseCount_ = parseInt(xmlElement.getAttribute('else'), 10) || 0;
      this.updateShape_();
    },
    /**
     * Populate the mutator's dialog with this block's components.
     * @param {!Blockly.Workspace} workspace Mutator's workspace.
     * @return {!Blockly.Block} Root block in mutator.
     * @this Blockly.Block
     */
    decompose: function(workspace) {
      var containerBlock = workspace.newBlock('controls_if_if');
      containerBlock.initSvg();
      var connection = containerBlock.nextConnection;
      for (var i = 1; i <= this.elseifCount_; i++) {
        var elseifBlock = workspace.newBlock('controls_if_elseif');
        elseifBlock.initSvg();
        connection.connect(elseifBlock.previousConnection);
        connection = elseifBlock.nextConnection;
      }
      if (this.elseCount_) {
        var elseBlock = workspace.newBlock('controls_if_else');
        elseBlock.initSvg();
        connection.connect(elseBlock.previousConnection);
      }
      return containerBlock;
    },
    /**
     * Reconfigure this block based on the mutator dialog's components.
     * @param {!Blockly.Block} containerBlock Root block in mutator.
     * @this Blockly.Block
     */
    compose: function(containerBlock) {
      var clauseBlock = containerBlock.nextConnection.targetBlock();
      // Count number of inputs.
      this.elseifCount_ = 0;
      this.elseCount_ = 0;
      var valueConnections = [null];
      var statementConnections = [null];
      var elseStatementConnection = null;
      while (clauseBlock) {
        switch (clauseBlock.type) {
          case 'controls_if_elseif':
            this.elseifCount_++;
            valueConnections.push(clauseBlock.valueConnection_);
            statementConnections.push(clauseBlock.statementConnection_);
            break;
          case 'controls_if_else':
            this.elseCount_++;
            elseStatementConnection = clauseBlock.statementConnection_;
            break;
          default:
            throw 'Unknown block type.';
        }
        clauseBlock = clauseBlock.nextConnection &&
            clauseBlock.nextConnection.targetBlock();
      }
      this.updateShape_();
      // Reconnect any child blocks.
      for (var i = 1; i <= this.elseifCount_; i++) {
        Blockly.Mutator.reconnect(valueConnections[i], this, 'IF' + i);
        Blockly.Mutator.reconnect(statementConnections[i], this, 'DO' + i);
      }
      Blockly.Mutator.reconnect(elseStatementConnection, this, 'ELSE');
    },
    /**
     * Store pointers to any connected child blocks.
     * @param {!Blockly.Block} containerBlock Root block in mutator.
     * @this Blockly.Block
     */
    saveConnections: function(containerBlock) {
      var clauseBlock = containerBlock.nextConnection.targetBlock();
      var i = 1;
      while (clauseBlock) {
        switch (clauseBlock.type) {
          case 'controls_if_elseif':
            var inputIf = this.getInput('IF' + i);
            var inputDo = this.getInput('DO' + i);
            clauseBlock.valueConnection_ =
                inputIf && inputIf.connection.targetConnection;
            clauseBlock.statementConnection_ =
                inputDo && inputDo.connection.targetConnection;
            i++;
            break;
          case 'controls_if_else':
            var inputDo = this.getInput('ELSE');
            clauseBlock.statementConnection_ =
                inputDo && inputDo.connection.targetConnection;
            break;
          default:
            throw 'Unknown block type.';
        }
        clauseBlock = clauseBlock.nextConnection &&
            clauseBlock.nextConnection.targetBlock();
      }
    },
    /**
     * Modify this block to have the correct number of inputs.
     * @private
     * @this Blockly.Block
     */
    updateShape_: function() {
      // Delete everything.
      if (this.getInput('ELSE')) {
        this.removeInput('ELSE');
      }
      var i = 1;
      while (this.getInput('IF' + i)) {
        this.removeInput('IF' + i);
        this.removeInput('DO' + i);
        i++;
      }
      // Rebuild block.
      for (var i = 1; i <= this.elseifCount_; i++) {
        this.appendValueInput('IF' + i)
            .setCheck('Boolean')
            .appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSEIF);
        this.appendStatementInput('DO' + i)
            .appendField(Blockly.Msg.CONTROLS_IF_MSG_THEN);
      }
      if (this.elseCount_) {
        this.appendStatementInput('ELSE')
            .appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSE);
      }
    }
  };
  
  Blockly.Blocks['controls_if_if'] = {
    /**
     * Mutator block for if container.
     * @this Blockly.Block
     */
    init: function() {
      this.setColour(Blockly.CAT_LOGIC_RGB);
      this.appendDummyInput()
          .appendField(Blockly.Msg.CONTROLS_IF_IF_TITLE_IF);
      this.setNextStatement(true);
      this.setTooltip(Blockly.Msg.CONTROLS_IF_IF_TOOLTIP);
      this.contextMenu = false;
    }
  };
  
  Blockly.Blocks['controls_if_elseif'] = {
    /**
     * Mutator bolck for else-if condition.
     * @this Blockly.Block
     */
    init: function() {
      this.setColour(Blockly.CAT_LOGIC_RGB);
      this.appendDummyInput()
          .appendField(Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF);
      this.setPreviousStatement(true);
      this.setNextStatement(true);
      this.setTooltip(Blockly.Msg.CONTROLS_IF_ELSEIF_TOOLTIP);
      this.contextMenu = false;
    }
  };
  
  Blockly.Blocks['controls_if_else'] = {
    /**
     * Mutator block for else condition.
     * @this Blockly.Block
     */
    init: function() {
      this.setColour(Blockly.CAT_LOGIC_RGB);
      this.appendDummyInput()
          .appendField(Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE);
      this.setPreviousStatement(true);
      this.setTooltip(Blockly.Msg.CONTROLS_IF_ELSE_TOOLTIP);
      this.contextMenu = false;
    }
  };
  
  Blockly.Blocks['logic_compare'] = {
    /**
     * Block for comparison operator.
     * @this Blockly.Block
     */
    init: function() {
      var OPERATORS = this.RTL ? [
            ['=', 'EQ'],
            ['\u2260', 'NEQ'],
            ['>', 'LT'],
            ['\u2265', 'LTE'],
            ['<', 'GT'],
            ['\u2264', 'GTE']
          ] : [
            ['=', 'EQ'],
            ['\u2260', 'NEQ'],
            ['<', 'LT'],
            ['\u2264', 'LTE'],
            ['>', 'GT'],
            ['\u2265', 'GTE']
          ];
      this.setHelpUrl(Blockly.Msg.LOGIC_COMPARE_HELPURL);
      this.setColour(Blockly.CAT_CONTROL_RGB);
      this.setOutput(true, 'Boolean');
      this.appendValueInput('A');
      this.appendValueInput('B')
          .appendField(new Blockly.FieldDropdown(OPERATORS), 'OP');
      this.setInputsInline(true);
      // Assign 'this' to a variable for use in the tooltip closure below.
      var thisBlock = this;
      this.setTooltip(function() {
        var op = thisBlock.getFieldValue('OP');
        var TOOLTIPS = {
          'EQ': Blockly.Msg.LOGIC_COMPARE_TOOLTIP_EQ,
          'NEQ': Blockly.Msg.LOGIC_COMPARE_TOOLTIP_NEQ,
          'LT': Blockly.Msg.LOGIC_COMPARE_TOOLTIP_LT,
          'LTE': Blockly.Msg.LOGIC_COMPARE_TOOLTIP_LTE,
          'GT': Blockly.Msg.LOGIC_COMPARE_TOOLTIP_GT,
          'GTE': Blockly.Msg.LOGIC_COMPARE_TOOLTIP_GTE
        };
        return TOOLTIPS[op];
      });
      this.prevBlocks_ = [null, null];
    },
    /**
     * Modify this block to have a appropriate operator. Only used in Roberta blocks.
     * @param {String} operator
     * @this Blockly.Block
     */
    updateShape : function(range) {
      // Set the range of operators.
      if (range) {
        this.operatorRange_ = range;
        var OPERATORS;
        var valueB = this.getInputTargetBlock('B');
        this.removeInput('B', true);
        this.removeInput('OP_DROP', true);     
        if (range == 'NUM_REV') {
          OPERATORS = Blockly.RTL ? [ [ '<', 'GT' ], [ '\u2264', 'GTE' ], [ '>', 'LT' ], [ '\u2265', 'LTE' ], [ '=', 'EQ' ], [ '\u2260', 'NEQ' ] ] : [
                      [ '>', 'GT' ], [ '\u2265', 'GTE' ], [ '<', 'LT' ], [ '\u2264', 'LTE' ], [ '=', 'EQ' ], [ '\u2260', 'NEQ' ] ];
        } else if (range == 'BOOL') {
          OPERATORS = Blockly.RTL ? [ [ '=', 'EQ' ], [ '\u2260', 'NEQ' ] ] : [ [ '=', 'EQ' ], [ '\u2260', 'NEQ' ] ];
        } else if (range == 'COLOUR') {
          OPERATORS = Blockly.RTL ? [ [ '=', 'EQ' ], [ '\u2260', 'NEQ' ] ] : [ [ '=', 'EQ' ], [ '\u2260', 'NEQ' ] ];
        } else {
          OPERATORS = Blockly.RTL ? [ [ '>', 'LT' ], [ '\u2265', 'LTE' ], [ '<', 'GT' ], [ '\u2264', 'GTE' ], [ '=', 'EQ' ], [ '\u2260', 'NEQ' ] ] : [
                      [ '<', 'LT' ], [ '\u2264', 'LTE' ], [ '>', 'GT' ], [ '\u2265', 'GTE' ], [ '=', 'EQ' ], [ '\u2260', 'NEQ' ] ];
        }
        this.appendDummyInput('OP_DROP').appendField(new Blockly.FieldDropdown(OPERATORS), 'OP')
        var inputB = this.appendValueInput('B');
        if (valueB) {
          inputB.connection.connect(valueB);
        }
      }
    },
    /**
     * Called whenever anything on the workspace changes.
     * Prevent mismatched types from being compared.
     * @param {!Blockly.Events.Abstract} e Change event.
     * @this Blockly.Block
     */
    onchange: function(e) {
  //    var blockA = this.getInputTargetBlock('A');
  //    var blockB = this.getInputTargetBlock('B');
  //    // Disconnect blocks that existed prior to this change if they don't match.
  //    if (blockA && blockB &&
  //        !blockA.outputConnection.checkType_(blockB.outputConnection)) {
  //      // Mismatch between two inputs.  Disconnect previous and bump it away.
  //      for (var i = 0; i < this.prevBlocks_.length; i++) {
  //        var block = this.prevBlocks_[i];
  //        if (block === blockA || block === blockB) {
  //          block.setParent(null);
  //          block.bumpNeighbours_();
  //        }
  //      }
  //    }
  //    this.prevBlocks_[0] = blockA;
  //    this.prevBlocks_[1] = blockB;
      
      // for roberta we need a different check to get changes in the visible type
      if (!this.workspace || Blockly.Block.dragMode_ == 2) {
        // Block has been deleted or is in move
        return;
      }
      var blockA = this.getInputTargetBlock('A');
      var blockB = this.getInputTargetBlock('B');
      if (blockA && blockB) {
        if (!blockA.outputConnection.check_ || !blockB.outputConnection.check_) {
          return;
        }
        Blockly.Events.setGroup(false);
        if ((blockA.outputConnection.check_[0] === blockB.outputConnection.check_[0])) {
          return;
        } 
        this.getInput('A').setCheck(blockA.outputConnection.check_);
        this.getInput('B').setCheck(blockA.outputConnection.check_);
      } else if (blockA) {
          this.getInput('B').setCheck(blockA.outputConnection.check_)
      } else if (blockB) {
        this.getInput('A').setCheck(blockB.outputConnection.check_);
      } else {
        this.getInput('A').setCheck(null);
        this.getInput('B').setCheck(null);
      }
      this.render();
    }
  };
  
  Blockly.Blocks['logic_operation'] = {
    /**
     * Block for logical operations: 'and', 'or'.
     * @this Blockly.Block
     */
    init: function() {
      var OPERATORS =
          [[Blockly.Msg.LOGIC_OPERATION_AND, 'AND'],
           [Blockly.Msg.LOGIC_OPERATION_OR, 'OR']];
      this.setHelpUrl(Blockly.Msg.LOGIC_OPERATION_HELPURL);
      this.setColour(Blockly.CAT_CONTROL_RGB);
      this.setOutput(true, 'Boolean');
      this.appendValueInput('A')
          .setCheck('Boolean');
      this.appendValueInput('B')
          .setCheck('Boolean')
          .appendField(new Blockly.FieldDropdown(OPERATORS), 'OP');
      this.setInputsInline(true);
      // Assign 'this' to a variable for use in the tooltip closure below.
      var thisBlock = this;
      this.setTooltip(function() {
        var op = thisBlock.getFieldValue('OP');
        var TOOLTIPS = {
          'AND': Blockly.Msg.LOGIC_OPERATION_TOOLTIP_AND,
          'OR': Blockly.Msg.LOGIC_OPERATION_TOOLTIP_OR
        };
        return TOOLTIPS[op];
      });
    }
  };
  
  Blockly.Blocks['logic_negate'] = {
    /**
     * Block for negation.
     * @this Blockly.Block
     */
    init: function() {
      this.jsonInit({
        "message0": Blockly.Msg.LOGIC_NEGATE_TITLE,
        "args0": [
          {
            "type": "input_value",
            "name": "BOOL",
            "check": "Boolean"
          }
        ],
        "output": "Boolean",
        "colour": Blockly.CAT_CONTROL_RGB,
        "tooltip": Blockly.Msg.LOGIC_NEGATE_TOOLTIP,
        "helpUrl": Blockly.Msg.LOGIC_NEGATE_HELPURL
      });
    }
  };
  
  Blockly.Blocks['logic_boolean'] = {
    /**
     * Block for boolean data type: true and false.
     * @this Blockly.Block
     */
    init: function() {
      this.jsonInit({
        "message0": "%1",
        "args0": [
          {
            "type": "field_dropdown",
            "name": "BOOL",
            "options": [
              [Blockly.Msg.LOGIC_BOOLEAN_TRUE, "TRUE"],
              [Blockly.Msg.LOGIC_BOOLEAN_FALSE, "FALSE"]
            ]
          }
        ],
        "output": "Boolean",
        "colour": Blockly.CAT_CONTROL_RGB,
        "tooltip": Blockly.Msg.LOGIC_BOOLEAN_TOOLTIP,
        "helpUrl": Blockly.Msg.LOGIC_BOOLEAN_HELPURL
      });
    }
  };
  
  Blockly.Blocks['logic_null'] = {
    /**
     * Block for null data type.
     * @this Blockly.Block
     */
    init: function() {
      this.jsonInit({
        "message0": Blockly.Msg.LOGIC_NULL,
        "output": null,
        "colour": Blockly.CAT_OBJECTS_RGB,
        "tooltip": Blockly.Msg.LOGIC_NULL_TOOLTIP,
        "helpUrl": Blockly.Msg.LOGIC_NULL_HELPURL
      });
    }
  };
  
  Blockly.Blocks['logic_ternary'] = {
    /**
     * Block for ternary operator.
     * @this Blockly.Block
     */
    init: function() {
      this.setHelpUrl(Blockly.Msg.LOGIC_TERNARY_HELPURL);
      this.setColour(Blockly.CAT_CONTROL_RGB);
      this.appendValueInput('IF')
          .setCheck('Boolean')
          .appendField(Blockly.Msg.LOGIC_TERNARY_CONDITION);
      this.appendValueInput('THEN')
          .appendField(Blockly.Msg.LOGIC_TERNARY_IF_TRUE);
      this.appendValueInput('ELSE')
          .appendField(Blockly.Msg.LOGIC_TERNARY_IF_FALSE);
      this.setOutput(true);
      this.setTooltip(Blockly.Msg.LOGIC_TERNARY_TOOLTIP);
      this.prevParentConnection_ = null;
    },
    /**
     * Called whenever anything on the workspace changes.
     * Prevent mismatched types.
     * @param {!Blockly.Events.Abstract} e Change event.
     * @this Blockly.Block
     */
    onchange: function(e) {
      var blockA = this.getInputTargetBlock('THEN');
      var blockB = this.getInputTargetBlock('ELSE');
      var parentConnection = this.outputConnection.targetConnection;
      // Disconnect blocks that existed prior to this change if they don't match.
      if ((blockA || blockB) && parentConnection) {
        for (var i = 0; i < 2; i++) {
          var block = (i == 1) ? blockA : blockB;
          if (block && !block.outputConnection.checkType_(parentConnection)) {
            // Ensure that any disconnections are grouped with the causing event.
            Blockly.Events.setGroup(e.group);
            if (parentConnection === this.prevParentConnection_) {
              this.unplug();
              parentConnection.getSourceBlock().bumpNeighbours_();
            } else {
              block.unplug();
              block.bumpNeighbours_();
            }
            Blockly.Events.setGroup(false);
          }
        }
      }
      this.prevParentConnection_ = parentConnection;
    }
  };
  
  Blockly.Blocks['unityControls_ifElse'] = {
    /**
     * Block for if/elseif/else condition. Roberta version.
     * @this Blockly.Block
     */
    init : function() {
      this.setColour(Blockly.CAT_CONTROL_RGB);
      this.appendValueInput('IF0').appendField(Blockly.Msg.CONTROLS_IF_MSG_IF).setCheck('Boolean');
      this.appendStatementInput('DO0').appendField(Blockly.Msg.CONTROLS_IF_MSG_THEN);
      this.appendStatementInput('ELSE').appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSE);
      this.setPreviousStatement(true);
      this.setNextStatement(true);
      this.setMutatorPlus(new Blockly.MutatorPlus(this));
      this.elseifCount_ = 0;
      this.elseCount_ = 1;
      // Assign 'this' to a variable for use in the tooltip closure below.
      var thisBlock = this;
      this.setTooltip(function() {
        if (thisBlock.elseifCount_ === 0) {
          return Blockly.Msg.CONTROLS_IF_TOOLTIP_2;
        } else {
          return Blockly.Msg.CONTROLS_IF_TOOLTIP_4;
        }
      });
    },
    mutationToDom : function() {
      if (!this.elseifCount_ && !this.elseCount_) {
        return null;
      }
      var container = document.createElement('mutation');
        if (this.elseifCount_) {
          container.setAttribute('elseIf', this.elseifCount_);
        }
        if (this.elseCount_) {
          container.setAttribute('else', 1);
        }
        return container;
    },
    /**
     * Parse XML to restore the ifElse inputs.
     * @param {!Element} xmlElement XML storage element.
     * @this Blockly.Block
     */
    domToMutation : function(xmlElement) {
      if (xmlElement.hasAttribute('elseif')) {
        this.elseifCount_ = parseInt(xmlElement.getAttribute('elseif'), 10);
      }
      this.removeInput('ELSE');
      for (var x = 1; x <= this.elseifCount_; x++) {
        this.appendValueInput('IF' + x).appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSEIF).setCheck('Boolean');
        this.appendStatementInput('DO' + x).appendField(Blockly.Msg.CONTROLS_IF_MSG_THEN);
      }
      this.appendStatementInput('ELSE').appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSE);
      if (this.elseifCount_ >= 1) {
        this.setMutatorMinus(new Blockly.MutatorMinus(this));
      }
    },
    /**
     * Update the shape according to the number of elseIf inputs.
     * @param {Number} number of elseIf inputs.
     * @this Blockly.Block
     */
    updateShape_ : function(num) {
      Blockly.dragMode_ = Blockly.DRAG_NONE;
      if (num == 1) {
        this.elseifCount_++;
        this.removeInput('ELSE');
        this.appendValueInput('IF' + this.elseifCount_).appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSEIF).setCheck('Boolean');
        this.appendStatementInput('DO' + this.elseifCount_).appendField(Blockly.Msg.CONTROLS_IF_MSG_THEN);
        this.appendStatementInput('ELSE').appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSE);
      } else if (num == 0) {
        this.elseifCount_ = 0;
      } else if (num == -1) {
        var target = this.getInputTargetBlock('IF' + this.elseifCount_);
        if (target) {
          target.unplug(false);
          target.bumpNeighbours_();
        }
        this.removeInput('ELSE');
        this.removeInput('DO' + this.elseifCount_);
        this.removeInput('IF' + this.elseifCount_);
        this.appendStatementInput('ELSE').appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSE);
        this.elseifCount_--;
      }
      if (this.elseifCount_ >= 1) {
        if (this.elseifCount_ == 1) {
          this.setMutatorMinus(new Blockly.MutatorMinus(this));
          this.render();
        }
      } else {
        this.mutatorMinus.dispose();
        this.mutatorMinus = null;
      }
    }
  };
  
  Blockly.Blocks['unityControls_if'] = {
    /**
     * Block for if/elseif condition. Roberta version.
     * @this Blockly.Block
     */
    init : function() {
      this.setColour(Blockly.CAT_CONTROL_RGB);
      this.appendValueInput('IF0').appendField(Blockly.Msg.CONTROLS_IF_MSG_IF).setCheck('Boolean');
      this.appendStatementInput('DO0').appendField(Blockly.Msg.CONTROLS_IF_MSG_THEN);
      // this.setInputsInline(true);
      this.setPreviousStatement(true);
      this.setNextStatement(true);
      this.setMutatorPlus(new Blockly.MutatorPlus(this));
      this.elseifCount_ = 0;
      // Assign 'this' to a variable for use in the tooltip closure below.
      var thisBlock = this;
      this.setTooltip(function() {
        if (thisBlock.elseifCount_ === 0) {
          return Blockly.Msg.CONTROLS_IF_TOOLTIP_1;
        } else {
          return Blockly.Msg.CONTROLS_IF_TOOLTIP_3;
        }
      });
    },
    mutationToDom : function() {
      if (!this.elseifCount_) {
        return null;
      }
      var container = document.createElement('mutation');
      if (this.elseifCount_) {
        container.setAttribute('elseIf', this.elseifCount_);
      }
      return container;
    },
    /**
     * Parse XML to restore the wait inputs.
     * @param {!Element} xmlElement XML storage element.
     * @this Blockly.Block
     */
    domToMutation : function(xmlElement) {
      this.elseifCount_ = parseInt(xmlElement.getAttribute('elseif'), 10);
      for (var x = 1; x <= this.elseifCount_; x++) {
        this.appendValueInput('IF' + x).appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSEIF).setCheck('Boolean');
        this.appendStatementInput('DO' + x).appendField(Blockly.Msg.CONTROLS_IF_MSG_THEN);
      }
      if (this.elseifCount_ >= 1) {
        this.setMutatorMinus(new Blockly.MutatorMinus(this));
      }
    },
    /**
     * Update the shape according to the number of elseIf inputs.
     * @param {Number} number of else inputs.
     * @this Blockly.Block
     */
    updateShape_ : function(num) {
      Blockly.dragMode_ = Blockly.DRAG_NONE;
      if (num == 1) {
        this.elseifCount_++;
        this.appendValueInput('IF' + this.elseifCount_).appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSEIF).setCheck('Boolean');
        this.appendStatementInput('DO' + this.elseifCount_).appendField(Blockly.Msg.CONTROLS_IF_MSG_THEN);
      } else if (num == -1) {
        var target = this.getInputTargetBlock('IF' + this.elseifCount_);
        if (target) {
          target.unplug();
          target.bumpNeighbours_();     
        }
        this.removeInput('DO' + this.elseifCount_);
        this.removeInput('IF' + this.elseifCount_);
        this.elseifCount_--;
      }
      if (this.elseifCount_ >= 1) {
        if (this.elseifCount_ == 1) {
          this.setMutatorMinus(new Blockly.MutatorMinus(this));
          this.render();
        }
      } else {
        this.mutatorMinus.dispose();
        this.mutatorMinus = null;
      }
    }
  };