//------------------------------------------------------------------------------
// Lamp : Open source game middleware
// Copyright (C) 2004  Junpei Ohtani ( Email : junpee@users.sourceforge.jp )
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//------------------------------------------------------------------------------

/** @file
 * バッファ入力ヘッダ
 * @author Junpee
 */

#ifndef BUFFERED_INPUT_H_
#define BUFFERED_INPUT_H_

#include <Core/Thread/Thread.h>
#include <Core/Utility/FPSController.h>
#include <Core/Container/Deque.h>
#include <Core/Container/ArrayList.h>
#include <Input/Keyboard/KeyboardState.h>
#include <Input/Mouse/MouseState.h>
#include <Input/Joystick/JoystickState.h>

namespace Lamp{

class Keyboard;
class KeyboardDevice;
class Mouse;
class MouseDevice;
class Joystick;
class JoystickDevice;
class BinaryWriter;
class BinaryReader;

//------------------------------------------------------------------------------
/**
 * バッファ入力
 */
class BufferedInput : public Thread{
friend class LampInput;
public:
	/// 60FPS
	static const float interval60FPS;
	/// 30FPS
	static const float interval30FPS;

	//--------------------------------------------------------------------------
	/**
	 * 目標時間間隔の設定
	 * @param targetInterval 目標時間間隔をミリ秒で指定
	 */
	virtual void setTargetInterval(float targetInterval);

	/**
	 * 目標時間間隔の取得
	 * @return 目標時間間隔をミリ秒で取得
	 */
	virtual float getTargetInterval();

	//--------------------------------------------------------------------------
	/**
	 * 実行
	 * @param thread 実行しているスレッド
	 *
	 * ユーザは呼び出さないで下さい
	 */
	virtual void run(Thread* thread);

private:
	//--------------------------------------------------------------------------
	/**
	 * コンストラクタ
	 */
	BufferedInput();

	/**
	 * デストラクタ
	 */
	virtual ~BufferedInput();

	//--------------------------------------------------------------------------
	/**
	 * キーボードの設定
	 * @param keyboard キーボード
	 * @param keyboardDevice キーボードデバイス
	 */
	virtual void setKeyboard(
		Keyboard* keyboard, KeyboardDevice* keyboardDevice){
		keyboard_ = keyboard;
		keyboardDevice_ = keyboardDevice;
		Assert((keyboard_ != NULL) && (keyboardDevice_ != NULL));
	}

	/**
	 * マウスの設定
	 * @param mouse マウス
	 * @param mouseDevice マウスデバイス
	 */
	virtual void setMouse(Mouse* mouse, MouseDevice* mouseDevice){
		mouse_ = mouse;
		mouseDevice_ = mouseDevice;
		Assert((mouse_ != NULL) && (mouseDevice_ != NULL));
	}

	/**
	 * ジョイスティックの追加
	 * @param joystick ジョイスティック
	 * @param joystickDevice ジョイスティックデバイス
	 */
	virtual void addJoystick(
		Joystick* joystick, JoystickDevice* joystickDevice){
		Assert((joystick != NULL) && (joystickDevice != NULL));
		joysticks_.add(joystick);
		joystickDevices_.add(joystickDevice);
	}

	//--------------------------------------------------------------------------
	/**
	 * 入力があるか
	 * @return 入力があればtrue
	 */
	virtual bool hasMoreInput();

	/**
	 * 次の入力
	 */
	virtual void nextInput();

	/**
	 * 入力数の取得
	 * @return 入力数
	 */
	virtual int getInputCount();

	//--------------------------------------------------------------------------
	// ログ取得
	//--------------------------------------------------------------------------
	/**
	 * ログ取得の開始
	 * @param binaryWriter バイナリライタ
	 */
	virtual void startLogging(BinaryWriter* binaryWriter);

	/**
	 * ログ取得の終了
	 */
	virtual void endLogging();

	//--------------------------------------------------------------------------
	// ログ再生
	//--------------------------------------------------------------------------
	/**
	 * ログ再生の開始
	 * @param binaryReader バイナリリーダ
	 */
	virtual void playLog(BinaryReader* binaryReader);

	/**
	 * ログ再生の停止
	 */
	virtual void stopLog();

	//--------------------------------------------------------------------------
	// デバイスポーリング
	virtual void devicePolling();

	// デバイスアップデート
	virtual void deviceUpdate();

	// ログアップデート
	virtual void logUpdate();

	// ログの書き出し
	virtual void writeLog();

	//--------------------------------------------------------------------------
	// コピーコンストラクタの隠蔽
	BufferedInput(const BufferedInput& copy);

	// 代入コピーの隠蔽
	void operator =(const BufferedInput& copy);

	// FPSコントローラ
	FPSController fpsController_;
	// ログライタ
	BinaryWriter* logWriter_;
	// ログリーダ
	BinaryReader* logReader_;

	// キーボード
	Keyboard* keyboard_;
	// キーボードデバイス
	KeyboardDevice* keyboardDevice_;
	// キーボードステート
	Deque<KeyboardState> keyboardStates_;

	// マウス
	Mouse* mouse_;
	// マウスデバイス
	MouseDevice* mouseDevice_;
	// マウスステート
	Deque<MouseState> mouseStates_;

	// ジョイスティック
	ArrayList<Joystick*> joysticks_;
	// ジョイスティックデバイス
	ArrayList<JoystickDevice*> joystickDevices_;
	// ジョイスティックステート
	Deque<JoystickState> joystickStates_;

};

//------------------------------------------------------------------------------
} // End of namespace Lamp
#endif // End of BUFFERED_INPUT_H_
//------------------------------------------------------------------------------
