//------------------------------------------------------------------------------
// 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
 * SF互換パッドヘッダ
 * @author Junpee
 */

#ifndef SF_PAD_H_
#define SF_PAD_H_

#include <Input/Pad/Pad.h>

namespace Lamp{

//------------------------------------------------------------------------------
/**
 * SF互換パッド
 */
class SFPad : public Pad{
public:
	/**
	 * 互換性チェック
	 * @param joystick 互換性をチェックするジョイスティック
	 * @return 互換性があればtrueを返す
	 */
	static bool checkCompatibility(Joystick* joystick);

	/// ボタン
	enum Button{
		button0 = 0,
		button1,
		button2,
		button3,
		buttonL,
		buttonR,
		buttonStart,
		buttonSelect,
		maxButtonCount,
		buttonUnknown = -1,
		buttonA = 0,
		buttonB = 1,
		buttonX = 2,
		buttonY = 3,
	};

	//--------------------------------------------------------------------------
	// 生成、破棄
	//--------------------------------------------------------------------------
	/**
	 * コンストラクタ
	 * @param joystick 使用するジョイスティック
	 */
	SFPad(Joystick* joystick);

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

	//--------------------------------------------------------------------------
	// ボタンマップ
	//--------------------------------------------------------------------------
	/**
	 * ボタンマップの変更
	 * @param button ボタンマップを変更するボタン
	 * @param id 変更するボタンID
	 */
	virtual void changeButtonMap(Button button, int id);

	/**
	 * ボタンマップの取得
	 * @param button ボタンマップを取得するボタン
	 * @return ボタンID
	 */
	virtual int getButtonMap(const Button button){
		Assert((button >= 0) && (button < maxButtonCount));
		return buttonMap_[button];
	}

	//--------------------------------------------------------------------------
	// デジタル境界
	//--------------------------------------------------------------------------
	/**
	 * デジタル境界の設定
	 * @param digitalBoundary デジタル境界
	 */
	virtual void setDigitalBoundary(float digitalBoundary){
		Assert((digitalBoundary > 0.f) && (digitalBoundary <= 1.f));
		digitalBoundary_ = digitalBoundary;
	}

	/**
	 * デジタル境界の取得
	 * @return デジタル境界
	 */
	virtual float setDigitalBoundary() const{ return digitalBoundary_; }

	//--------------------------------------------------------------------------
	// 軸データの取得
	//--------------------------------------------------------------------------
	/**
	 * X軸の取得
	 * @return 1から-1の値をとるX軸
	 */
	virtual float getXAxis() const;

	/**
	 * Y軸の取得
	 * @return 1から-1の値をとるY軸
	 */
	virtual float getYAxis() const;

	//--------------------------------------------------------------------------
	// 十字キーデータの取得
	//--------------------------------------------------------------------------
	/**
	 * 上キーが押されているか
	 * @return 上キーが押されていればtrue
	 */
	virtual bool upKeyPressed() const;

	/**
	 * 上キーが下がった
	 * @return 上キーが下がったならばtrue
	 */
	virtual bool upKeyDown() const;

	/**
	 * 上キーが上がった
	 * @return 上キーが上がったならばtrue
	 */
	virtual bool upKeyUp() const;

	//--------------------------------------------------------------------------
	/**
	 * 下キーが押されているか
	 * @return 下キーが押されていればtrue
	 */
	virtual bool downKeyPressed() const;

	/**
	 * 下キーが下がった
	 * @return 下キーが下がったならばtrue
	 */
	virtual bool downKeyDown() const;

	/**
	 * 下キーが上がった
	 * @return 下キーが上がったならばtrue
	 */
	virtual bool downKeyUp() const;

	//--------------------------------------------------------------------------
	/**
	 * 左キーが押されているか
	 * @return 左キーが押されていればtrue
	 */
	virtual bool leftKeyPressed() const;

	/**
	 * 左キーが下がった
	 * @return 左キーが下がったならばtrue
	 */
	virtual bool leftKeyDown() const;

	/**
	 * 左キーが上がった
	 * @return 左キーが上がったならばtrue
	 */
	virtual bool leftKeyUp() const;

	//--------------------------------------------------------------------------
	/**
	 * 右キーが押されているか
	 * @return 右キーが押されていればtrue
	 */
	virtual bool rightKeyPressed() const;

	/**
	 * 右キーが下がった
	 * @return 右キーが下がったならばtrue
	 */
	virtual bool rightKeyDown() const;

	/**
	 * 右キーが上がった
	 * @return 右キーが上がったならばtrue
	 */
	virtual bool rightKeyUp() const;

	//--------------------------------------------------------------------------
	// ボタンデータの取得
	//--------------------------------------------------------------------------
	/**
	 * ボタンが押されているか
	 * @param button ボタン
	 * @return ボタンが押されていればtrue
	 */
	virtual bool buttonPressed(Button button) const;

	/**
	 * ボタンが下がった
	 * @param button ボタン
	 * @return ボタンが下がったならばtrue
	 */
	virtual bool buttonDown(Button button) const;

	/**
	 * ボタンが上がった
	 * @param button ボタン
	 * @return ボタンが上がったならばtrue
	 */
	virtual bool buttonUp(Button button) const;

	//--------------------------------------------------------------------------
	// 文字列データ取得
	//--------------------------------------------------------------------------
	/**
	 * ボタン文字列の取得
	 * @param button ボタン
	 * @return ボタン文字列
	 */
	static String getButtonString(Button button);

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

protected:
	//--------------------------------------------------------------------------
	/**
	 * Y軸値から上キーへの変換
	 * @param yAxis Y軸値
	 * @return 上キーが押されていればtrue
	 */
	inline bool yAxisToUpKey(float yAxis) const{
		return (yAxis < (-digitalBoundary_));
	}

	/**
	 * Y軸値から下キーへの変換
	 * @param yAxis Y軸値
	 * @return 下キーが押されていればtrue
	 */
	inline bool yAxisToDownKey(float yAxis) const{
		return (yAxis > digitalBoundary_);
	}

	/**
	 * X軸値から左キーへの変換
	 * @param xAxis X軸値
	 * @return 左キーが押されていればtrue
	 */
	inline bool xAxisToLeftKey(float xAxis) const{
		return (xAxis < (-digitalBoundary_));
	}

	/**
	 * X軸値から右キーへの変換
	 * @param xAxis X軸値
	 * @return 右キーが押されていればtrue
	 */
	inline bool xAxisToRightKey(float xAxis) const{
		return (xAxis > digitalBoundary_);
	}

	/// ボタンマップ
	int buttonMap_[maxButtonCount];
	/// デジタル境界
	float digitalBoundary_;

private:

};

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