#ifndef INCLUDED_BOBCAT_CLOCKBASE_
#define INCLUDED_BOBCAT_CLOCKBASE_

#include <ostream>

#include <bobcat/clocktypes>

namespace FBB
{

template <typename ChronoClock>
struct ClockBase;

template <typename ChronoClock>
std::ostream &operator<<(std::ostream &out,
                         ClockBase<ChronoClock> const &clock);

template <typename ChronoClock>
struct ClockBase: public ClockTypes
{
    using Clock = ChronoClock;            // std::chrono::system_clock;
    using TimePoint = Clock::time_point;

    friend std::ostream &operator<< <>(std::ostream &out,               // .f
                                       ClockBase<ChronoClock> const &clock);
    private:
        TimePoint d_timePoint;

    public:
        ClockBase(TimePoint const &timePoint); // = now() ?

        template <typename ClockTp>
        ClockBase(ClockBase<ClockTp> const &clock);                     // .f

        template <typename Ratio>
        ClockBase<ChronoClock> &operator+=(
                    std::chrono::duration<int64_t, Ratio> const &amount);

        ClockBase<ChronoClock> &operator+=(int amount);  // amount in seconds

        template <typename Ratio>
        ClockBase<ChronoClock> &operator-=(
                        std::chrono::duration<int64_t, Ratio> const &amount);

        ClockBase<ChronoClock> &operator-=(int amount);  // amount in seconds

        Duration elapsed() const;   // time_since_epoch                 // .f
        long int count() const;                                         // .f

        TimePoint const &timePoint() const; // inserts the same as when 
                                            // inserting the object itself

        template <typename Dest>
        double toDouble() const;

        static TimePoint max();
        static TimePoint min();
        static TimePoint now();
};

#include "clockbase.f"

} // FBB        
#endif

