/*************************************************************************************************/
/*!
   	@file		main.h
	@author 	Fanzo
 	@date 		2008/5/13
*/
/*************************************************************************************************/
#pragma		once

///////////////////////////////////////////////////////////////////////////////////////////////////
//include files
#include	<windows.h>
#include	<math.h>

using namespace icubic;
using namespace shared;


///////////////////////////////////////////////////////////////////////////////////////////////////
// preprocessor deifne

#define create_item( obj_name , title_obj_name , title , view_height )																								\
	title_obj_name->SetString( title );																																\
	title_obj_name->Create( ( rViewParentCtrl )( reference )this_object() , irect( ivector2( m_es , y ) , isize( p->m_rect.Width() - m_es * 2 , m_ts ) ) );			\
	y += title_obj_name->GetRect().Height();																														\
	obj_name->Create( ( rViewParentCtrl )( reference )this_object() , irect( ivector2( m_es , y ) , isize( p->m_rect.Width() - m_es * 2 , view_height ) ) );		\
	obj_name->SetMsgCallback( ( rControlMsg )( reference )this_object() , 0 );																						\
	y += obj_name->GetRect().Size().height;

#define create_item_w( obj_name , title_obj_name , title , view_width )																								\
	title_obj_name->SetString( title );																																\
	title_obj_name->Create( ( rViewParentCtrl )( reference )this_object() , irect( ivector2( x , m_es ) , isize( view_width , m_ts ) ) );							\
	obj_name->Create( ( rViewParentCtrl )( reference )this_object() , irect( ivector2( x , title_obj_name->GetRect().Height() + m_es ) , isize( view_width , p->m_rect.Height() - title_obj_name->GetRect().Height() - m_es * 2 ) ) );		\
	obj_name->SetMsgCallback( ( rControlMsg )( reference )this_object() , 0 );																						\
	x += view_width;

///////////////////////////////////////////////////////////////////////////////////////////////////
// type define

///////////////////////////////////////////////////////////////////////////////////////////////////
// classes define

/**************************************************************************************************
"DispCfgView" class 
**************************************************************************************************/
class DispCfgView : public CheckCfgView
{
// variable member
private:
// public functions
public:
//=================================================================================================
DispCfgView()
{
	SetCheckNum( 3 );
	SetString( 0 , L"disp rect clip" );
	SetString( 1 , L"disp clip" );
	SetString( 2 , L"disp handle" );
	SetValue( 1 , false );
}
//=================================================================================================
bool GetClipRectState()
{
	return GetValue( 0 );
}
//=================================================================================================
bool GetClipState()
{
	return GetValue( 1 );
}
//=================================================================================================
bool GetHandleState()
{
	return GetValue( 2 );
}
};
/**************************************************************************************************
"AlphaCfgView" class 
**************************************************************************************************/
class AlphaCfgView : public View , public ISliderMsg
{
	query_begin()
	iface_hook( ISliderMsg , ISliderMsg_IID )
	query_end( View )
	
	msg_view_map_begin()
	msg_view_hook( Create , OnCreate )
	msg_view_hook( Update , OnUpdate )
	msg_view_map_end( View )

// variable member
private:
	instance<Slider>					m_alpha;
	instance<Font>					m_font;
	
	rControlMsg							m_msg;
	int									m_id;
	
	const int							m_sh;
	const int							m_info_w;
	
// ctrlmsg functions
private:
//=================================================================================================
void cb_call ValueChanged_slider
		(
		int		id
		)
{
	RequireUpdate( irect( ivector2( 0 , 0 ) , GetRect().Size() ) , false );
	iControlMsg	ck = m_msg.lock();
	if( ck == true )
		ck->ValueChanged_controlmsg( m_id );
}
// msg functions
protected:
//=================================================================================================
void OnCreate
		(
		Create_ViewPM*	p
		)
{
	m_alpha->Create
			( 
			( rViewParentCtrl )( reference )this_object() , 
			irect( ivector2( 0 , 0 ) , isize( p->m_rect.Size().width - m_info_w , m_sh ) )
			);
	m_alpha->SetValue( 1.0f );
	m_alpha->SetMsgCallback( ( rSliderMsg )( reference )this_object() , 100 );
}
//=================================================================================================
void OnUpdate
		(
		Update_ViewPM*	p
		)
{
	wchar_t	text[ 256 ];
	cb_swprintf( text , L"A:%d" , GetValue() );
	DrawText( (iSurfaceDest)p->m_surface , fvector2( ( float )( GetRect().Size().width - m_info_w ) , ( float )(  m_sh / 2 ) ) , text , ( iFont )m_font , rgb(0,0,0) , Center_TextAlign );
}
// public functions
public:
//=================================================================================================
AlphaCfgView() : m_sh( 15 ) , m_info_w( 30 ) , m_id( 0 )
{
	cb_verify( true == m_font->Create( fsize( 0.0f , 7.0f ) , L"Tahoma" , Roman_FontCharsetType , 400 , false ) );
}
//=================================================================================================
void SetMsgCallback
		(
		rControlMsg&		msg , 
		int					id
		)
{
	m_msg	= msg;
	m_id	= id;
}
//=================================================================================================
uint8 GetValue()
{
	return ( uint8 )( m_alpha->GetValue() * 255.0f );
}
};

/**************************************************************************************************
"Control1View" class 
**************************************************************************************************/
class Control1View : public View , public IControlMsg
{
	query_begin()
	iface_hook( IControlMsg , IControlMsg_IID )	
	query_end( View )

	msg_view_map_begin()
	msg_view_hook( Create , OnCreate )
	msg_view_hook( Update , OnUpdate )
	msg_view_map_end( View )

// variable member
public:
	instance<SeparateView>			m_alpha_t;
	instance<AlphaCfgView>			m_alpha;

	instance<SeparateView>			m_text_t;
	instance<TextSampleCfgView>		m_text;
	
	instance<SeparateView>			m_align_t;
	instance<TextAlignCfgView>		m_align;

	instance<SeparateView>			m_disp_state_t;
	instance<DispCfgView>			m_disp_state;
	instance<SeparateView>			m_processor_t;
	instance<ProcessorCfgView>		m_processor;


private:
	rControlMsg							m_msg;
	int									m_id;
	
	const int							m_es;
	const int							m_ts;
	
// "IControlMsg" msg	
//=================================================================================================
void cb_call ValueChanged_controlmsg
		(
		int		id
		)
{
	iControlMsg	ck = m_msg.lock();
	if( ck == true )
		ck->ValueChanged_controlmsg( m_id );
}
// msg functions
protected:
//=================================================================================================
void OnCreate
		(
		Create_ViewPM*	p
		)
{
	int		y = m_es;
	create_item( m_alpha , m_alpha_t , L"alpha" , 20 );
	create_item( m_text , m_text_t , L"text" , 30 );
	create_item( m_align , m_align_t , L"align" , 95 );
	create_item( m_disp_state , m_disp_state_t , L"disp switch" , 45 );
	create_item( m_processor , m_processor_t , L"processor" , 20 );
}
//=================================================================================================
void OnUpdate
		(
		Update_ViewPM*	p
		)
{
	DrawConfigBack( (iSurfaceDest)p->m_surface , GetRect().Size() );
}

// public functions
public:
//=================================================================================================
Control1View() : m_id( 0 ) , m_es( 5 ) , m_ts( 11 )
{
}
//=================================================================================================
void SetMsgCallback
		(
		rControlMsg&		msg , 
		int					id
		)
{
	m_msg	= msg;
	m_id	= id;
}
};
/**************************************************************************************************
"FontView" class 
**************************************************************************************************/
class FontView : public View , public IControlMsg
{
	query_begin()
	iface_hook( IControlMsg , IControlMsg_IID )	
	query_end( View )

	msg_view_map_begin()
	msg_view_hook( Create , OnCreate )
	msg_view_hook( Update , OnUpdate )
	msg_view_map_end( View )

// variable member
public:
	instance<SeparateView>			m_font_t;
	instance<FontCfgView_gp>		m_font;

private:
	rControlMsg						m_msg;
	int								m_id;
	
	const int						m_es;
	const int						m_ts;
	
// "IControlMsg" msg	
//=================================================================================================
void cb_call ValueChanged_controlmsg
		(
		int		id
		)
{
	iControlMsg	ck = m_msg.lock();
	if( ck == true )
		ck->ValueChanged_controlmsg( m_id );
}
// msg functions
protected:
//=================================================================================================
void OnCreate
		(
		Create_ViewPM*	p
		)
{
	int		y = m_es;
	create_item( m_font , m_font_t , L"font" , 300 );
}
//=================================================================================================
void OnUpdate
		(
		Update_ViewPM*	p
		)
{
	DrawConfigBack( (iSurfaceDest)p->m_surface , GetRect().Size() );
}

// public functions
public:
//=================================================================================================
FontView() : m_id( 0 ) , m_es( 5 ) , m_ts( 11 )
{
}
//=================================================================================================
void SetMsgCallback
		(
		rControlMsg&		msg , 
		int					id
		)
{
	m_msg	= msg;
	m_id	= id;
}
};
/**************************************************************************************************
"Coord" class 
**************************************************************************************************/
class Coord
{
// variable member
private:
	iSubCoordLayer	m_coord;
	fvector2		m_coord_vec;
	const float		m_coord_len;
	const float		m_handle_r;
	
	// brush/pen
	iFont_gp		m_font;
	iPaint_gp		m_brush;
	iPen_gp			m_pen;
	
// public functions
public:
//=================================================================================================
Coord() : m_coord_len( 100.0f ) , m_coord_vec( 100.0f , 100.0f ) , m_handle_r( 5.0f )
{
	m_brush		= CreatePaintSolid( rgba( 0 , 0 , 0 , 255 ) );
	m_pen		= CreatePenStroke( CreateJoint( Bevel_JointType_gp ) , CreateCap( Flat_CapType_gp ) , CreateCapArrow( 4.0f , 3.5f ) );
	m_font		= CreateFont( fsize( 0.0f , 10.0f ) , L"Tahoma" , Roman_FontCharsetType );
}
//=================================================================================================
iCoordLayer SetCoord
		(
		iCoordLayer&	coord
		)
{
	m_coord			= coord->AddChild( (iCoordLayer)instance<SubCoordLayer>() );
	m_coord_vec		= fvector2( m_coord_len , m_coord_len );
	m_coord->m_unit	= unit_ip( value_ip::px , 1.0f , 1.0f );
	m_coord->m_org	= point_iplr( value_iplr::px , fvector2( 0.0f , 0.0f ) );
	return m_coord;
}
//=================================================================================================
void SetPoint
		(
		int				off , 
		const fvector2&	pnt
		)
{
	if( off == 0 || off == 1 )
	{
		Coord_ld	coord;
		if( false == m_coord->GetCoord_ld( &coord , 0 , 0 ) )
			return;
		fvector2	p = coord.PDtoL( pnt );
		m_coord_vec.m[ off ] = p.m[ off ];
		
		int		c_off , c_num = m_coord->GetChildnum();
		for( c_off = 0 ; c_off < c_num ; c_off++ )
		{
			iSubCoordLayer	c = m_coord->GetChild( c_off );
			if( c == true )
				c->m_unit	= unit_ip( value_ip::inch , 0.03937f * m_coord_vec.x / m_coord_len , 0.03937f * m_coord_vec.y / m_coord_len );
		}
	}
	else if( off == 2 )
	{
		iCoordLayer	parent = m_coord->GetParent();
		if( parent == false )
			return;
		Coord_ld	coord;
		if( false == parent->GetCoord_ld( &coord , 0 , 0 ) )
			return;
		fvector2	p	= coord.PDtoP( pnt );
		m_coord->m_org	= point_iplr( value_iplr::px , p );
	}
}
//=================================================================================================
bool Search
		(
		int*			off , 
		const fvector2&	pnt
		)
{
	Coord_ld	coord;
	if( false == m_coord->GetCoord_ld( &coord , 0 , 0 ) )
		return false;

	fvector2	p	= coord.PDtoL( pnt );
	frect		r( p.x - m_handle_r , p.y - m_handle_r , p.x + m_handle_r , p.y + m_handle_r );
	if( true == r.IsInside( fvector2( m_coord_vec.x , 0.0f ) ) )
	{
		*off	= 0;
		return true;
	}
	if( true == r.IsInside( fvector2( 0.0f , m_coord_vec.y ) ) )
	{
		*off	= 1;
		return true;
	}
	if( true == r.IsInside( fvector2( 0.0f , 0.0f ) ) )
	{
		*off	= 2;
		return true;
	}
	return false;
}
//=================================================================================================
void Draw
		(
		iGraphics_gp&	g
		)
{
	SaveAttr	save( g );
	faffine		ltod	= m_coord->LtoD();
	g->SetStrokePaint( m_brush );
	g->SetStrokePen( m_pen );
	g->SetStrokeWidth( 1.0f );
	g->SetStrokeClose( false );
	g->SetFont( m_font );
	fvector2	p[] = { -fvector2( m_coord_vec.x , 0.0f ) , fvector2( m_coord_vec.x , 0.0f ) , -fvector2( 0.0f , m_coord_vec.y ) , fvector2( 0.0f , m_coord_vec.y ) };
	g->StrokeLine( 2 , &p[0] , faffine() , ltod );
	g->StrokeLine( 2 , &p[2] , faffine() , ltod );
		
	wchar_t		buf[256];
	g->SetTextAlign( m_coord_vec.x < 0.0f ? Right_TextAlignHorz_gp : Left_TextAlignHorz_gp , Center_TextAlignVert_gp );
	cb_swprintf( buf , L"%.2f[mm]" , m_coord_vec.x / m_coord_len );
	g->DrawText( buf , wcslen( buf ) , ltod.Transform( fvector2( m_coord_vec.x + ( m_coord_vec.x < 0.0f ? -5.0f : 5.0f ) , 0.0f ) ) , rgba( 0 , 0 , 0 ) , 0 );

	g->SetTextAlign( Center_TextAlignHorz_gp , m_coord_vec.y < 0.0f ? Bottom_TextAlignVert_gp : Top_TextAlignVert_gp );
	cb_swprintf( buf , L"%.2f[mm]" , m_coord_vec.y / m_coord_len );
	g->DrawText( buf , wcslen( buf ) , ltod.Transform( fvector2( 0.0f , m_coord_vec.y + ( m_coord_vec.y < 0.0f ? -5.0f : 5.0f ) ) ) , rgba( 0 , 0 , 0 ) , 0 );
}
};
/**************************************************************************************************
"MainView" class 
**************************************************************************************************/
class MainView : public View , public IControlMsg
{
	query_begin()
	iface_hook( IControlMsg , IControlMsg_IID )
	query_end( View )

	msg_view_map_begin()
	msg_view_hook( Create , OnCreate )
	msg_view_hook( Update , OnUpdate )
	msg_view_hook( Size , OnSize )
	msg_view_hook( LDragStart , OnLDragStart )
	msg_view_hook( LDrag , OnLDrag )
	msg_view_hook( LDragEnd , OnLDragEnd )
	msg_view_hook( LDragCancel , OnLDragCancel )
	msg_view_map_end( View )

// variable member
private:
	instance<Control1View>	m_control1;
	instance<FontView>		m_font;
	instance<TimeCfgView>	m_time;
	instance<Graphics_gp>	m_graphics;

	// edit
	int							m_edit_type;
	int							m_edit_pnt;
	frect						m_rect[1];
	fvector2					m_pnt[8];

	// coord
	iDeviceCoordLayer			m_root;
	Coord						m_coord;
	iSubCoordLayer				m_coord_graphics;
	
	// clip
	instance<Path>				m_path_clip;

	// brush/pen
	iPaint_gp					m_brush_back;
	iPaint_gp					m_brush_coord;
	iPaint_gp					m_brush_handle;
	iPaint_gp					m_brush_handle_lb;
	iPaint_gp					m_brush_clip;
	iPaint_gp					m_brush_clip_rect;
	iPaint_gp					m_brush_coord_source;
	iPen_gp						m_pen_coord;
	iPen_gp						m_pen_handle;

	// coord
	instance<Path>				m_coord_path;

	const float					m_handle_r;

// private functions
private:
//=================================================================================================
int GetPointNum()
{
	return _countof( m_rect ) * 2 + _countof( m_pnt );
}
//=================================================================================================
fvector2 GetPoint_d
		(
		int				off
		)
{
	if( off < _countof( m_rect ) * 2 )
	{
		int			roff	= off / 2;
		int			poff	= off % 2;
		if( poff == 0 )
			return m_root->CtoC( value_ipl::logical , value_ipl::logical , (iCoordLayer)m_coord_graphics ).Transform( m_rect[roff].Min() );
		else
			return m_root->CtoC( value_ipl::logical , value_ipl::logical , (iCoordLayer)m_coord_graphics ).Transform( m_rect[roff].Max() );
	}
	else
	{
		return m_root->CtoC( value_ipl::logical , value_ipl::logical , (iCoordLayer)m_coord_graphics ).Transform( m_pnt[ off - _countof( m_rect ) * 2 ] );
	}
}
//=================================================================================================
fvector2 GetPoint_l
		(
		int				off
		)
{
	if( off < _countof( m_rect ) * 2 )
	{
		int			roff	= off / 2;
		int			poff	= off % 2;
		if( poff == 0 )
			return m_rect[roff].Min();
		else
			return m_rect[roff].Max();
	}
	else
	{
		return m_pnt[ off - _countof( m_rect ) * 2 ];
	}
}
//=================================================================================================
void SetPoint
		(
		int				off , 
		fvector2		pnt
		)
{
	pnt	= m_coord_graphics->CtoC( value_ipl::logical , value_ipl::logical , (iCoordLayer)m_root ).Transform( pnt );
	if( off < _countof( m_rect ) * 2 )
	{
		int			roff	= off / 2;
		int			poff	= off % 2;
		if( poff == 0 )
		{
			m_rect[roff].xmin = pnt.x;
			m_rect[roff].ymin = pnt.y;
		}
		else
		{
			m_rect[roff].xmax = pnt.x;
			m_rect[roff].ymax = pnt.y;
		}
	}
	else
	{
		m_pnt[ off - _countof( m_rect ) * 2 ]	= pnt;
	}
}	
//=================================================================================================
bool Search
		(
		int*			pntoff , 
		const fvector2&	pnt
		)
{
	fvector2	pp	= m_coord_graphics->CtoC( value_ipl::logical , value_ipl::logical , (iCoordLayer)m_root ).Transform( pnt );
	int		off , num = GetPointNum();
	for( off = 0 ; off < num ; off++ )
	{
		fvector2	p	= GetPoint_l( off );
		frect		r( p.x - m_handle_r , p.y - m_handle_r , p.x + m_handle_r , p.y + m_handle_r );
		if( true == r.IsInside( pp ) )
		{
			*pntoff	= off;
			return true;
		}
	}
	return false;
}
//=================================================================================================
void DrawHandleClipRect
		(
		iGraphics_gp&	g
		)
{
	SaveAttr	save( g );
	faffine		ltod = m_coord_graphics->LtoD();
	g->SetPaint( m_brush_clip_rect );
	g->SetStrokePaint( m_brush_clip_rect );
	g->SetStrokePen( m_pen_handle );
	g->SetStrokeWidth( 0.5f );
	g->SetStrokeClose( true );

	// stroke
	fvector2	lt		= m_rect[0].Min() , rb = m_rect[0].Max();
	fvector2	s[4]	= { lt , fvector2( rb.x , lt.y ) , rb , fvector2( lt.x , rb.y ) };
	g->StrokeLine( _countof( s ) , s , faffine() , ltod );
	g->PaintCircle( lt , m_handle_r , m_handle_r , ltod );
	g->PaintCircle( rb , m_handle_r , m_handle_r , ltod );
}
//=================================================================================================
void DrawHandle
		(
		iGraphics_gp&	g
		)
{
	SaveAttr	save( g );
	faffine		ltod	= m_coord_graphics->LtoD();
	g->SetPaint( m_brush_handle );
	g->PaintCircle( m_pnt[0] , m_handle_r , m_handle_r , ltod );
}
//=================================================================================================
void DrawHandleClip
		(
		iGraphics_gp&	g
		)
{
	SaveAttr	save( g );
	faffine		ltod	= m_coord_graphics->LtoD();

	g->SetStrokePaint( m_brush_clip );
	g->SetPaint( m_brush_clip );
	g->SetStrokePen( m_pen_handle );
	g->SetStrokeWidth( 0.5f );
	g->SetStrokeClose( true );
	g->StrokePath( (iPathLogicInfo)m_path_clip , faffine() , ltod );

	int	pntoff , pntnum = _countof( m_pnt );
	for( pntoff = 1 ; pntoff < pntnum ; pntoff++ )
	{
		g->PaintCircle( m_pnt[pntoff] , m_handle_r , m_handle_r , ltod );
	}
}
//=================================================================================================
void SetClip
		(
		iGraphics_gp&	g , 
		const faffine&	ltod
		)
{
	m_path_clip->Reset();
	m_path_clip->Move( m_pnt[1] , faffine() , true );
	m_path_clip->Line( m_pnt[2] );
	m_path_clip->BezierQ( m_pnt[3] , m_pnt[4] );
	m_path_clip->BezierC( m_pnt[5] , m_pnt[6] , m_pnt[7] );
	g->SetClip( (iPathLogicInfo)m_path_clip , ltod );
}

// callback functions
private:
//=================================================================================================
void cb_call ValueChanged_controlmsg
		(
		int		id
		)
{
	RequireUpdate( irect( ivector2( 0 , 0 ) , GetRect().Size() ) , false );
}
// msg functions
private:
//=================================================================================================
void OnCreate
		(
		Create_ViewPM*	p
		)
{
	m_control1->Create( ( rViewParentCtrl )( reference )this_object() , irect( ivector2( 1 , 1 ) , isize( 130 , 300 ) ) );
	m_control1->SetMsgCallback( ( rControlMsg )( reference )this_object() , 100 );

	m_font->Create( ( rViewParentCtrl )( reference )this_object() , irect( ivector2( 1 , p->m_rect.Size().height - 1 - 150 ) , isize( 475 , 140 ) ) );
	m_font->SetMsgCallback( ( rControlMsg )( reference )this_object() , 0 );

	m_time->Create( ( rViewParentCtrl )( reference )this_object() , irect( ivector2( 135 , 0 ) , isize( 300 , 16 ) ) );
	m_time->SetMsgCallback( ( rControlMsg )( reference )this_object() , 0 );
}
//=================================================================================================
void OnUpdate
		(
		Update_ViewPM*	p
		)
{
	// set surface
	m_graphics->SetSurface( p->m_surface );
	m_root->m_dpi = p->m_surface->GetDestDPI();
	m_root->m_view= p->m_surface->GetDestSize();
	
	// back
	m_graphics->SetPaint( m_brush_back );
	m_graphics->PaintRect( 0 , faffine() );
	
	// misc
	m_graphics->SetAntialias( x4_antialias );
	m_graphics->SetAlpha( m_control1->m_alpha->GetValue() );
	
	// coord org
	m_coord.Draw( (iGraphics_gp)m_graphics );

	// draw
	{
		SaveAttr	save( (iGraphics_gp)m_graphics );
		faffine		ltod	= m_coord_graphics->LtoD();

		fsize	fs;
		m_graphics->SetFont( m_font->m_font->GetValue( &fs ) );
		m_graphics->SetTextAlign( m_control1->m_align->GetTextAlignHorz() , m_control1->m_align->GetTextAlignVert() );
		rgba		c		= m_font->m_font->GetColor();
		wstring		text	= m_control1->m_text->GetValue();
		frect		cp		= frect( ltod.Transform( m_rect[0].Min() ) , ltod.Transform( m_rect[0].Max() ) ).Normalize();
		
		// clip
		if( m_control1->m_disp_state->GetClipState() == true )
			SetClip( (iGraphics_gp)m_graphics , ltod );

		m_time->BeginMeasure();
		m_graphics->DrawText( text.c_str() , text.length() , ltod.Transform( m_pnt[0] ) , c , ( m_control1->m_disp_state->GetClipRectState() == true ) ? &cp : 0 );
		m_time->EndMeasure();
		
		// clip
		m_graphics->ReleaseClip();
	}
	if( m_control1->m_disp_state->GetClipState() == true && m_control1->m_disp_state->GetHandleState() == true )
		DrawHandleClip( (iGraphics_gp)m_graphics );
	if( m_control1->m_disp_state->GetClipRectState() == true && m_control1->m_disp_state->GetHandleState() == true )
		DrawHandleClipRect( (iGraphics_gp)m_graphics );
	if( m_control1->m_disp_state->GetHandleState() == true )
		DrawHandle( (iGraphics_gp)m_graphics );
	m_graphics->ReleaseSurface();
}
//=================================================================================================
void OnSize
		(
		Size_ViewPM*	p
		)
{
	m_root->m_view	= p->m_rect.Size();
	m_font->Move( irect( ivector2( 1 , p->m_rect.Size().height - 150 - 1 ) , isize( 475 , 140 ) ) );
}
//=================================================================================================
void OnLDragStart
		(
		LDragStart_ViewPM*	p
		)
{
	isize	size = GetRect().Size();
	if( m_control1->m_disp_state->GetHandleState() == false )
		return;
	else if( true == Search( &m_edit_pnt , p->m_pos ) )
		m_edit_type	= 0;
	else if( true == m_coord.Search( &m_edit_pnt , p->m_pos ) )
		m_edit_type = 2;
}
//=================================================================================================
void OnLDrag
		(
		LDrag_ViewPM*	p
		)
{
	if( m_edit_pnt == -1 )
		return;
	else if( m_edit_type == 2 )
		m_coord.SetPoint( m_edit_pnt , p->m_pos );
	else if( m_edit_type == 0 )
		SetPoint( m_edit_pnt , p->m_pos );
	RequireUpdate( irect( ivector2( 0 , 0 ) , GetRect().Size() ) , false );
}
//=================================================================================================
void OnLDragEnd
		(
		LDragEnd_ViewPM*	p
		)
{
	m_edit_type	= -1;
	m_edit_pnt = -1;
}
//=================================================================================================
void OnLDragCancel
		(
		LDragCancel_ViewPM*	p
		)
{
	m_edit_type	= -1;
	m_edit_pnt = -1;
}
// public functions
public:
//=================================================================================================
MainView() : 
		m_handle_r( 1.0f ) , 
		m_edit_type( -1 ) , 
		m_edit_pnt( -1 )
{
	m_brush_back		= CreatePaintSolid( rgba(255 , 255 , 235 ) );
	m_brush_coord		= CreatePaintSolid( rgba( 0 , 0 , 0 , 255 ) );
	m_brush_handle		= CreatePaintSolid( rgba( 121 , 121 , 40 ) );
	m_brush_handle_lb	= CreatePaintSolid( rgba( 121 , 40 , 121 ) );
	m_pen_coord			= CreatePenStroke( CreateJoint( Bevel_JointType_gp ) , CreateCap( Flat_CapType_gp ) , CreateCapArrow( 4.0f , 3.5f ) );
	m_brush_clip		= CreatePaintSolid( rgba(200 , 100 , 50 ) );
	m_brush_clip_rect	= CreatePaintSolid( rgba(50 , 200 , 100 ) );
	m_pen_handle		= CreatePenStroke();
	m_brush_coord_source= CreatePaintSolid( rgba(50,50,160) );

	m_root						= (iDeviceCoordLayer)instance<DeviceCoordLayer>();
	iSubCoordLayer	center		= m_root->AddChild( (iCoordLayer)instance<SubCoordLayer>() );
	center->m_unit	= unit_ip( value_ip::px , 1.0f , 1.0f );
	center->m_org	= point_iplr( value_iplr::ratio , fvector2( 0.5f , 0.4f ) );

	iCoordLayer		t			= m_coord.SetCoord( (iCoordLayer)center );
	m_coord_graphics			= t->AddChild( (iCoordLayer)instance<SubCoordLayer>() );
	m_coord_graphics->m_unit	= unit_ip( value_ip::inch , 0.03937f , 0.03937f );
	m_coord_graphics->m_org		= point_iplr( value_iplr::ratio , fvector2( 0.0f , 0.0f ) );

	m_rect[0]	= frect( fvector2( -25.0f , -25.0f ) , fsize( 50.0f , 50.0f ) );
	m_pnt[0]	= fvector2( -22.0f , -22.0f );
	m_pnt[1]	= fvector2( -30.0f , 0.0f );
	m_pnt[2]	= fvector2( -30.0f , -30.0f );
	m_pnt[3]	= fvector2( 30.0f , -30.0f );
	m_pnt[4]	= fvector2( 30.0f , 0.0f );
	m_pnt[5]	= fvector2( 30.0f , 30.0f );
	m_pnt[6]	= fvector2( 0.0f , 30.0f );
	m_pnt[7]	= fvector2( -30.0f , 30.0f );
}
//=================================================================================================
bool Initialize()
{
	return true;
}
};

///////////////////////////////////////////////////////////////////////////////////////////////////
// global variable define

///////////////////////////////////////////////////////////////////////////////////////////////////
// global functions define





