//	World.h - Base class for the various worlds.
//  ----------------------------------------------------------------------------
//	This file is part of 'NiallsAVLib', base code for any kind of audiovisual
//	apps.
//	Copyright (C) 2012  Niall Moody
//	
//	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 WORLD_H_
#define WORLD_H_

#include "ThreeFloats.h"
#include "c0xHeaders.h"
#include "TwoFloats.h"

///	Base class for the various worlds.
class World
{
  public:
	///	Constructor.
	/*!
		\param backCol The background colour for the planet.
		\param pCol1 The colour of the planet's outermost ring.
		\param pCol2 The colour of the planet's middle ring.
		\param pCol3 The colour of the planet's inner ring.
		\param pScales The relative scales of the planet's rings (x should
		always be 1.0).
		\param pos The planet's position.
	 */
	World(const ThreeFloats& backCol,
		  const ThreeFloats& pCol1,
		  const ThreeFloats& pCol2,
		  const ThreeFloats& pCol3,
		  const ThreeFloats& pScales,
		  const TwoFloats& pos):
	backgroundColour(backCol),
	ringScales(pScales),
	scale(0.05f),
	//position(pos),
	startPosition(pos)
	{
		ringColours[0] = pCol1;
		ringColours[1] = pCol2;
		ringColours[2] = pCol3;

		ringPos[0] = pos;
		ringPos[1] = pos;
		ringPos[2] = pos;
	};
	///	Destructor.
	virtual ~World() {};

	///	Handles mouse input for this world.
	virtual void mouseMove(const TwoFloats& pos) = 0;
	///	Returns true when it's time to move to the next world.
	virtual bool worldDone() = 0;

	///	Used to gradually shrink the world.
	void tick()
	{
		if((scale < 0.66f) && (scale > 0.01f))
		{
			if(scale > 0.05f)
				scale -= 0.001f;
			else
				scale -= 0.00005f;
		}

		subclassTick();
	};

	///	Sets the world's position.
	void setPosition(const TwoFloats& val)
	{
		//position = val;
		ringPos[0] = val;
		ringPos[1] = val;
		ringPos[2] = val;
	};
	///	Sets the world's overall scale.
	void setOverallScale(float val)
	{
		scale = val;
	};
	///	Sets the world's rings' colours.
	void setRingColours(const ThreeFloats cols[3])
	{
		ringColours[0] = cols[0];
		ringColours[1] = cols[1];
		ringColours[2] = cols[2];
	};

	///	Called whenever there's a bar start.
	virtual void barStart() {};

	///	Returns the world's background colour.
	const ThreeFloats& getBackgroundCol() const {return backgroundColour;};
	///	Returns the world's outermost ring colour.
	const ThreeFloats& getRing1Col() const {return ringColours[0];};
	///	Returns the world's middle ring colour.
	const ThreeFloats& getRing2Col() const {return ringColours[1];};
	///	Returns the world's inner ring colour.
	const ThreeFloats& getRing3Col() const {return ringColours[2];};
	///	Returns the world's three scales.
	const ThreeFloats& getScales() const {return ringScales;};
	///	Returns the world's overall scale.
	float getOverallScale() const {return scale;};
	///	Returns the world's start position.
	const TwoFloats& getStartPosition() const {return startPosition;};
	///	Returns the world's position.
	//const TwoFloats& getPosition() const {return position;};
	///	Returns the outermost ring's position.
	const TwoFloats& getRing1Pos() const {return ringPos[0];};
	///	Returns the outermost ring's position.
	const TwoFloats& getRing2Pos() const {return ringPos[1];};
	///	Returns the outermost ring's position.
	const TwoFloats& getRing3Pos() const {return ringPos[2];};
  protected:
	///	Sets the world's background colour.
	void setBackgroundColour(const ThreeFloats& col)
	{
		backgroundColour = col;
	};
	///	Sets the world's rings' scales.
	void setRingScales(const ThreeFloats& val)
	{
		ringScales = val;
	};
	///	Sets the outermost ring's position.
	void setRing1Pos(const TwoFloats& val)
	{
		ringPos[0] = val;
	};
	///	Sets the outermost ring's position.
	void setRing2Pos(const TwoFloats& val)
	{
		ringPos[1] = val;
	};
	///	Sets the outermost ring's position.
	void setRing3Pos(const TwoFloats& val)
	{
		ringPos[2] = val;
	};

	///	Called for every draw frame.
	virtual void subclassTick() {};
  private:
	///	The planet's background colour.
	ThreeFloats backgroundColour;
	///	The planet's three rings' colours.
	ThreeFloats ringColours[3];
	///	The relative scales of the planet's three rings.
	ThreeFloats ringScales;
	///	The overall scale of the planet.
	float scale;
	///	The planet's actual position.
	//TwoFloats position;
	///	The rings' positions.
	TwoFloats ringPos[3];
	///	The planet's start position.
	TwoFloats startPosition;
};

#endif
