/*
	AramakiOnline
	Copyright (C) 2008 superbacker

	This program 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.

	This program 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 this
	program. If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef MODEL_H_
#define MODEL_H_

#include <wx/wx.h>
#include <wx/glcanvas.h>
#include <wx/tokenzr.h>
#include "Texture.h"
#include <vector>
#include <map>
#include "DisplayList.h"
#include <wx/file.h>
#include "Point3d.h"
#include "Face.h"

//wavefront obj ローダ
class Model {
	//テクスチャ座標
	struct TexturePoint {
		//座標
		double x,y;
	};

	//マテリアル
	struct Material {
		//周囲光
		float ambient[4];
		//拡散光
		float diffuse[4];
		//反射光
		float specular[4];
		//反射の強さ
		float shininess;
		//テクスチャ
		Texture *texture;
	};

	//テクスチャ座標配列
	typedef std::vector<TexturePoint> TexturePoints;
	//頂点法線配列
	typedef std::vector<Point3d> NormalVectors;
	//面配列
	typedef std::vector<Face> Faces;
	//マテリアルマップ
	typedef std::map<wxString,Material> Materials;
	//テクスチャ配列
	typedef std::vector<Texture *> Textures;

	Faces faces;
	Textures textures;
	//ディスプレイリスト
	DisplayList displayList;

	//オブジェクトファイルをパース
	void parseObject(const wxString &fileName);
	//マテリアルライブラリファイルをパース
	void parseMaterial(const wxString &fileName,Materials &materials);
	//マテリアルライブラリ
	void parseMaterialLibrary(wxStringTokenizer &tokenizer,Materials &materials);
	//頂点
	void parseVertex(wxStringTokenizer &tokenizer,Vertexes &vertexes);
	//テクスチャ頂点
	void parseTextureVertex(wxStringTokenizer &tokenizer,TexturePoints &texturePoints);
	//頂点法線
	void parseNormalVector(wxStringTokenizer &tokenizer,NormalVectors &normalVectors);
	//面
	void parseFace(wxStringTokenizer &tokenizer,Vertexes &vertexes,TexturePoints &texturePoints,NormalVectors &normalVectors);
	//マテリアル指定
	void parseUseMaterial(wxStringTokenizer &tokenizer,Materials &materials);
	//新規マテリアル
	Material &parseNewMaterial(wxStringTokenizer &tokenizer,Materials &materials);
	//周囲光
	void parseAmbient(wxStringTokenizer &tokenizer,Material &material);
	//拡散光
	void parseDiffuse(wxStringTokenizer &tokenizer,Material &material);
	//反射光
	void parseSpecular(wxStringTokenizer &tokenizer,Material &material);
	//反射の強さ
	void parseShininess(wxStringTokenizer &tokenizer,Material &material);
	//テクスチャ
	void parseTexture(wxStringTokenizer &tokenizer,Material &material);

	Model(const Model &);
	void operator=(const Model &);
public:
	Model(const wxString &fileName);
	~Model();
	//描画
	void render() const;
	// 線分と当たり判定をとる
	bool collide(const Point3d &lineStart,const Point3d &lineEnd,Point3d &crossPoint,Face &hitFace) const;
};

#endif /* MODEL_H_ */
