#ifndef TIMER_H_
#define TIMER_H_

namespace system {
	class TimerController;
	class Task;
}

namespace system {
	/*
	 * タイマー
	 */
	class Timer {
		// 定数
		static const dword FLAG_FREE = 0;
		static const dword FLAG_ALLOC = 1;
		static const dword FLAG_ACTIVE = 2;
		
		Timer* next_timer_;
		dword timeout_;
		
		dword flags_;
		bool auto_close_;
		
		//std::queue<Message>* fifo_;
		Task* task_;
		int fifo_data_;
		
	public:
		explicit Timer();
		
		// 使用マークを付ける
		void use() { flags_ = FLAG_ALLOC; }
		
		// 未使用マークを付ける
		void release() { flags_ = FLAG_FREE; }
		
		// タイマが使用中かどうか
		bool used() const { return flags_ >= FLAG_ALLOC; }
		
		// タイマが作動中かどうか
		bool active() const { return flags_ == FLAG_ACTIVE; }
		
		// タイムアウト時刻を設定する
		void set_time(dword timeout) {
			timeout_ = timeout;
			flags_ = FLAG_ACTIVE;
		}
		
		// タイムアウト時刻を取得する
		dword get_time() { return timeout_; }
		
		// タイムアウトを知らせる
		void timeout() { flags_ = FLAG_ALLOC; }
		
		// 次のタイマーを設定する
		void set_nexttimer(Timer* tim) { next_timer_ = tim; }
		
		// 次のタイマーを取得する
		Timer* get_nexttimer() { return next_timer_; }
		
		// 自動クローズを有効にする
		void enable_autoclose() { auto_close_ = true; }
		
		// 自動クローズを無効にする
		void disable_autoclose() { auto_close_ = false; }
		
		// 自動クローズが有効かどうか
		bool autoclose() { return auto_close_; }
		
		// fifoバッファを設定
		void set_task(Task* task, int data);
		
		// fifoに送るデータを設定
		void set_data(int data) { fifo_data_ = data; }
		
		// メッセージをfifoバッファに送る
		void send_message();
	};

	/*
	 * タイマーコントローラー
	 */
	class TimerController {
		static const int MAX_TIMERS = 1024;
		dword count_; // 32ビットタイマーカウンタ
		Timer* timers0_; // タイマーの実体
		Timer* timer_top_; // タイマーの先頭
		dword next_timeout_; // 次にタイムアウトする時間
	public:
		explicit TimerController();
		~TimerController();
		
		// 時刻を進める
		void countup() { count_++; }
		
		// 時刻を取得
		dword get_count() { return count_; }
		
		// タイムアウト時刻を取得する
		dword get_timeout() { return next_timeout_; }
		
		// 先頭タイマーを設定
		void set_timer_top(Timer* tim);
		
		// 先頭タイマーを取得
		Timer* get_timer_top() { return timer_top_; }
		
		// タイマーを生成
		Timer* alloc();
		
		// タイマーを解放
		void free(Timer* tim);
		
		// タイムアウト時刻を設定する
		void set_time(Timer* tim, dword timeout);
	};
	
	void timer_settime(Timer* timer, dword timeout);
}


#endif /*TIMER_H_*/
