/*
 * BallFactory.h
 *
 *  Created on: Aug 9, 2019
 *      Author: fredrick
 */

#ifndef BALLFACTORY_H_
#define BALLFACTORY_H_

#include <cstdint>
#include <string>
#include <memory>
#include <functional>
#include <vector>

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>

#include <ecos/utility/Memory.h>
#include <ecos/core/IDCache.h>
#include <ecos/core/Log.h>
#include <ecos/core/BroadcastObservable.h>
#include <ecos/core/Message.h>
#include <ecos/core/Entity.h>
#include <ecos/core/SceneGraph.h>
#include <ecos/core/ICCResponseComponent.h>
#include <ecos/asset/AssetSystem.h>
#include <ecos/asset/DataManagementMode.h>
#include <ecos/physics/PhysicsSystem.h>
#include <ecos/physics/PhysicsComponent.h>
#include <ecos/physics/ColliderFactory.h>
#include <ecos/physics/Collider.h>
#include <ecos/graphics/GraphicsSystem.h>
#include <ecos/graphics/GraphicsComponent.h>
#include <ecos/graphics/RenderLayer.h>
#include <ecos/graphics/TextureFactory.h>
#include <ecos/graphics/Texture.h>
#include <ecos/graphics/assets/ShaderAsset.h>
#include <ecos/graphics/ShaderProgram.h>
#include <ecos/graphics/ShaderProgramFactory.h>
#include <ecos/graphics/Material.h>
#include <ecos/graphics/MaterialFactory.h>
#include <ecos/graphics/Mesh.h>
#include <ecos/graphics/MeshFactory.h>
#include <ecos/graphics/ModelRenderable.h>
#include <ecos/graphics/lighting/LightSource.h>
#include <ecos/graphics/lighting/LightSourceFactory.h>
#include <ecos/graphics/ModelRenderableFactory.h>
#include <ecos/graphics/ShaderType.h>

#include "BallPhysicsComponent.h"

namespace JamSpook {

using std::string;
using std::shared_ptr;
using std::make_shared;
using std::weak_ptr;
using std::dynamic_pointer_cast;
using std::function;
using std::bind;
using std::vector;

using glm::vec3;
using glm::mat4;
using glm::quat;
using glm::translate;

using ecos::utility::getShared;
using ecos::core::IDCache;
using ecos::core::logging::Log;
using ecos::core::logging::LogLevel;
using ecos::core::BroadcastObservable;
using ecos::core::Message;
using ecos::core::Entity;
using ecos::core::SceneGraph;
using ecos::core::ICCResponseComponent;
using ecos::asset::AssetSystem;
using ecos::asset::DataManagementMode;
using ecos::graphics::GraphicsSystem;
using ecos::graphics::GraphicsComponent;
using ecos::graphics::RenderLayer;
using ecos::graphics::TextureFactory;
using ecos::graphics::Texture;
using ecos::graphics::ShaderType;
using ecos::graphics::ShaderAsset;
using ecos::graphics::ShaderProgram;
using ecos::graphics::ShaderProgramFactory;
using ecos::graphics::Material;
using ecos::graphics::MaterialFactory;
using ecos::graphics::Mesh;
using ecos::graphics::MeshFactory;
using ecos::graphics::ModelRenderableFactory;
using ecos::graphics::ModelRenderable;
using ecos::graphics::lighting::LightSource;
using ecos::graphics::lighting::LightSourceFactory;
using ecos::physics::PhysicsSystem;
using ecos::physics::PhysicsComponent;
using ecos::physics::ColliderFactory;
using ecos::physics::Collider;

///
class BallFactory
{
private:
    weak_ptr<AssetSystem>    mAssetSystem;
    weak_ptr<GraphicsSystem> mGraphicsSystem;
    weak_ptr<PhysicsSystem>  mPhysicsSystem;
    weak_ptr<RenderLayer>    mRenderLayer;

public:
    BallFactory(weak_ptr<AssetSystem>    assetSystem,
                weak_ptr<GraphicsSystem> graphicsSystem,
                weak_ptr<PhysicsSystem>  physicsSystem,
                weak_ptr<RenderLayer>    renderLayer);
    virtual ~BallFactory();

    shared_ptr<Entity> createBall(const vec3 position,
                                  const float radius,
                                  const float mass,
                                  const float restitution,
                                  const string& ballName,
                                  const vec3 lightColor);
};

} // namespace JamSpook

#endif // BALLFACTORY_H_
