//------------------------------------------------------------------------------
// 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
 * Xテクスチャトランスレータ実装
 * @author Junpee
 */

#include "LampBasic.h"
#include "XTranslator/XTextureTranslator.h"
#include <Core/InputOutput/FilePath.h>
#include <Graphics/System/LampGraphics.h>
#include <Graphics/Scene/Scene.h>
#include <Graphics/Texture/TextureManager.h>
#include <Graphics/Picture/PictureManager.h>

/// テクスチャサフィックス
const String XTextureTranslator::textureSuffix = "Texture";
/// ピクチャサフィックス
const String XTextureTranslator::pictureSuffix = "Picture";

//------------------------------------------------------------------------------
// コンストラクタ
XTextureTranslator::XTextureTranslator() : d3dTexture_(NULL), texture_(NULL){
}
//------------------------------------------------------------------------------
// デストラクタ
XTextureTranslator::~XTextureTranslator(){
	SafeRelease(d3dTexture_);
}
//------------------------------------------------------------------------------
// 変換
bool XTextureTranslator::translate(const FilePath& xFilePath,
	Scene* scene, const String& name, const String& texturePath){
	// テクスチャファイルの存在を確認する
	if(texturePath.isEmpty()){ return true; }
	FilePath textureFilePath(texturePath);
	if(!textureFilePath.existFile()){
		// 絶対パスで見つからなかった場合、Xファイルからの相対パスに変換
		textureFilePath.setPath(
			xFilePath.getFolderPath() + textureFilePath.getFileName());
		if(!textureFilePath.existFile()){
			ErrorOut("XTextureTranslator::translate() "
				"テクスチャファイルが見つかりません " + texturePath);
			return false;
		}
	}

	// D3Dテクスチャのロード
	u_int mipLevels = 1;
	u_int usage = 0;
	DirectXCheck(D3DXCreateTextureFromFileEx(LampGraphics::getDirect3DDevice(),
		textureFilePath.getPath().getBytes(), D3DX_DEFAULT, D3DX_DEFAULT,
		mipLevels, usage, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, D3DX_DEFAULT,
		D3DX_DEFAULT, 0, NULL, NULL, &d3dTexture_));
	Assert(d3dTexture_ != NULL);
	Assert(d3dTexture_->GetType() == D3DRTYPE_TEXTURE);

	// サーフェース記述の取得
	D3DSurfaceDescription surfaceDescription;
	DirectXCheck(d3dTexture_->GetLevelDesc(0, &surfaceDescription));
	Assert(surfaceDescription.Format == D3DFMT_A8R8G8B8);
	Assert(surfaceDescription.Type == D3DRTYPE_SURFACE);
	Assert(surfaceDescription.Usage == 0);
	Assert(surfaceDescription.Pool == D3DPOOL_SYSTEMMEM);
	u_int width = surfaceDescription.Width;
	u_int height = surfaceDescription.Height;
	u_int pixelCount = width * height;
	Assert((width != 0) && (height != 0));

	// サーフェースデータの取得
	u_int* imageData = new u_int[pixelCount];
	D3DLOCKED_RECT lockRect;
	DirectXCheck(d3dTexture_->LockRect(0, &lockRect, NULL, D3DLOCK_READONLY));
	Assert((width * 4) == lockRect.Pitch);
	::memcpy(imageData, lockRect.pBits, pixelCount * sizeof(u_int));
	DirectXCheck(d3dTexture_->UnlockRect(0));

	// アルファを持っているかチェック
	bool hasAlpha = false;
	for(u_int i = 0; i < pixelCount; i++){
		// 0xff以外のアルファがあればアルファ付テクスチャ
		if((imageData[i] & 0xff000000) != 0xff000000){
			hasAlpha = true;
			break;
		}
	}

	// テクスチャの作成
	TextureManager* textureManager = scene->getTextureManager();
	String textureName = textureManager->rename(name + textureSuffix);
	SurfaceTexture* texture = textureManager->createSurfaceTexture(textureName);
	texture_ = texture;

	// ピクチャの作成
	PictureManager* pictureManager = scene->getPictureManager();
	String pictureName = pictureManager->rename(name + pictureSuffix);
	String picturePath = textureFilePath.getFolderPath() +
		textureFilePath.getName() + ".tga";
	if(hasAlpha){
		PictureRGB8* picture = pictureManager->createPictureRGB8(pictureName);
		picture->setPath(picturePath);
		picture->setSize(DimensionI(width, height));
		Color3c* image = new Color3c[pixelCount];
		for(u_int i = 0; i < pixelCount; i++){
			image[i].setARGB(imageData[i]);
		}
		picture->setImage(image);
		SafeArrayDelete(image);
		texture->addPicture(picture);
	}else{
		PictureRGBA8* picture = pictureManager->createPictureRGBA8(pictureName);
		picture->setPath(picturePath);
		picture->setSize(DimensionI(width, height));
		Color4c* image = new Color4c[pixelCount];
		for(u_int i = 0; i < pixelCount; i++){
			image[i].setARGB(imageData[i]);
		}
		picture->setImage(image);
		SafeArrayDelete(image);
		texture->addPicture(picture);
	}
	SafeArrayDelete(imageData);
	return true;
}
//------------------------------------------------------------------------------
