text: /**
   * @module Image
   */
  
  import Book from './book';
  
  /**
   * Image object from API.
   * @global
   * @typedef {object} APIImage
   * @property {string}        t Image type.
   * @property {number|string} w Image width.
   * @property {number|string} h Image height.
   */
  
  /**
   * @typedef {object} ImageTypes
   * @property {TagType} JPEG JPEG image type.
   * @property {TagType} PNG  PNG image type.
   */
  
  /**
   * Class representing image type.
   * @class
   */
  class ImageType {
  	/**
  	 * @type {ImageTypes}
  	 * @static
  	 */
  	static knownTypes = {};
  
  	/**
  	 * Image type name.
  	 * @type {?string}
  	 */
  	type = null;
  
  	/**
  	 * Image type extension.
  	 * @type {?string}
  	 */
  	extension = null;
  
  	/**
  	 * Create image type.
  	 * @param {string} type      Image type name.
  	 * @param {string} extension Image type extension.
  	 */
  	constructor(type, extension) {
  		if (type) {
  			this.type = type;
  			this.constructor.knownTypes[type] = this;
  		}
  		this.extension = extension;
  	}
  
  	/**
  	 * Whatever this tag type is unknown.
  	 * @type {boolean}
  	 */
  	get isKnown() {
  		return !(this instanceof UnknownImageType);
  	}
  }
  
  /**
   * Class representing unknown image type.
   * @class
   * @extends ImageType
   */
  class UnknownImageType extends ImageType {
  	/**
  	 * Create unknown image type.
  	 * @param {string} type      Unknown image type name.
  	 * @param {string} extension Unknown image type extension.
  	 */
  	constructor(type, extension) {
  		super(null, extension);
  		this.type = type;
  	}
  }
  
  /**
   * Class representing image.
   * @class
   */
  class Image {
  	/**
  	 * Image types.
  	 * @type {ImageTypes}
  	 * @static
  	 */
  	static types = {
  		JPEG: new ImageType('jpeg', 'jpg'),
  		PNG : new ImageType('png', 'png'),
  
  		/**
  		 * Known image types.
  		 * @type {ImageType}
  		 */
  		known: ImageType.knownTypes,
  
  		/**
  		 * Get image type class instance by name.
  		 * @param {string} type Image type.
  		 * @returns {ImageType|UnknownImageType} Image type class instance.
  		 */
  		get(type) {
  			let known;
  			if ('string' === typeof type) {
  				type = type.toLowerCase();
  				switch (type) {
  					case 'j':
  					case 'jpg':
  					case 'jpeg':
  						type = 'jpeg';
  						break;
  					case 'p':
  					case 'png':
  						type = 'png';
  						break;
  				}
  			}
  			return ((known = this.known[type])) ? known : new UnknownImageType(type);
  		},
  	};
  
  	/**
  	 * Parse pure image object from API into class instance.
  	 * @param {APIImage} image  Image object
  	 * @param {number}   [id=0] Image id (a.k.a. page number).
  	 * @returns {Image} Image instance.
  	 * @static
  	 */
  	static parse(image, id = 0) {
  		let {
  			t: type,
  			w: width,
  			h: height,
  		} = image;
  
  		return new this({
  			type,
  			width : +width,
  			height: +height,
  			id,
  		});
  	}
  
  	/**
  	 * Image ID.
  	 * @type {number}
  	 */
  	id = 0;
  
  	/**
  	 * Image width.
  	 * @type {number}
  	 */
  	width = 0;
  
  	/**
  	 * Image height.
  	 * @type {number}
  	 */
  	height = 0;
  
  	/**
  	 * Image type.
  	 * @type {ImageType}
  	 */
  	type = this.constructor.types.JPEG;
  
  	/**
  	 * Image parent book.
  	 * @type {Book}
  	 */
  	book = Book.Unknown;
  
  	/**
  	 * Create image.
  	 * @param {object}           [params]                      Image parameters.
  	 * @param {number}           [params.id=0]                 Image ID.
  	 * @param {number}           [params.width=0]              Image width.
  	 * @param {number}           [params.height=0]             Image height.
  	 * @param {string|ImageType} [params.type=ImageTypes.JPEG] Image type.
  	 * @param {Book}             [params.book=Book.Unknown]    Image's Book.
  	 */
  	constructor({
  		id     = 0,
  		width  = 0,
  		height = 0,
  		type   = this.constructor.types.JPEG,
  		book   = Book.Unknown,
  	} = {}) {
  		Object.assign(this, {
  			id: 'number' === typeof id
  				? id < 1 ? 0 : id
  				: 0,
  			width,
  			height,
  			type: type instanceof ImageType
  				? type
  				: this.constructor.types.get(type),
  			book: book instanceof Book
  				? book
  				: Book.Unknown,
  		});
  	}
  
  	/**
  	 * Whatever this image is book cover.
  	 * @type {boolean}
  	 */
  	get isCover() {
  		return this.id < 1;
  	}
  
  	/**
  	 * Image filename.
  	 * @type {string}
  	 */
  	get filename() {
  		return `${this.isCover ? 'cover' : this.id}.${this.type.extension}`;
  	}
  }
  
  export default Image;
  