/*----------------------------------------------------------------------------------*/
#define _KM_USE_VERTEX_MACRO_L4_
#include <shinobi.h>
#include <kamui2.h>
#include <km2util.h>
#include <string.h>
#include <stdlib.h>
#include "dispstrex.h"
#include "command.h"
#include "km2kamuix.h"
#include "math.h"
#include "clock.h"
#include "arrow.h"

static KMSTRIPHEAD kmiStripHead03_0;
static KMSTRIPHEAD kmiStripHead03_1;
static PROCESSHANDLE hProcessClock;
static KMSURFACEDESC sTexSurface0;
static KMSURFACEDESC sTexSurface1;
static int busy;

#define DEG2RAD(x) ((float)(x)/180.f*3.14159f)
/*----------------------------------------------------------------------------------*/
void ClockCommandExec(PKMVERTEXBUFFDESC pBufferDesc)
{
	SYS_RTC_DATE date;
	KMRECT		Rect;
	float		Width,Height,Left,Top;
	float		cx,cy,sx,sy,ax,ay,r0,r1;

	GetClientRect(hProcessClock, &Rect);
	Left  = (float)Rect.nXmin;
	Top   = (float)Rect.nYmin;
	Width = (float)(Rect.nXmax - Rect.nXmin);
	Height= (float)(Rect.nYmax - Rect.nYmin);
	cx  = Left + Width  / 2.f;
	cy  = Top  + Height / 2.f;

	kmxxGetCurrentPtr(pBufferDesc);
	kmxxStartStrip(pBufferDesc,&kmiStripHead03_0);

	kmxxSetVertex_3(KM_VERTEXPARAM_NORMAL		, Left      , Top       , 10.f, 0.f,0.f, 0xffffffff, 0);
	kmxxSetVertex_3(KM_VERTEXPARAM_NORMAL		, Left      , Top+Height, 10.f, 0.f,1.f, 0xffffffff, 0);
	kmxxSetVertex_3(KM_VERTEXPARAM_NORMAL		, Left+Width, Top       , 10.f, 1.f,0.f, 0xffffffff, 0);
	kmxxSetVertex_3(KM_VERTEXPARAM_ENDOFSTRIP	, Left+Width, Top+Height, 10.f, 1.f,1.f, 0xffffffff, 0);
	kmEndStrip( pBufferDesc );

	syRtcGetDate( &date );

	kmxxStartStrip(pBufferDesc,&kmiStripHead03_1);
	r0 = DEG2RAD(-date.second*6    );
	r1 = DEG2RAD(-date.second*6+90 );
	sx = sin(r0) * Width  * 0.47f;
	sy = cos(r0) * Height * 0.47f;
	ax = sin(r1) * 1.8f;
	ay = cos(r1) * 1.8f;
	kmxxSetVertex_3(KM_VERTEXPARAM_NORMAL		, cx+ax   , cy+ay     , 300.f, 0.f,1.f, 0, 0);
	kmxxSetVertex_3(KM_VERTEXPARAM_NORMAL		, cx-ax   , cy-ay     , 300.f, 1.f,1.f, 0, 0);
	kmxxSetVertex_3(KM_VERTEXPARAM_NORMAL		, cx-sx+ax, cy-sy+ay  , 300.f, 0.f,0.f, 0, 0);
	kmxxSetVertex_3(KM_VERTEXPARAM_ENDOFSTRIP	, cx-sx-ax, cy-sy-ay  , 300.f, 1.f,0.f, 0, 0);

	r0 = DEG2RAD(-(date.minute*6+date.second/10)    );
	r1 = DEG2RAD(-(date.minute*6+date.second/10)+90 );
	sx = sin(r0) * Width  * 0.35f;
	sy = cos(r0) * Height * 0.35f;
	ax = sin(r1) * 2.4f;
	ay = cos(r1) * 2.4f;
	kmxxSetVertex_3(KM_VERTEXPARAM_NORMAL		, cx+ax   , cy+ay     , 300.f, 0.f,1.f, 0, 0);
	kmxxSetVertex_3(KM_VERTEXPARAM_NORMAL		, cx-ax   , cy-ay     , 300.f, 1.f,1.f, 0, 0);
	kmxxSetVertex_3(KM_VERTEXPARAM_NORMAL		, cx-sx+ax, cy-sy+ay  , 300.f, 0.f,0.f, 0, 0);
	kmxxSetVertex_3(KM_VERTEXPARAM_ENDOFSTRIP	, cx-sx-ax, cy-sy-ay  , 300.f, 1.f,0.f, 0, 0);

	r0 = DEG2RAD(-(date.hour*30+date.minute/2)    );
	r1 = DEG2RAD(-(date.hour*30+date.minute/2)+90 );
	sx = sin(r0) * Width  * 0.20f;
	sy = cos(r0) * Height * 0.20f;
	ax = sin(r1) * 3.2f;
	ay = cos(r1) * 3.2f;
	kmxxSetVertex_3(KM_VERTEXPARAM_NORMAL		, cx+ax   , cy+ay     , 300.f, 0.f,1.f, 0, 0);
	kmxxSetVertex_3(KM_VERTEXPARAM_NORMAL		, cx-ax   , cy-ay     , 300.f, 1.f,1.f, 0, 0);
	kmxxSetVertex_3(KM_VERTEXPARAM_NORMAL		, cx-sx+ax, cy-sy+ay  , 300.f, 0.f,0.f, 0, 0);
	kmxxSetVertex_3(KM_VERTEXPARAM_ENDOFSTRIP	, cx-sx-ax, cy-sy-ay  , 300.f, 1.f,0.f, 0, 0);

	kmEndStrip( pBufferDesc );
	kmxxReleaseCurrentPtr(pBufferDesc);
}
/*----------------------------------------------------------------------------------*/
void ClockCommand(int argc, char *argv[])
{
	KMSTRIPCONTEXT CTX;

	kmCreateTextureSurface( &sTexSurface0, 128,128, KM_TEXTURE_VQ|KM_TEXTURE_RGB565);
	kmCreateTextureSurface( &sTexSurface1,  16,16 , KM_TEXTURE_TWIDDLED|KM_TEXTURE_ARGB4444);
	kmLoadTexture( &sTexSurface0, clock );
	kmLoadTexture( &sTexSurface1, arrow );
	InitStripContext03( &CTX, &kmiStripHead03_0, &sTexSurface0);
	InitStripContext03( &CTX, &kmiStripHead03_1, &sTexSurface1);

	kmChangeStripListType( &kmiStripHead03_1, KM_TRANS_POLYGON );
	kmChangeStripBlendingMode( &kmiStripHead03_1, KM_IMAGE_PARAM1, KM_SRCALPHA, KM_INVSRCALPHA);
	kmChangeStripUseAlpha( &kmiStripHead03_1,  KM_IMAGE_PARAM1, KM_TRUE);
	kmChangeStripClampUV( &kmiStripHead03_1,  KM_IMAGE_PARAM1, KM_CLAMP_UV);
	kmChangeStripSuperSampleMode( &kmiStripHead03_1,  KM_IMAGE_PARAM1, KM_TRUE);

	SetWindowArea(hProcessClock, 10, 20, 128, 128);
	ActivateProcess(hProcessClock);
}
/*----------------------------------------------------------------------------------*/
void ClockMessage(PKMVOID hProcess, PDCXMESSAGE pMessage )
{
	switch (pMessage->eType) {
	case DCXMESSAGE_DESTROY_WINDOW:
		kmFreeTexture( &sTexSurface0 );
		kmFreeTexture( &sTexSurface1 );
		busy = 0;
		break;
	case DCXMESSAGE_DISPLAY_HELP:
		strcpy( pMessage->pContext, "Analog Clock" );
		break;
	}
}
/*----------------------------------------------------------------------------------*/
void InitClockCommand(void)
{
	hProcessClock = RegisterCommand(
		ClockCommand,
		(PKMCALLBACKFUNC)ClockCommandExec,
		NULL,
		"clock",
		PROCESSTYPE_W_DRAW
	);

	SetMessageCallback( hProcessClock, ClockMessage );
	busy = 0;
}
/*----------------------------------------------------------------------------------*/