/// Copyright (c) 2010 Ruben Penalva. All rights reserved.
/// Redistribution and use in source and binary forms, with or without modification, 
/// are permitted provided that the following conditions are met:
///    1. Redistributions of source code must retain the above copyright notice, this 
///    list of conditions and the following disclaimer.
///    2. Redistributions in binary form must reproduce the above copyright notice,
///    this list of conditions and the following disclaimer in the documentation and/or
///    other materials provided with the distribution.
///    3. The name of the author may not be used to endorse or promote products derived
///    from this software without specific prior written permission.
///
/// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
/// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
/// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 
/// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 
/// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
/// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
/// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 
/// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef _FLOCK_H_
#define _FLOCK_H_

#include "Vector3.h"
#include <boost\shared_array.hpp>

namespace TaskBasedFlockSim
{

typedef boost::shared_array<TestFrameWork::Vector3> Positions;
typedef boost::shared_array<TestFrameWork::Vector3> Velocities;
typedef boost::shared_array<float> Angles;

class Flock
{
public:
	Flock(size_t boidsCount = 0);

	~Flock(void);

	void SetMaxSize(size_t boidsCount);

	float GetMaxSize(void) const;

	void SetAngleIncrement(float angle);

	float GetAngleIncrement(void) const;

	void SetSeparationWeight(float weight);

	float GetSeparationWeight(void) const;

	void SetCohesionWeight(float weight);

	float GetCohesionWeight(void) const;

	void SetAlignmentWeight(float weight);

	float GetAlignmentWeight(void) const;

	void SetTrefoilKnotPathWeight(float weight);

	float GetTrefoilKnotPathWeight(void) const;
	
	size_t GetBoidsCount(void) const;	

	Positions& GetPositions(void);

	Velocities& GetVelocities(void);

	Angles& GetAngles(void);

	const Positions& GetPositions(void) const;

	const Velocities& GetVelocities(void) const;

	const Angles& GetAngles(void) const;

	Flock& operator=(const Flock& flock);

	void SetMaxSpeed(const TestFrameWork::Vector3& speed);

	void SetSeparationDistance(float distance);

	void SetGroupDistance(float distance);

	const TestFrameWork::Vector3& GetMaxSpeed(void) const;

	float GetSeparationDistance(void) const;

	float GetGroupDistance(void) const;

	void Resize(size_t boidsCount);

private:
	size_t m_maxFlockSize;

	float m_angleIncrement;

	float m_separationWeight;
	float m_cohesionWeight;
	float m_alignmentWeight;
	float m_trefoilknotPathWeight;

	TestFrameWork::Vector3 m_maxSpeed;
	float m_separationDistance;
	float m_groupDistance;

	size_t m_boidsCount;

	Positions m_positions;
	Velocities m_velocities;
	Angles m_angles;
};

}

#endif