#pragma once
#include "OBB.h"

class fkut_CubicModel : public fk_Model {
private:
	fk_IndexFaceSet	shape;

protected:
	void makeCircle(int div, double r);
	void makeBlock(double w, double h, double d);
	void makeSphere(int div, double r);
	void makePrism(int div, double rt, double rb, double h);
	void makeCone(int div, double r, double h);

public:
	fkut_CubicModel(void);
	virtual ~fkut_CubicModel(void);

	bool setParent(fk_Model &model, bool setMode = false);
};

class fkut_SphereModel : public fkut_CubicModel {
private:
	friend class fkut_BlockModel;

	double	rad;

public:
	void create(int div, double radius)
	{
		makeSphere(div, radius);
		rad = radius;
	};

	bool checkToSphere(fkut_SphereModel &other, fk_Vector &backV)
	{
		fk_Vector distV = other.getInhPosition()-getInhPosition();

		if(distV.dist() < rad+other.rad) {
			double fixDist = distV.dist()-(rad+other.rad);
			distV.normalize();
			distV *= fixDist;
			backV = distV;
			return true;
		} else {
			backV.init();
			return false;
		}
	};
};

class fkut_BlockModel : public fkut_CubicModel {
private:
	fkut_OBB	obb;
public:
	void create(double width, double height, double depth)
	{
		makeBlock(width, height, depth);
		obb.setBlockSize(width, height, depth);
		obb.setModel(this);
	};

	bool checkToBlock(fkut_BlockModel &other, fk_Vector &backV)
	{
		return obb.checkVSOBB(other.obb, backV);
	};
	fk_Vector checkToPoint(fk_Vector &pos)
	{
		return obb.checkVSPoint(pos);
	};
	bool checkToSphere(fkut_SphereModel &other, fk_Vector &backV)
	{
		return obb.checkVSSphere(other.getInhPosition(), other.rad, backV);
	};

	bool checkToMovingBlock(fkut_BlockModel &other, fk_Vector &spd, fk_Vector &backV)
	{
		return obb.checkVSMovingOBB(other.obb, spd, backV);
	};
	bool checkToMovingSphere(fkut_SphereModel &other, fk_Vector &spd, fk_Vector &backV)
	{
		return obb.checkVSMovingSphere(other.getInhPosition(), other.rad, spd, backV);
	};
};

class fkut_PrismModel : public fkut_CubicModel {
private:
	fkut_Capsule	cap;
public:
	void create(int div, double top, double bottom, double height)
	{
		makePrism(div, top, bottom, height);
		cap.setCapsuleSize(bottom, height);
		cap.setModel(this);
	};

	bool checkToCapsule(fkut_PrismModel &other, fk_Vector &backV)
	{
		return cap.checkVSCapsule(other.cap, &backV);
	};
};

class fkut_ConeModel : public fkut_CubicModel {
public:
	void create(int div, double radius, double height)
	{
		makeCone(div, radius, height);
	};
};
