//------------------------------------------------------------------------------
// 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
 * 交差結果ヘッダ
 * @author Junpee
 */

#ifndef INTERSECTION_RESULT_H_
#define INTERSECTION_RESULT_H_

#include <Core/Container/ArrayList.h>
#include <Geometry/System/Intersection.h>

namespace Lamp{

//------------------------------------------------------------------------------
/**
 * 交差結果
 */
class IntersectionResult{
public:
	/**
	 * コンストラクタ
	 */
	IntersectionResult(){}

	/**
	 * デストラクタ
	 */
	virtual ~IntersectionResult(){}

	//--------------------------------------------------------------------------
	/**
	 * クリア
	 */
	virtual void clear(){ intersections_.clear(); }

	/**
	 * 反転
	 */
	virtual void reverse(){
		int count = getCount();
		for(int i = 0; i < count; i++){ intersections_.get(i).reverse(); }
	}

	/**
	 * 交差しているか
	 * @return 交差していればtrue
	 */
	virtual bool isIntersected() const{
		return (intersections_.getCount() != 0);
	}

	//--------------------------------------------------------------------------
	/**
	 * 交差数の取得
	 * @return 交差数
	 */
	virtual int getCount() const{ return intersections_.getCount(); }

	/**
	 * 交差の取得
	 * @param index インデックス
	 * @return 交差
	 */
	virtual const Intersection& get(int index) const{
		return intersections_.get(index);
	}

	//--------------------------------------------------------------------------
	/**
	 * 交差位置の平均取得
	 * @return 交差位置の平均
	 */
	virtual Vector3 getAveragePosition() const{
		Assert(isIntersected());
		Vector3 result(Vector3::zero);
		int count = getCount();
		for(int i = 0; i < count; i++){ result += get(i).getPosition(); }
		result *= 1.f / count;
		return result;
	}

	/**
	 * 反射の平均取得
	 * @return 反射の平均
	 */
	virtual Vector3 getAverageRefrection() const{
		Vector3 result(Vector3::zero);
		if(!isIntersected()){ return result; }
		int count = getCount();
		for(int i = 0; i < count; i++){ result += get(i).getRefrection(); }
		result *= 1.f / count;
		return result;
	}

	/**
	 * 最大の反射取得
	 * @return 最大の反射
	 */
	virtual Vector3 getMaxRefrection() const{
		if(!isIntersected()){ return Vector3::zero; }
		Vector3 result(get(0).getRefrection());
		float maxSquaredLength = result.getSquaredLength();
		int count = getCount();
		for(int i = 1; i < count; i++){
			const Vector3& refrection = get(i).getRefrection();
			float squaredLength = refrection.getSquaredLength();
			if(squaredLength > maxSquaredLength){
				result = refrection;
				maxSquaredLength = squaredLength;
			}
		}
		return result;
	}

	//--------------------------------------------------------------------------
	/**
	 * 交差の追加
	 * @param intersection 交差
	 */
	virtual void add(const Intersection& intersection){
		intersections_.add(intersection);
	}

	/**
	 * 交差の削除
	 * @param index インデックス
	 */
	virtual void remove(int index){ intersections_.remove(index); }

	/**
	 * 交差の削除
	 * @param intersection 交差
	 * @return 削除したインデックス。-1なら該当する要素無し。
	 */
	virtual int remove(const Intersection& intersection){
		return intersections_.removeByValue(intersection);
	}

private:
	//--------------------------------------------------------------------------
	// コピーコンストラクタの隠蔽
	IntersectionResult(const IntersectionResult& copy);

	// 代入コピーの隠蔽
	void operator =(const IntersectionResult& copy);

	//--------------------------------------------------------------------------
	// 交差配列
	ArrayList<Intersection> intersections_;

};

//------------------------------------------------------------------------------
} // End of namespace Lamp
#endif // End of INTERSECTION_RESULT_H_
//------------------------------------------------------------------------------
