text: "use strict";
  // 
  // Copyright (c) Microsoft. All rights reserved.
  // Licensed under the MIT license.
  // 
  // Microsoft Bot Framework: http://botframework.com
  // 
  // Bot Builder SDK Github:
  // https://github.com/Microsoft/BotBuilder
  // 
  // Copyright (c) Microsoft Corporation
  // All rights reserved.
  // 
  // MIT License:
  // Permission is hereby granted, free of charge, to any person obtaining
  // a copy of this software and associated documentation files (the
  // "Software"), to deal in the Software without restriction, including
  // without limitation the rights to use, copy, modify, merge, publish,
  // distribute, sublicense, and/or sell copies of the Software, and to
  // permit persons to whom the Software is furnished to do so, subject to
  // the following conditions:
  // 
  // The above copyright notice and this permission notice shall be
  // included in all copies or substantial portions of the Software.
  // 
  // THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND,
  // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  //
  Object.defineProperty(exports, "__esModule", { value: true });
  var tslib_1 = require("tslib");
  var Dialog_1 = require("./Dialog");
  var consts = require("../consts");
  var WaterfallDialog = /** @class */ (function (_super) {
      tslib_1.__extends(WaterfallDialog, _super);
      function WaterfallDialog(steps) {
          var _this = _super.call(this) || this;
          _this._onBeforeStep = [];
          if (steps) {
              _this.steps = Array.isArray(steps) ? steps : [steps];
          }
          else {
              _this.steps = [];
          }
          return _this;
      }
      WaterfallDialog.prototype.begin = function (session, args) {
          this.doStep(session, 0, args);
      };
      WaterfallDialog.prototype.replyReceived = function (session, recognizeResult) {
          this.doStep(session, 0, recognizeResult.args);
      };
      WaterfallDialog.prototype.dialogResumed = function (session, result) {
          var step = session.dialogData[consts.Data.WaterfallStep];
          switch (result.resumed) {
              case Dialog_1.ResumeReason.reprompt:
                  // Ignore re-prompts
                  return;
              case Dialog_1.ResumeReason.back:
                  step--;
                  break;
              default:
                  step++;
                  break;
          }
          this.doStep(session, step, result);
      };
      WaterfallDialog.prototype.onBeforeStep = function (handler) {
          this._onBeforeStep.unshift(handler);
          return this;
      };
      /** Executes a waterfall step. */
      WaterfallDialog.prototype.doStep = function (session, step, args) {
          var _this = this;
          var skip = function (result) {
              result = result || {};
              if (result.resumed == null) {
                  result.resumed = Dialog_1.ResumeReason.forward;
              }
              _this.dialogResumed(session, result);
          };
          // Call any onBeforeStep() handlers                
          this.beforeStep(session, step, args, function (s, a) {
              if (s >= 0) {
                  if (s < _this.steps.length) {
                      // Execute next step of the waterfall
                      try {
                          session.logger.log(session.dialogStack(), 'waterfall() step ' + (s + 1) + ' of ' + _this.steps.length);
                          session.dialogData[consts.Data.WaterfallStep] = s;
                          _this.steps[s](session, a, skip);
                      }
                      catch (e) {
                          session.error(e);
                      }
                  }
                  else if (a && a.hasOwnProperty('resumed')) {
                      // End the current dialog and return results to parent
                      session.endDialogWithResult(a);
                  }
                  else {
                      // Empty waterfall so end dialog with not completed
                      session.logger.warn(session.dialogStack(), 'waterfall() empty waterfall detected');
                      session.endDialogWithResult({ resumed: Dialog_1.ResumeReason.notCompleted });
                  }
              }
          });
      };
      /** Calls any custom step handlers. */
      WaterfallDialog.prototype.beforeStep = function (session, step, args, final) {
          var index = 0;
          var handlers = this._onBeforeStep;
          function next(s, a) {
              try {
                  if (index < handlers.length) {
                      handlers[index++](session, s, a, next);
                  }
                  else {
                      final(s, a);
                  }
              }
              catch (e) {
                  session.error(e);
              }
          }
          next(step, args);
      };
      WaterfallDialog.createHandler = function (steps) {
          return function waterfallHandler(s, r) {
              var skip = function (result) {
                  result = result || {};
                  if (result.resumed == null) {
                      result.resumed = Dialog_1.ResumeReason.forward;
                  }
                  waterfallHandler(s, result);
              };
              // Check for continuation of waterfall
              if (r && r.hasOwnProperty('resumed')) {
                  // Ignore re-prompts
                  if (r.resumed !== Dialog_1.ResumeReason.reprompt) {
                      // Adjust step based on users utterance
                      var step = s.dialogData[consts.Data.WaterfallStep];
                      switch (r.resumed) {
                          case Dialog_1.ResumeReason.back:
                              step -= 1;
                              break;
                          default:
                              step++;
                      }
                      // Handle result
                      if (step >= 0 && step < steps.length) {
                          // Execute next step of the waterfall
                          try {
                              s.logger.log(s.dialogStack(), 'waterfall() step ' + step + 1 + ' of ' + steps.length);
                              s.dialogData[consts.Data.WaterfallStep] = step;
                              steps[step](s, r, skip);
                          }
                          catch (e) {
                              s.error(e);
                          }
                      }
                      else {
                          // End the current dialog and return results to parent
                          s.endDialogWithResult(r);
                      }
                  }
              }
              else if (steps && steps.length > 0) {
                  // Start waterfall
                  try {
                      s.logger.log(s.dialogStack(), 'waterfall() step 1 of ' + steps.length);
                      s.dialogData[consts.Data.WaterfallStep] = 0;
                      steps[0](s, r, skip);
                  }
                  catch (e) {
                      s.error(e);
                  }
              }
              else {
                  // Empty waterfall so end dialog with not completed
                  s.logger.warn(s.dialogStack(), 'waterfall() empty waterfall detected');
                  s.endDialogWithResult({ resumed: Dialog_1.ResumeReason.notCompleted });
              }
          };
      };
      return WaterfallDialog;
  }(Dialog_1.Dialog));
  exports.WaterfallDialog = WaterfallDialog;
  //# sourceMappingURL=WaterfallDialog.js.map