text: const EventEmitter = require('events');
  
  const twgl = require('twgl.js');
  
  const RenderConstants = require('./RenderConstants');
  
  class Skin extends EventEmitter {
      /**
       * Create a Skin, which stores and/or generates textures for use in rendering.
       * @param {int} id - The unique ID for this Skin.
       * @constructor
       */
      constructor (id) {
          super();
  
          /** @type {int} */
          this._id = id;
  
          /** @type {Vec3} */
          this._rotationCenter = twgl.v3.create(0, 0);
  
          /**
           * The uniforms to be used by the vertex and pixel shaders.
           * Some of these are used by other parts of the renderer as well.
           * @type {Object.<string,*>}
           * @private
           */
          this._uniforms = {
              /**
               * The nominal (not necessarily current) size of the current skin.
               * @type {Array<number>}
               */
              u_skinSize: [0, 0],
  
              /**
               * The actual WebGL texture object for the skin.
               * @type {WebGLTexture}
               */
              u_skin: null
          };
  
          this.setMaxListeners(RenderConstants.SKIN_SHARE_SOFT_LIMIT);
      }
  
      /**
       * Dispose of this object. Do not use it after calling this method.
       */
      dispose () {
          this._id = RenderConstants.ID_NONE;
      }
  
      /**
       * @return {int} the unique ID for this Skin.
       */
      get id () {
          return this._id;
      }
  
      /**
       * @returns {Vec3} the origin, in object space, about which this Skin should rotate.
       */
      get rotationCenter () {
          return this._rotationCenter;
      }
  
      /**
       * @abstract
       * @return {Array<number>} the "native" size, in texels, of this skin.
       */
      get size () {
          return [0, 0];
      }
  
      /**
       * Set the origin, in object space, about which this Skin should rotate.
       * @param {number} x - The x coordinate of the new rotation center.
       * @param {number} y - The y coordinate of the new rotation center.
       * @fires Skin.event:WasAltered
       */
      setRotationCenter (x, y) {
          const emptySkin = this.size[0] === 0 && this.size[1] === 0;
          const changed = x !== this._rotationCenter[0] || y !== this._rotationCenter[1];
          if (!emptySkin && changed) {
              this._rotationCenter[0] = x;
              this._rotationCenter[1] = y;
              this.emit(Skin.Events.WasAltered);
          }
      }
  
      /**
       * Get the center of the current bounding box
       * @return {Array<number>} the center of the current bounding box
       */
      calculateRotationCenter () {
          return [this.size[0] / 2, this.size[1] / 2];
      }
  
      /**
       * @abstract
       * @param {Array<number>} scale - The scaling factors to be used.
       * @return {WebGLTexture} The GL texture representation of this skin when drawing at the given size.
       */
      // eslint-disable-next-line no-unused-vars
      getTexture (scale) {
          return null;
      }
  
      /**
       * Update and returns the uniforms for this skin.
       * @param {Array<number>} scale - The scaling factors to be used.
       * @returns {object.<string, *>} the shader uniforms to be used when rendering with this Skin.
       */
      getUniforms (scale) {
          this._uniforms.u_skin = this.getTexture(scale);
          this._uniforms.u_skinSize = this.size;
          return this._uniforms;
      }
  }
  
  /**
   * These are the events which can be emitted by instances of this class.
   * @enum {string}
   */
  Skin.Events = {
      /**
       * Emitted when anything about the Skin has been altered, such as the appearance or rotation center.
       * @event Skin.event:WasAltered
       */
      WasAltered: 'WasAltered'
  };
  
  module.exports = Skin;
  