//------------------------------------------------------------------------------
// 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 JOYSTICK_DEVICE_H_
#define JOYSTICK_DEVICE_H_

#include <Input/System/InputDevice.h>
#include <Input/Joystick/JoystickState.h>

namespace Lamp{

//------------------------------------------------------------------------------
/**
 * ジョイスティックデバイス
 */
class JoystickDevice : public InputDevice{
friend class LampInput;
friend class BufferedInput;
public:
	//--------------------------------------------------------------------------
	// 定数
	//--------------------------------------------------------------------------
	/// 最大視点コントローラ数
	static const int maxPOVCount = JoystickState::maxPOVCount;

	/// 最大スライダ数
	static const int maxSliderCount = JoystickState::maxSliderCount;

	/// 最大ボタン数
	static const int maxButtonCount = JoystickState::maxButtonCount;

	/// 軸データ最大値
	static const int maxAxisValue = JoystickState::maxAxisValue;

	/// 軸データ最小値
	static const int minAxisValue = JoystickState::minAxisValue;

	/// 視点コントローラ最大値
	static const int maxPOVValue = JoystickState::maxPOVValue;

	//--------------------------------------------------------------------------
	/**
	 * ジョイスティックステートの取得
	 * @return ジョイスティックステート
	 */
	virtual const JoystickState& getJoystickState() const{
		return joystickState_;
	}

	/**
	 * 文字列への変換
	 * @return 文字列
	 */
	virtual String toString() const;

	//--------------------------------------------------------------------------
	/**
	 * X軸を持つか
	 * @return X軸を持てばtrue
	 */
	virtual bool hasXAxis() const{ return hasXAxis_; }

	/**
	 * Y軸を持つか
	 * @return Y軸を持てばtrue
	 */
	virtual bool hasYAxis() const{ return hasYAxis_; }

	/**
	 * Z軸を持つか
	 * @return Z軸を持てばtrue
	 */
	virtual bool hasZAxis() const{ return hasZAxis_; }

	//--------------------------------------------------------------------------
	/**
	 * X回転を持つか
	 * @return X回転を持てばtrue
	 */
	virtual bool hasXRotation() const{ return hasXRotation_; }

	/**
	 * Y回転を持つか
	 * @return Y回転を持てばtrue
	 */
	virtual bool hasYRotation() const{ return hasYRotation_; }

	/**
	 * Z回転を持つか
	 * @return Z回転を持てばtrue
	 */
	virtual bool hasZRotation() const{ return hasZRotation_; }

	//--------------------------------------------------------------------------
	/**
	 * 視点コントローラ数の取得
	 * @return 視点コントローラ数
	 */
	virtual int getPOVCount() const{ return povCount_; }

	/**
	 * スライダ数の取得
	 * @return スライダ数
	 */
	virtual int getSliderCount() const{ return sliderCount_; }

	//--------------------------------------------------------------------------
	/**
	 * ジョイスティックオブジェクトの列挙コールバック
	 *
	 * ユーザはこのメソッドを呼び出さないで下さい
	 * @param instance デバイスオブジェクトインスタンス
	 * @param userData ユーザデータ
	 * @return 列挙継続フラグ
	 */
	static int __stdcall joystickObjectEnumeration(
		const DIDEVICEOBJECTINSTANCE* instance, void* userData);

protected:
	//--------------------------------------------------------------------------
	/**
	 * コンストラクタ
	 */
	JoystickDevice();

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

	/**
	 * 初期化
	 * @param inputDevice 入力デバイス
	 * @param windowHandle ウィンドウハンドル
	 * @return 成功すればtrue
	 */
	virtual bool initialize(DirectInputDevice* inputDevice, HWND windowHandle);

	/**
	 * ジョイスティックオブジェクトのチェック
	 * @param instance ジョイスティックオブジェクト
	 * @return 成功すればtrue
	 */
	virtual bool checkJoystickObject(const DIDEVICEOBJECTINSTANCE* instance);

	/**
	 * ポーリング
	 * @return ポーリングが正常であればtrue
	 */
	virtual bool polling();

private:
	// ジョイスティックステート
	JoystickState joystickState_;
	// 視点コントローラ数
	int povCount_;
	// スライダ数
	int sliderCount_;
	// X軸を持っているか
	bool hasXAxis_;
	// Y軸を持っているか
	bool hasYAxis_;
	// Z軸を持っているか
	bool hasZAxis_;
	// X回転を持っているか
	bool hasXRotation_;
	// Y回転を持っているか
	bool hasYRotation_;
	// Z回転を持っているか
	bool hasZRotation_;

	// デッドゾーン
	static const int deadZone_ = 3000;
	// 飽和ゾーン
	static const int saturationZone_ = 9500;
};

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