/* globals state, createObj, findObjs, getObj, getAttrByName, sendChat, on, log, Campaign, playerIsGM, spawnFx,
 spawnFxBetweenPoints, filterObjs */
'use strict';
const _ = require('underscore');

// noinspection JSUnusedGlobalSymbols
module.exports = class Roll20Wrapper {

  getState(module) {
    if (!state[module]) {
      state[module] = {};
    }
    return state[module];
  }

  createObj(type, attributes) {
    return createObj(type, attributes);
  }

  findObjs(attributes) {
    return findObjs(attributes);
  }

  filterObjs(attributes) {
    return filterObjs(attributes);
  }

  getObj(type, id) {
    return getObj(type, id);
  }

  getOrCreateObj(type, attributes) {
    const newAttributes = _.extend(_.clone(attributes), { type });
    const existing = this.findObjs(newAttributes);
    switch (existing.length) {
      case 0:
        return this.createObj(type, newAttributes);
      case 1:
        return existing[0];
      default:
        throw new Error(`Asked for a single ${type} but more than 1 was found matching attributes: ` +
          `${JSON.stringify(attributes)}`);
    }
  }

  getAttrByName(character, attrName) {
    return getAttrByName(character, attrName);
  }

  getAttrObjectByName(character, attrName) {
    const attr = this.findObjs({ type: 'attribute', characterid: character, name: attrName });
    return attr && attr.length > 0 ? attr[0] : null;
  }

  getOrCreateAttr(characterId, attrName) {
    return this.getOrCreateObj('attribute', { characterid: characterId, name: attrName });
  }

  setAttrByName(characterId, attrName, value) {
    this.getOrCreateAttr(characterId, attrName).set('current', value);
  }

  processAttrValue(characterId, attrName, cb) {
    const attribute = this.getOrCreateAttr(characterId, attrName);
    attribute.set('current', cb(attribute.get('current')));
  }

  getRepeatingSectionAttrs(characterId, sectionName) {
    const prefix = `repeating_${sectionName}`;
    return _.filter(this.findObjs({ type: 'attribute', characterid: characterId }),
      attr => attr.get('name').indexOf(prefix) === 0);
  }

  getRepeatingSectionItemIdsByName(characterId, sectionName) {
    const re = new RegExp(`repeating_${sectionName}_([^_]+)_name$`);
    return _.reduce(this.getRepeatingSectionAttrs(characterId, sectionName),
      (lookup, attr) => {
        const match = attr.get('name').match(re);
        if (match) {
          lookup[attr.get('current').toLowerCase()] = match[1];
        }
        return lookup;
      }, {});
  }

  getCurrentPage(playerId) {
    let pageId;
    if (this.playerIsGM(playerId)) {
      pageId = this.getObj('player', playerId).get('lastpage');
    }
    else {
      pageId = this.getCampaign().get('playerspecificpages')[playerId] || this.getCampaign().get('playerpageid');
    }

    return pageId ? this.getObj('page', pageId) : null;
  }

  spawnFx(pointsArray, fxType, pageId) {
    switch (pointsArray.length) {
      case 1:
        spawnFx(pointsArray[0].x, pointsArray[0].y, fxType, pageId);
        break;
      case 2:
        spawnFxBetweenPoints(pointsArray[0], pointsArray[1], fxType, pageId);
        break;
      default:
        throw new Error('Wrong number of points supplied to spawnFx: $$$', pointsArray);
    }
  }

  playerIsGM(playerId) {
    return playerIsGM(playerId);
  }

  getCampaign() {
    return Campaign(); // eslint-disable-line
  }

  sendChat(sendAs, message, callback, options) {
    return sendChat(sendAs, message, callback, options);
  }

  on(event, callback) {
    return on(event, callback);
  }

  log(msg) {
    return log(msg);
  }
};


@@ -1134,32 +1134,43 @@
 racter, attrName
+, valueType
 ) %7B%0A    return g
@@ -1197,24 +1197,35 @@
 er, attrName
+, valueType
 );%0A  %7D%0A%0A  ge

Add valueType to getAttrByName