'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _dec, _dec2, _dec3, _desc, _value, _obj;

exports.timeIsUp = timeIsUp;

var _immutable = require('immutable');

var _constants = require('../../constants');

var _reduxStore = require('../../reduxStore');

var _reduxStore2 = _interopRequireDefault(_reduxStore);

var _interactionTypeRecordForItem = require('./interactionTypeRecordForItem');

var _interactionTypeRecordForItem2 = _interopRequireDefault(_interactionTypeRecordForItem);

var _withCachedArguments = require('./withCachedArguments');

var _withCachedArguments2 = _interopRequireDefault(_withCachedArguments);

var _withStateCache = require('./withStateCache');

var _withStateCache2 = _interopRequireDefault(_withStateCache);

var _BankEntry = require('../records/BankEntry');

var _BankEntry2 = _interopRequireDefault(_BankEntry);

var _Item = require('../records/Item');

var _Item2 = _interopRequireDefault(_Item);

var _ItemAnalysis = require('../records/ItemAnalysis');

var _ItemAnalysis2 = _interopRequireDefault(_ItemAnalysis);

var _QtiImport = require('../records/QtiImport');

var _QtiImport2 = _interopRequireDefault(_QtiImport);

var _Quiz = require('../records/Quiz');

var _Quiz2 = _interopRequireDefault(_Quiz);

var _QuizSession = require('../records/QuizSession');

var _QuizSession2 = _interopRequireDefault(_QuizSession);

var _QuizSessionEvent = require('../records/QuizSessionEvent');

var _QuizSessionEvent2 = _interopRequireDefault(_QuizSessionEvent);

var _QuizSessionResult = require('../records/QuizSessionResult');

var _QuizSessionResult2 = _interopRequireDefault(_QuizSessionResult);

var _QuizEntry = require('../records/QuizEntry');

var _QuizEntry2 = _interopRequireDefault(_QuizEntry);

var _QuizAnalysis = require('../records/QuizAnalysis');

var _QuizAnalysis2 = _interopRequireDefault(_QuizAnalysis);

var _Response = require('../records/Response');

var _Response2 = _interopRequireDefault(_Response);

var _SessionItem = require('../records/SessionItem');

var _SessionItem2 = _interopRequireDefault(_SessionItem);

var _SessionItemResult = require('../records/SessionItemResult');

var _SessionItemResult2 = _interopRequireDefault(_SessionItemResult);

var _taking = require('../selectors/taking');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
  var desc = {};
  Object['ke' + 'ys'](descriptor).forEach(function (key) {
    desc[key] = descriptor[key];
  });
  desc.enumerable = !!desc.enumerable;
  desc.configurable = !!desc.configurable;

  if ('value' in desc || desc.initializer) {
    desc.writable = true;
  }

  desc = decorators.slice().reverse().reduce(function (desc, decorator) {
    return decorator(target, property, desc) || desc;
  }, desc);

  if (context && desc.initializer !== void 0) {
    desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
    desc.initializer = undefined;
  }

  if (desc.initializer === void 0) {
    Object['define' + 'Property'](target, property, desc);
    desc = null;
  }

  return desc;
}

// ================================
//  helper to get data and records
//  from the app state
// ================================

var stateHelper = (_dec = (0, _withStateCache2.default)(function () {
  return [['interactionTypes']];
}), _dec2 = (0, _withStateCache2.default)(function () {
  return [['quizEntries'], ['modifications', 'quizEntries'], ['modifications', 'items'], ['modifications', 'stimuli'], ['editing']];
}), _dec3 = (0, _withStateCache2.default)(function () {
  return [['editing']];
}), (_obj = {
  state: function state() {
    return _reduxStore2.default.getAppState();
  },


  // ==========================
  //     NON-RECORD HELPERS
  // ==========================

  activeQuizId: function activeQuizId() {
    return this.state().getIn(['quizzes', 'activeQuizId']) || this.activeQuizSession().get('quiz');
  },
  activeQuizSessionId: function activeQuizSessionId() {
    return this.state().getIn(['quizSessions', 'activeQuizSessionId']);
  },
  getFiles: function getFiles() {
    return this.state().getIn(['upload', 'files'], (0, _immutable.List)());
  },
  getSessionId: function getSessionId() {
    return this.state().getIn(['taking', 'browserSessionId']);
  },
  getTimerData: function getTimerData() {
    var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.state();

    return state.getIn(['taking', 'timerData'], (0, _immutable.Map)());
  },
  getIsTaking: function getIsTaking() {
    return this.state().getIn(['taking', 'isTaking'], (0, _immutable.Map)());
  },
  getTakingResponseByPosition: function getTakingResponseByPosition(position) {
    return this.state().getIn(['taking', 'responses'], (0, _immutable.List)()).find(function (resp) {
      return resp.get('position') === position;
    }) || (0, _immutable.Map)();
  },
  getCurrentSessionItemPosition: function getCurrentSessionItemPosition() {
    return (0, _taking.getCurrentSessionItemPosition)(this.state());
  },
  getSessionItemsCount: function getSessionItemsCount() {
    return this.activeQuizSession().get('sessionItemsCount');
  },
  backtrackingIsAllowed: function backtrackingIsAllowed() {
    return this.activeQuizSession().get('allowBacktracking');
  },
  isOneQuestionAtATime: function isOneQuestionAtATime() {
    return this.activeQuizSession().isOneQuestionAtATime();
  },
  isActiveQuizWorkingInstanceOneQuestionAtATime: function isActiveQuizWorkingInstanceOneQuestionAtATime() {
    return this.activeQuiz().getWorkingInstance().isOneQuestionAtATime();
  },
  calculatorType: function calculatorType() {
    return this.activeQuiz().calculatorType;
  },
  callbacksDoneFor: function callbacksDoneFor(callType) {
    return this.state().getIn(['calls', callType, 'callbackStatus']) === 'complete';
  },


  // ========================
  //    FIND & INSTANTIATE
  // ========================

  // SINGLE RECORDS

  activeQuiz: function activeQuiz() {
    return this.findQuiz(this.activeQuizId());
  },
  activeQuizSession: function activeQuizSession() {
    return this.findQuizSession(this.activeQuizSessionId());
  },
  findAndInstantiate: function findAndInstantiate(RecordClass, keys) {
    var data = this.state().getIn(keys);
    return RecordClass.create(data);
  },
  findBankEntry: function findBankEntry(id) {
    return this.findAndInstantiate(_BankEntry2.default, ['bankEntries', id]);
  },
  findQuiz: function findQuiz(id) {
    return this.findAndInstantiate(_Quiz2.default, ['quizzes', id]);
  },
  findQuizSession: function findQuizSession(id) {
    return this.findAndInstantiate(_QuizSession2.default, ['quizSessions', id]);
  },
  findSessionItem: function findSessionItem(sessionItemKey) {
    return this.findAndInstantiate(_SessionItem2.default, ['sessionItems', sessionItemKey]);
  },
  findQuizSessionResult: function findQuizSessionResult(id) {
    return this.findAndInstantiate(_QuizSessionResult2.default, ['quizSessionResults', id]);
  },
  findSessionItemResult: function findSessionItemResult(id) {
    return this.findAndInstantiate(_SessionItemResult2.default, ['sessionItemResults', '' + id]);
  },
  findTakingResponse: function findTakingResponse(responseKey) {
    return this.findAndInstantiate(_Response2.default, ['taking', 'responses', responseKey]);
  },
  findImport: function findImport(id) {
    return this.findAndInstantiate(_QtiImport2.default, ['qtiImports', id]);
  },
  findQuizSessionEvent: function findQuizSessionEvent(createdAt) {
    return this.findAndInstantiate(_QuizSessionEvent2.default, ['quizSessionEvents', createdAt]);
  },
  findItem: function findItem(id) {
    if (id === _constants.TEMPORARY_ITEM_ID) {
      return this.findTemporaryItem();
    }

    return this.findAndInstantiate(_Item2.default, ['items', id]);
  },
  findQuizEntry: function findQuizEntry(id) {
    if (id === _constants.TEMPORARY_QUIZ_ENTRY_ID) {
      return this.findTemporaryQuizEntry();
    }

    return this.findAndInstantiate(_QuizEntry2.default, ['quizEntries', id]);
  },
  findItemAnalysis: function findItemAnalysis(itemKey) {
    var state = _reduxStore2.default.getAppState();
    var itemAnalysisData = state.getIn(['reporting', 'item_analysis', itemKey]);
    return new _ItemAnalysis2.default(itemAnalysisData);
  },
  findQuizAnalysis: function findQuizAnalysis(quizKey) {
    var state = _reduxStore2.default.getAppState();
    var quizAnalysisData = state.getIn(['reporting', 'quiz_analysis', quizKey]);
    return new _QuizAnalysis2.default(quizAnalysisData);
  },
  findTemporaryItem: function findTemporaryItem() {
    var temporaryItemData = this.state().getIn(['modifications', 'items', _constants.TEMPORARY_ITEM_ID], (0, _immutable.Map)());
    return _Item2.default.create(temporaryItemData);
  },
  findTemporaryQuizEntry: function findTemporaryQuizEntry() {
    var temporaryQuizEntryData = this.state().getIn(['modifications', 'quizEntries', _constants.TEMPORARY_QUIZ_ENTRY_ID], (0, _immutable.Map)({ entry: _constants.TEMPORARY_ITEM_ID }));
    return _QuizEntry2.default.create(temporaryQuizEntryData);
  },
  findInteractionType: function findInteractionType(id) {
    var interactionTypeData = this.state().getIn(['interactionTypes', id]) || (0, _immutable.Map)();
    var slug = interactionTypeData.get('slug');
    var IntTypeRecord = (0, _interactionTypeRecordForItem2.default)(slug);
    return new IntTypeRecord(interactionTypeData);
  },


  // MULTIPLE RECORDS

  findQuizSessions: function findQuizSessions() {
    var _this = this;

    var ids = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];

    return ids.reduce(function (list, id) {
      var quizSession = _this.findQuizSession(id);
      return quizSession ? list.push(quizSession) : list;
    }, (0, _immutable.List)());
  },
  interactionTypes: function interactionTypes() {
    var _this2 = this;

    return this.state().get('interactionTypes', (0, _immutable.Map)()).map(function (intTypeData) {
      return _this2.findInteractionType(intTypeData.get('id'));
    }).valueSeq().toList();
  },


  // MISC.

  __isShowingErrors: function __isShowingErrors(quizEntry) {
    var isInvalid = !quizEntry.getEntry().getWorkingInstance().isValid();
    var isEditing = this.state().getIn(['editing', quizEntry.id + '_' + _constants.QUIZ_ENTRY_GUID_SUFFIX]);
    return isInvalid && isEditing;
  },
  quizEntryWithErrorsShowing: function quizEntryWithErrorsShowing() {
    var _this3 = this;

    var qeWithErrors = this.state().get('quizEntries').find(function (qe) {
      return _this3.__isShowingErrors(_QuizEntry2.default.create(qe));
    });

    if (qeWithErrors) {
      return qeWithErrors;
    }

    var temp = this.findTemporaryQuizEntry();
    if (this.__isShowingErrors(temp)) {
      return temp;
    }
  },
  editingQuizEntry: function editingQuizEntry() {
    return this.state().get('editing', []).find(function (isEditing, key) {
      return isEditing && key.includes(_constants.QUIZ_ENTRY_GUID_SUFFIX);
    });
  },
  gradingSessionItems: function gradingSessionItems(sessionItems, scope) {
    return sessionItems.filter(scope).map(function (si) {
      return _SessionItem2.default.create(si);
    }).sortBy(function (si) {
      return si.position;
    }).toList();
  },
  gradingSessionItemResults: function gradingSessionItemResults(sessionItemResults, scope) {
    return sessionItemResults.toList().filter(scope);
  }
}, (_applyDecoratedDescriptor(_obj, 'interactionTypes', [_dec], Object.getOwnPropertyDescriptor(_obj, 'interactionTypes'), _obj), _applyDecoratedDescriptor(_obj, 'quizEntryWithErrorsShowing', [_dec2], Object.getOwnPropertyDescriptor(_obj, 'quizEntryWithErrorsShowing'), _obj), _applyDecoratedDescriptor(_obj, 'editingQuizEntry', [_dec3], Object.getOwnPropertyDescriptor(_obj, 'editingQuizEntry'), _obj), _applyDecoratedDescriptor(_obj, 'gradingSessionItems', [_withCachedArguments2.default], Object.getOwnPropertyDescriptor(_obj, 'gradingSessionItems'), _obj), _applyDecoratedDescriptor(_obj, 'gradingSessionItemResults', [_withCachedArguments2.default], Object.getOwnPropertyDescriptor(_obj, 'gradingSessionItemResults'), _obj)), _obj));

function timeIsUp() {
  var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : stateHelper.state();

  var timerRunning = state.getIn(['taking', 'timerData', 'timerRunning']);
  var noTimeLeft = state.getIn(['taking', 'timerData', 'timeLeftInSeconds']) <= 0;
  return noTimeLeft && timerRunning;
}

exports.default = stateHelper;