#pragma once

#include <list>
#include "stdio.h"
#include <utility>


template <typename T>
class Callable{
public:
    Callable():taskId(generateTaskId()){}
    virtual ~Callable() {}
    virtual T call() = 0;
    int getTaskId() const{return taskId;}
private:
    int generateTaskId(){
        static volatile int N = 0;
        return N++;
    }

    const int taskId;
};

template <typename T>
class Runnable{
public:
    Runnable():taskId(generateTaskId()){}
    virtual void run() = 0;
    virtual ~Runnable() {}
    int getTaskId() const{return taskId;}
private:
    int generateTaskId(){
        static volatile int N = 0;
        return N++;
    }

    const int taskId;
};


class ThreadPoolCachedEx{
public:
    inline ThreadPoolCachedEx(const int hotThreads, const int maxThreads, const int timeout);
    inline virtual ~ThreadPoolCachedEx();
    template <typename T>
    void submit(Callable<T>* c);
    template <typename T>
    void submit(Runnable<T>* task);
    int getTimeout() const {return timeout;}
    //int getActualWorkersCount() const {return workers.size();}
    //inline ExecutionUnit<void*>* findTask();
    //boost::condition_variable queue_notifier;
    //boost::condition_variable pool_deletition_notifier;
    //boost::mutex queueMtx;
    //boost::mutex deletingMtx;
    //inline void tryToRemoveWorker(Worker* worker);
    //bool isShutdown() {return false;}   //TODO: isShutdown
    //void shutdown() {} //TODO: shutdown

private:
    //std::list<Worker* > workers;
    inline void startNewWorker();
    const int hotThreads;
    const int maxThreads;
    const int timeout;
    std::list<void* > tasksQueue;
};

#include "util/ThreadPoolCachedEx.cpp"



