use :node;

var Node = module.require('../Node').Node;

fn FallthroughStatement()

extends Node {

this.type = 'FallthroughStatement';

}

FallthroughStatement.prototype.codegen = () -> {

if !super.codegen() {
  return;
}

var parent = this.parent;
var iterations = 0;

while parent? and !parent.switchCase {
  parent = parent.parent;
  iterations++;
}

if parent? {
  parent.fallthrough = true;
} else {
  Node.getErrorManager().error({
    type: "InvalidFallthroughContext",
    message: "fallthrough statement is only allowed in a switch case clause.",
    loc: this.loc
  });
}

var switchStatement = parent.parent;

if !switchStatement.fallthroughId {
  switchStatement.fallthroughId = {
    "type": "Identifier",
    "name": FallthroughStatement.getNextVariableName()
  };
}

switchStatement.branchFallthrough = true;

parent.body.body = [{
  "type": "ExpressionStatement",
  "codeGenerated": true,
  "expression": {
    "type": "AssignmentExpression",
    "operator": "=",
    "left": switchStatement.fallthroughId,
    "right": {
      "type": "Literal",
      "value": 2
    }
  }
}].concat(parent.body.body);

this.type = "ExpressionStatement";
this.expression = {
  "type": "AssignmentExpression",
  "operator": "=",
  "left": switchStatement.fallthroughId,
  "right": {
    "type": "Literal",
    "value": 1
  }
};

return this;

};

FallthroughStatement.getNextVariableName = () -> {

if (!this.fallthroughIndex?) { 
  this.fallthroughIndex = 0; 
}

return "fallthrough" + this.fallthroughIndex++;

};

FallthroughStatement.resetVariableNames = () -> {

this.fallthroughIndex = 0;

};

exports.FallthroughStatement = FallthroughStatement;