//------------------------------------------------------------------------------
// Lamp : Open source game middleware
// Copyright (C) 2004  Junpei Ohtani ( Email : junpee@users.sourceforge.jp )
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//------------------------------------------------------------------------------

/** @file
 * Targaセーバ実装
 * @author Junpee
 */

#include "LampBasic.h"
#include "Core/Codec/Tga/TargaSaver.h"
#include "Core/InputOutput/BinaryFileWriter.h"

namespace Lamp{

// フッタ
const char TargaSaver::footer_[] = "TRUEVISION-XFILE.";

//------------------------------------------------------------------------------
// コンストラクタ
TargaSaver::TargaSaver(){
}
//------------------------------------------------------------------------------
// デストラクタ
TargaSaver::~TargaSaver(){
}
//------------------------------------------------------------------------------
// セーブ
void TargaSaver::save(
	BinaryWriter* writer, const DimensionI& size, const Color3c* colors){
	writer_ = writer;
	size_ = size;
	// アルファ無しヘッダの書き出し
	writeHeader(false);
	// イメージの書き出し
	int bufferSize = size_.width * size_.height * sizeof(Color3c);
	u_char* buffer = new u_char[bufferSize];
	u_char* writeAddress = buffer;
	for(int i = size_.height - 1; i >= 0; i--){
		int offset = i * size_.width;
		for(int j = 0; j < size_.width; j++){
			const Color3c& color = colors[offset + j];
			*writeAddress = color.b;
			writeAddress++;
			*writeAddress = color.g;
			writeAddress++;
			*writeAddress = color.r;
			writeAddress++;
		}
	}
	writer_->writeBytes(buffer, bufferSize);
	delete[] buffer;
	// フッタ書き出し
	writeFooter();
}
//------------------------------------------------------------------------------
// セーブ
void TargaSaver::save(
	BinaryWriter* writer, const DimensionI& size, const Color4c* colors){
	writer_ = writer;
	size_ = size;
	// アルファ有りヘッダの書き出し
	writeHeader(true);
	// イメージの書き出し
	int bufferSize = size_.width * size_.height * sizeof(Color4c);
	u_char* buffer = new u_char[bufferSize];
	u_char* writeAddress = buffer;
	for(int i = size_.height - 1; i >= 0; i--){
		int offset = i * size_.width;
		for(int j = 0; j < size_.width; j++){
			const Color4c& color = colors[offset + j];
			*writeAddress = color.b;
			writeAddress++;
			*writeAddress = color.g;
			writeAddress++;
			*writeAddress = color.r;
			writeAddress++;
			*writeAddress = color.a;
			writeAddress++;
		}
	}
	writer_->writeBytes(buffer, bufferSize);
	delete[] buffer;
	// フッタ書き出し
	writeFooter();
}
//------------------------------------------------------------------------------
// セーブ
void TargaSaver::save(
	BinaryWriter* writer, int width, int height, const Color3c* colors){
	save(writer, DimensionI(width, height), colors);
}
//------------------------------------------------------------------------------
// セーブ
void TargaSaver::save(
	BinaryWriter* writer, int width, int height, const Color4c* colors){
	save(writer, DimensionI(width, height), colors);
}
//------------------------------------------------------------------------------
// セーブ
void TargaSaver::save(
	const String& filePath, const DimensionI& size, const Color3c* colors){
	BinaryFileWriter* binaryFileWriter = new BinaryFileWriter(filePath);
	save(binaryFileWriter, size, colors);
	delete binaryFileWriter;
}
//------------------------------------------------------------------------------
// セーブ
void TargaSaver::save(
	const String& filePath, const DimensionI& size, const Color4c* colors){
	BinaryFileWriter* binaryFileWriter = new BinaryFileWriter(filePath);
	save(binaryFileWriter, size, colors);
	delete binaryFileWriter;
}
//------------------------------------------------------------------------------
// セーブ
void TargaSaver::save(
	const String& filePath, int width, int height, const Color3c* colors){
	BinaryFileWriter* binaryFileWriter = new BinaryFileWriter(filePath);
	save(binaryFileWriter, DimensionI(width, height), colors);
	delete binaryFileWriter;
}
//------------------------------------------------------------------------------
// セーブ
void TargaSaver::save(
	const String& filePath, int width, int height, const Color4c* colors){
	BinaryFileWriter* binaryFileWriter = new BinaryFileWriter(filePath);
	save(binaryFileWriter, DimensionI(width, height), colors);
	delete binaryFileWriter;
}
//------------------------------------------------------------------------------
// ヘッダの書き出し
void TargaSaver::writeHeader(bool hasAlpha){
	// イメージID無し
	writer_->writeUChar(0);
	// カラーマップ非対応
	writer_->writeUChar(0);
	// イメージタイプはカラーマップ無し非圧縮RGB
	writer_->writeUChar(2);
	// カラーマップ詳細情報無し
	writer_->writeShort(0);
	writer_->writeShort(0);
	writer_->writeUChar(0);
	// X開始点
	writer_->writeShort(0);
	// Y開始点
	writer_->writeShort(0);
	// 幅
	writer_->writeShort(size_.width);
	// 高さ
	writer_->writeShort(size_.height);
	if(hasAlpha){
		// ピクセルサイズ
		writer_->writeUChar(32);
		// アルファ深度
		writer_->writeUChar(8);
	}else{
		// ピクセルサイズ
		writer_->writeUChar(24);
		// アルファ深度
		writer_->writeUChar(0);
	}
}
//------------------------------------------------------------------------------
// フッタの書き出し
void TargaSaver::writeFooter(){
	writer_->writeUInt(0);
	writer_->writeUInt(0);
	writer_->writeBytes(footer_, 18);
}
//------------------------------------------------------------------------------
} // End of namespace Lamp
//------------------------------------------------------------------------------
