#include <nitro.h>
#include "peripheral.h"

static void peripheral_device_get(union peripheral_state *, int unknown);
static int  peripheral_device_set(union peripheral_state *);


static union peripheral_state _peripheralstate_normal;
static union peripheral_state _peripheralstate_current;
static union peripheral_state _peripheralstate_target;


//
// 周辺デバイスの自前ON/OFF制御
//
static void
peripheral_device_get(union peripheral_state *pstate,int unknowncase)
{
	PMBackLightSwitch bl_top;
	PMBackLightSwitch bl_bottom;
	PMLCDPower lcd;
	PMAmpSwitch ampsw;

	pstate->state = 0;

	if (PM_GetBackLight(&bl_top, &bl_bottom) == PM_RESULT_SUCCESS) {
		pstate->backlight_top    = (bl_top == PM_BACKLIGHT_ON)    ? 1 : 0;
		pstate->backlight_bottom = (bl_bottom == PM_BACKLIGHT_ON) ? 1 : 0;
	} else {
		// 取得できなかった場合は unknowncase にする。
		pstate->backlight_top    = !!unknowncase;
		pstate->backlight_bottom = !!unknowncase;
	}

	lcd = PM_GetLCDPower();
	pstate->lcd_power = (lcd == PM_LCD_POWER_ON) ? 1 : 0;

	if (PM_GetAmp(&ampsw) == PM_RESULT_SUCCESS) {
		pstate->amp_power = (ampsw == PM_AMP_ON) ? 1 : 0;
	} else {
		// 取得できなかった場合は unknowncase にする。
		pstate->amp_power = !!unknowncase;
	}

#if 0
	OS_TPrintf("peripheral_device_get: BackLight=%d/%d, LCD=%d, AMP=%d\n",
	           pstate->backlight_top,
	           pstate->backlight_bottom,
	           pstate->lcd_power,
	           pstate->amp_power);
#endif
}

static int
peripheral_device_set(union peripheral_state *pstate)
{
	u32 rc;

#if 0
	OS_TPrintf("peripheral_device_set: BackLight=%d/%d, LCD=%d, AMP=%d\n",
	           pstate->backlight_top,
	           pstate->backlight_bottom,
	           pstate->lcd_power,
	           pstate->amp_power);
#endif

	if (pstate->backlight_top && pstate->backlight_bottom) {
		rc = PM_SetBackLight(PM_LCD_ALL, PM_BACKLIGHT_ON);

	} else if (!pstate->backlight_top && !pstate->backlight_bottom) {
		rc = PM_SetBackLight(PM_LCD_ALL, PM_BACKLIGHT_OFF);

	} else {
		rc = PM_SetBackLight(PM_LCD_TOP,    (pstate->backlight_top    ? PM_BACKLIGHT_ON : PM_BACKLIGHT_OFF));
		if (rc != PM_RESULT_SUCCESS)
			return -1;

		rc = PM_SetBackLight(PM_LCD_BOTTOM, (pstate->backlight_bottom ? PM_BACKLIGHT_ON : PM_BACKLIGHT_OFF));
	}
	if (rc != PM_RESULT_SUCCESS)
		return -1;


	if (!PM_SetLCDPower(pstate->lcd_power ? PM_LCD_POWER_ON : PM_LCD_POWER_OFF))
		return -1;


	if (PM_SetAmp(pstate->amp_power ? PM_AMP_ON : PM_AMP_OFF) != PM_RESULT_SUCCESS)
		return -1;

	return 0;
}





void
peripheral_sync()
{
	if (_peripheralstate_current.state != _peripheralstate_target.state) {
		// デバイスの状態を変える。

		// 間隔が早すぎて失敗することもあるので成功するまで行う。
		if (peripheral_device_set(&_peripheralstate_target) == 0) {
			_peripheralstate_current = _peripheralstate_target;
		}
	}
}

void
peripheral_off()
{
	_peripheralstate_target.state = 0;
}

void
peripheral_save()
{
	peripheral_device_get(&_peripheralstate_current,1);
	_peripheralstate_target = _peripheralstate_current;
	_peripheralstate_normal = _peripheralstate_current;
}

void
peripheral_restore()
{
	_peripheralstate_target = _peripheralstate_normal;
}




#define LID_CLOSE_IGNORE_PERIOD	15
/*
 * LID_CLOSE_IGNORE_PERIODフレームの間、ずっと蓋が閉じられている状態ならば
 * TRUEを返す
 */
BOOL
IsLidClose()
{
	static u32 closestart = 0;

	if (PAD_DetectFold()) {
		if (closestart) {
			u32 closeperiod = OS_GetVBlankCount() - closestart;
			if (closeperiod >= LID_CLOSE_IGNORE_PERIOD) {
				return TRUE;
			}
		} else {
			closestart = OS_GetVBlankCount();
		}
	} else {
		closestart = 0;
	}
	return FALSE;
}



