/* xoreos-tools - Tools to help with xoreos development
 *
 * xoreos-tools is the legal property of its developers, whose names
 * can be found in the AUTHORS file distributed with this source
 * distribution.
 *
 * xoreos-tools is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 3
 * of the License, or (at your option) any later version.
 *
 * xoreos-tools is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with xoreos-tools. If not, see <http://www.gnu.org/licenses/>.
 */

/** @file
 *  Nitro Character Graphic Resource, a Nintendo DS image format.
 *  Uses NCLR, Nitro CoLoR, palette files.
 */

#ifndef IMAGES_NCGR_H
#define IMAGES_NCGR_H

#include <vector>

#include "src/common/scopedptr.h"

#include "src/aurora/nitrofile.h"

#include "src/images/decoder.h"

namespace Images {

/** Image decoder for Nintendo's tile-based graphics format.
 *
 *  2D graphics on the Nintendo DS is fundamentally tile-based.
 *  Specifically, the graphics data in NCGR is ordered in tiles of 8x8
 *  pixels. We unwrap them, so this is transparent to the user of the
 *  NCGR class.
 *
 *  Moreover, an NCGR file can itself be a tile of a larger image.
 *  By specifying a vector of NCGR streams and the dimensions of the
 *  grid they span (in NCGR files, not pixels), the NCGR class can
 *  automatically stitch them together into a single big image.
 *
 *  If a pointer in the NCGR stream vector is 0, the cell in the grid
 *  will stay empty, filled with entry 0 of the palette.
 *
 *  Please note that, in accordance with other image decoder classes,
 *  NCGR will never take over any of the streams. The caller has to
 *  manage stream deletion itself.
 */
class NCGR : public Decoder, public Aurora::NitroFile {
public:
	NCGR(Common::SeekableReadStream &ncgr, Common::SeekableReadStream &nclr);
	NCGR(const std::vector<Common::SeekableReadStream *> &ncgrs, uint32 width, uint32 height,
	     Common::SeekableReadStream &nclr);
	~NCGR();

private:
	struct NCGRFile {
		Common::SeekableSubReadStreamEndian *ncgr;
		Common::SeekableReadStream *image;

		/** Offset to the CHAR section within the NCGR file. */
		uint32 offsetCHAR;

		uint32 width;  ///< Width in pixels of this NCGR.
		uint32 height; ///< Height in pixels of this NCGR.
		uint8  depth;  ///< Color depth in bits.

		uint32 offsetX; ///< X offset in pixels into the final image.
		uint32 offsetY; ///< Y offset in pixels into the final image.

		NCGRFile();
		~NCGRFile();
	};

	struct ReadContext {
		uint32 width;  ///< Width of the NCGR grid, in NCGR.
		uint32 height; ///< Height of the NCGR grid, in NCGR.

		Common::ScopedArray<const byte> pal;

		std::vector<NCGRFile> ncgrs;
	};


	void load(const std::vector<Common::SeekableReadStream *> &ncgrs, uint32 width, uint32 height,
	          Common::SeekableReadStream &nclr);

	void load      (NCGRFile &ctx);
	void readHeader(NCGRFile &ctx);
	void readChar  (NCGRFile &ctx);

	void calculateGrid(ReadContext &ctx, uint32 &imageWidth, uint32 &imageHeight);
	void draw(ReadContext &ctx);
};

} // End of namespace Images

#endif // IMAGES_NCGR_H
