#include <windows.h>
#include "PajaTypes.h"
#include "ColorC.h"
#include "res\resource.h"
#include <math.h>
#include "FlareImageDialog.h"
#include <string>
#include <stdio.h>
#include "ColorCommonDialogC.h"
#include "DemoInterfaceC.h"
#include "FlareRendererC.h"
#include "ImportableImageI.h"

using namespace PajaTypes;
using namespace Import;
using namespace PajaSystem;
using namespace PluginClass;


// module handle
extern HINSTANCE	g_hInstance;


//
// helpers
//

inline
ColorC
COLOREF_to_color( COLORREF rColRef )
{
	ColorC	rCol;
	rCol.convert_from_uint8( GetRValue( rColRef ), GetGValue( rColRef ), GetBValue( rColRef ) );
	return rCol;
}

inline
COLORREF
color_to_COLOREF( const ColorC& rCol )
{
	return RGB( (int32)(rCol[0] * 255.0f), (int32)(rCol[1] * 255.0f), (int32)(rCol[2] * 255.0f) );
}

inline
void
ScreenToClient( HWND hWnd, LPRECT lpRect )
{
	POINT	rPt;
	rPt.x = lpRect->left;
	rPt.y = lpRect->top;
	ScreenToClient( hWnd, &rPt );
	lpRect->left = rPt.x;
	lpRect->top = rPt.y;

	rPt.x = lpRect->right;
	rPt.y = lpRect->bottom;
	ScreenToClient( hWnd, &rPt );
	lpRect->right = rPt.x;
	lpRect->bottom = rPt.y;
}

inline
void
ClientToScreen( HWND hWnd, LPRECT lpRect )
{
	POINT	rPt;
	rPt.x = lpRect->left;
	rPt.y = lpRect->top;
	ClientToScreen( hWnd, &rPt );
	lpRect->left = rPt.x;
	lpRect->top = rPt.y;

	rPt.x = lpRect->right;
	rPt.y = lpRect->bottom;
	ClientToScreen( hWnd, &rPt );
	lpRect->right = rPt.x;
	lpRect->bottom = rPt.y;
}



//
// DIB class
//


DIBitmapC::DIBitmapC ()
{
	m_pBits = NULL;
	m_hBitmap = NULL;
	m_rSize.cx = 0;
	m_rSize.cy = 0;
}


DIBitmapC::~DIBitmapC ()
{
	destroy();
}

bool
DIBitmapC::create( int32 i32Width, int32 i32Height )
{
	destroy();

	ZeroMemory( &m_rInfo, sizeof( BITMAPINFO ) );

	m_rInfo.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
	m_rInfo.bmiHeader.biWidth = i32Width;
	m_rInfo.bmiHeader.biHeight = i32Height;
	m_rInfo.bmiHeader.biPlanes = 1;
	m_rInfo.bmiHeader.biBitCount = 32; 
	m_rInfo.bmiHeader.biCompression = BI_RGB;
	m_rInfo.bmiHeader.biSizeImage = i32Width * i32Height * 4;
    
	m_hBitmap = CreateDIBSection( NULL, &m_rInfo, DIB_RGB_COLORS, (void **)&m_pBits, NULL, NULL ); 

	if( !m_hBitmap ) {
		m_rSize.cx = 0;
		m_rSize.cy = 0;
		return false;
	}

	m_rSize.cx = i32Width;
	m_rSize.cy = i32Height;

	return true;
}

void
DIBitmapC::destroy ()
{
	if( m_hBitmap )
		DeleteObject( m_hBitmap );
	m_hBitmap = NULL;
	m_rSize.cx = 0;
	m_rSize.cy = 0;
}

inline void
DIBitmapC::paste_to_DC( HDC hDC, int32 x, int32 y )
{
    // x,y - the DC coordinates to start from
	SetDIBitsToDevice( hDC, x, y, m_rSize.cx, m_rSize.cy, 0, 0, 0, m_rSize.cy, m_pBits, &m_rInfo, 0 ); 
}

inline void
DIBitmapC::paste_to_DC( HDC hDC, int32 x, int32 y, int32 w , int32 h )
{
    // x,y - the DC coordinates to start from
	// w,h - the destination width and height
	StretchDIBits( hDC, x, y, w, h, 0, 0, m_rSize.cx, m_rSize.cy, m_pBits, &m_rInfo, DIB_RGB_COLORS, SRCCOPY );
}

int32
DIBitmapC::get_width() const
{
	return m_rSize.cx;
}

int32
DIBitmapC::get_height() const
{
	return m_rSize.cy;
}

UINT*
DIBitmapC::get_bits()
{
	return m_pBits;
}

//
//
// Flare dialog
//
//

FlareDialogC::FlareDialogC( PajaSystem::DemoInterfaceC* pInterface ) :
	m_pInterface( pInterface ),
	m_i32Zoom( 100 ),
	m_i32OffsetX( 0 ),
	m_i32OffsetY( 0 ),
	m_i32OffsetXMax( 0 ),
	m_i32OffsetYMax( 0 ),
	m_i32StartOffsetX( 0 ),
	m_i32StartOffsetY( 0 ),
	m_i32StartX( 0 ),
	m_i32StartY( 0 ),
	m_bPanorate( false ),
	m_pHandle( 0 ),
	m_pOwnerImp( 0 )
{
	// empty
}

FlareDialogC::~FlareDialogC()
{
	// empty
}

void
FlareDialogC::set_bg_color( const ColorC& rColor )
{
	m_rBGColor = rColor;
}

const ColorC&
FlareDialogC::get_bg_color() const
{
	return m_rBGColor;
}

void
FlareDialogC::set_glow_color( const ColorC& rColor )
{
	m_rGlowColor = rColor;
}

const ColorC&
FlareDialogC::get_glow_color() const
{
	return m_rGlowColor;
}

void
FlareDialogC::set_name( const char* szName )
{
	m_sName = szName;
}

const char*
FlareDialogC::get_name() const
{
	return m_sName.c_str();
}

void
FlareDialogC::set_glow_size( float32 f32Size )
{
	m_f32Size = f32Size;
}

float32
FlareDialogC::get_glow_size() const
{
	return m_f32Size;
}

void
FlareDialogC::set_width( uint32 ui32Width )
{
	m_ui32Width = ui32Width;
}

uint32
FlareDialogC::get_width() const
{
	return m_ui32Width;
}

void
FlareDialogC::set_height( uint32 ui32Height )
{
	m_ui32Height = ui32Height;
}

uint32
FlareDialogC::get_height() const
{
	return m_ui32Height;
}

void
FlareDialogC::set_handle( FileHandleC* pHandle )
{
	m_pHandle = pHandle;
}

FileHandleC*
FlareDialogC::get_handle() const
{
	return m_pHandle;
}


void
FlareDialogC::set_owner_importable( ImportableImageI* pImp )
{
	m_pOwnerImp = pImp;
}

bool
FlareDialogC::do_modal()
{
	bool	bRes = DialogBoxParam( g_hInstance, (LPCTSTR)IDD_EDITDIALOG, NULL, (DLGPROC)dlg_proc, (LPARAM)this ) == IDOK ? true : false;
	return bRes;
}

LRESULT CALLBACK
FlareDialogC::dlg_proc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
{
	FlareDialogC*	pClass = 0;


	switch( message ) {
	case WM_INITDIALOG:
		{
			// save the dialog class pointer
			SetWindowLong( hDlg, GWL_USERDATA, (LONG)lParam );

			pClass = reinterpret_cast<FlareDialogC*>( lParam );
			pClass->m_hDlg = hDlg;

			return pClass->on_init_dialog();
		}
		break;


	case WM_DRAWITEM: 
		{
			pClass = reinterpret_cast<FlareDialogC*>(GetWindowLong( hDlg, GWL_USERDATA ) );
			LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT) lParam; 
			return pClass->on_draw_item( lpdis );
		}
		break;

	case WM_PAINT:
		{
			pClass = reinterpret_cast<FlareDialogC*>(GetWindowLong( hDlg, GWL_USERDATA ) );
			PAINTSTRUCT	ps;
			HDC			hDC = BeginPaint( hDlg, &ps );
			pClass->on_paint( hDC );
			EndPaint( hDlg, &ps );
			return TRUE;
		}
		break;

	case WM_COMMAND:
		{
			pClass = reinterpret_cast<FlareDialogC*>(GetWindowLong( hDlg, GWL_USERDATA ) );
			return pClass->on_command( (HWND)lParam, LOWORD( wParam ), HIWORD( wParam ) );
		}
		break;

    case WM_LBUTTONDOWN:
		{
			pClass = reinterpret_cast<FlareDialogC*>(GetWindowLong( hDlg, GWL_USERDATA ) );
			POINT	pt;
			pt.x = (short)LOWORD( lParam );
			pt.y = (short)HIWORD( lParam );
			pClass->on_lbutton_down( pt );
		}
		break;
		
    case WM_LBUTTONUP:
		{
			pClass = reinterpret_cast<FlareDialogC*>(GetWindowLong( hDlg, GWL_USERDATA ) );
			POINT	pt;
			pt.x = (short)LOWORD( lParam );
			pt.y = (short)HIWORD( lParam );
			pClass->on_lbutton_up( pt );
		}
		break;
		
    case WM_MOUSEMOVE:
		{
			pClass = reinterpret_cast<FlareDialogC*>(GetWindowLong( hDlg, GWL_USERDATA ) );
			POINT	pt;
			pt.x = (short)LOWORD( lParam );
			pt.y = (short)HIWORD( lParam );
			pClass->on_mouse_move( pt );
		}
		break;

	case WM_SETCURSOR:
		{
			pClass = reinterpret_cast<FlareDialogC*>(GetWindowLong( hDlg, GWL_USERDATA ) );
			POINT	pt;
			GetCursorPos( &pt );
			ScreenToClient( hDlg, &pt );
			if( pClass->on_set_cursor( pt ) )
				return TRUE;
		}
		break;
		

	case WM_DESTROY:
		break;
	
	}

    return FALSE;
}

BOOL
FlareDialogC::on_init_dialog()
{
	// Get view area
	HWND	hView;
	hView = GetDlgItem( m_hDlg, IDC_VIEW );
	GetClientRect( hView, &m_rViewRect );
	ClientToScreen( hView, &m_rViewRect );
	ScreenToClient( m_hDlg, &m_rViewRect );


	HWND	hComboSize;
	hComboSize = GetDlgItem( m_hDlg, IDC_COMBOSIZE );

	// add selections
	SendMessage( hComboSize, CB_ADDSTRING, 0, (LPARAM)"32x32" );
	SendMessage( hComboSize, CB_ADDSTRING, 0, (LPARAM)"64x64" );
	SendMessage( hComboSize, CB_ADDSTRING, 0, (LPARAM)"128x128" );
	SendMessage( hComboSize, CB_ADDSTRING, 0, (LPARAM)"256x256" );

	int32	i32Selection = 0;

	switch( m_ui32Width ) {
	case 32:
		m_ui32Width = m_ui32Height = 32;
		i32Selection = 0;
		break;
	case 64:
		m_ui32Width = m_ui32Height = 64;
		i32Selection = 1;
		break;
	case 128:
		m_ui32Width = m_ui32Height = 128;
		i32Selection = 2;
		break;
	case 256:
		m_ui32Width = m_ui32Height = 256;
		i32Selection = 3;
		break;
	default:
		m_ui32Width = m_ui32Height = 32;
		i32Selection = 0;
		break;
	}
	SendMessage( hComboSize, CB_SETCURSEL, (WPARAM)i32Selection, 0 );


	char	szVal[32];

	// zoom
	HWND	hEditZoom;
	_snprintf( szVal, 31, "%d%%", m_i32Zoom );
	hEditZoom = GetDlgItem( m_hDlg, IDC_EDITZOOM );
	SetWindowText( hEditZoom, szVal );

	// name
	HWND	hEditName;
	hEditName = GetDlgItem( m_hDlg, IDC_EDITNAME );
	SetWindowText( hEditName, m_sName.c_str() );

	// size
	HWND	hEditSize;
	_snprintf( szVal, 31, "%.1f", m_f32Size );
	hEditSize = GetDlgItem( m_hDlg, IDC_EDITSIZE );
	SetWindowText( hEditSize, szVal );
	// size spinner
	RECT	rRect;
	if( !m_rSpinnerSize.Create( g_hInstance, WS_CHILD | WS_VISIBLE | SPNB_SETBUDDYFLOAT | SPNB_USELIMITS, rRect, m_hDlg, IDC_SPINNER_SIZE ) )
		return FALSE;
	m_rSpinnerSize.SetScale( 1.0f );
	m_rSpinnerSize.SetMinMax( 0, 256 );
	m_rSpinnerSize.SetBuddy( hEditSize, SPNB_ATTACH_RIGHT );

	// update alpha labels
	update_alpha( IDC_STATICGLOWALPHA, m_rGlowColor[3] );
	update_alpha( IDC_STATICBGALPHA, m_rBGColor[3] );


	// set files
	char		szFname[_MAX_FNAME];
	char		szExt[_MAX_EXT];
	int32		i32Idx;
	int32		i32Sel = 0;

	HWND	hComboImage = GetDlgItem( m_hDlg, IDC_COMBO_IMAGE );

	i32Idx = SendMessage( hComboImage, CB_ADDSTRING, 0, (LPARAM)"<Empty>" );
	SendMessage( hComboImage, CB_SETITEMDATA, i32Idx, (LPARAM)0xffffffff );

	FileListC*	pFileList = m_pInterface->get_filelist();

	for( uint32 i = 0; i < pFileList->get_file_count(); i++ ) {

		FileHandleC*	pHandle = pFileList->get_file( i );
		ImportableI*	pImp = 0;

		if( !pHandle )
			continue;

		pImp = pHandle->get_importable();
		if( !pImp )
			continue;

		if( pImp == m_pOwnerImp )
			continue;
		
		if(  pImp->get_super_class_id() == SUPERCLASS_IMAGE ) {

			_splitpath( pImp->get_filename(), 0, 0, szFname, szExt );
			strcat( szFname, szExt );
		
			i32Idx = SendMessage( hComboImage, CB_ADDSTRING, 0, (LPARAM)szFname );
			SendMessage( hComboImage, CB_SETITEMDATA, i32Idx, (LPARAM)i );
		}

		if( m_pHandle == pHandle )
			i32Sel = i32Idx;
	}
	SendMessage( hComboImage, CB_SETCURSEL, i32Sel, 0 );

	check_file( m_pHandle );

	// update view
	update_flare();
	update_scroll_range();
	invalidate();

	return TRUE;
}

void
FlareDialogC::set_warning( const char* szMsg )
{
	SetWindowText( GetDlgItem( m_hDlg, IDC_STATIC_WARNING ), szMsg );
}

void
FlareDialogC::update_alpha( int32 i32ID, float32 f32Alpha )
{
	char	szVal[32];
	HWND	hEditAlpha;
	_snprintf( szVal, 31, "A:%d", (int32)(f32Alpha * 255.0f) );
	hEditAlpha = GetDlgItem( m_hDlg, i32ID );
	SetWindowText( hEditAlpha, szVal );
}

void
FlareDialogC::update_flare()
{
	if( m_rDIB.get_width() != m_ui32Width || m_rDIB.get_height() != m_ui32Height )
		m_rDIB.create( m_ui32Width, m_ui32Height );

	ImportableImageI*	pImp = 0;
	if( m_pHandle )
		pImp = (ImportableImageI*)m_pHandle->get_importable();
	if( pImp )
		pImp->eval_state( 0 );

	FlareRendererC::render_flare( (uint8*)m_rDIB.get_bits(), m_ui32Width, m_ui32Height, m_rBGColor, m_rGlowColor, m_f32Size, pImp, true );
}

void
FlareDialogC::update_scroll_range()
{
	int32	i32ViewWidth = m_rViewRect.right - m_rViewRect.left;
	int32	i32ViewHeight = m_rViewRect.bottom - m_rViewRect.top;

	int32	i32Width = m_rDIB.get_width();
	int32	i32Height = m_rDIB.get_height();

	i32Width *= m_i32Zoom;
	i32Height *= m_i32Zoom;
	i32Width /= 100;
	i32Height /= 100;

	m_i32OffsetXMax = 0;
	m_i32OffsetYMax = 0;

	if( i32Width > i32ViewWidth ) {
		m_i32OffsetXMax = i32Width - i32ViewWidth;
	}

	if( i32Height > i32ViewHeight ) {
		m_i32OffsetYMax = i32Height - i32ViewHeight;
	}

	if( m_i32OffsetX < 0 ) m_i32OffsetX = 0;
	if( m_i32OffsetX > m_i32OffsetXMax ) m_i32OffsetX = m_i32OffsetXMax;
	if( m_i32OffsetY < 0 ) m_i32OffsetY = 0;
	if( m_i32OffsetY > m_i32OffsetYMax ) m_i32OffsetY = m_i32OffsetYMax;
}

void
FlareDialogC::on_lbutton_down( POINT pt )
{
	if( m_i32OffsetXMax != 0 || m_i32OffsetYMax != 0 ) {
		if( PtInRect( &m_rViewRect, pt ) ) {
			m_i32StartX = pt.x;
			m_i32StartY = pt.y;
			m_i32StartOffsetX = m_i32OffsetX;
			m_i32StartOffsetY = m_i32OffsetY;
			m_bPanorate = true;
			SetCapture( m_hDlg );
			SetCursor( LoadCursor( g_hInstance, MAKEINTRESOURCE( IDC_HANDDRAG ) ) );
		}
	}
}

void
FlareDialogC::on_lbutton_up( POINT pt )
{
	if( GetCapture() == m_hDlg ) {
		ReleaseCapture();
		invalidate_view();
	}
	m_bPanorate = false;
}

void
FlareDialogC::on_mouse_move( POINT pt )
{
	if( GetCapture() == m_hDlg && m_bPanorate ) {
		m_i32OffsetX = (m_i32StartX - pt.x) + m_i32StartOffsetX;
		m_i32OffsetY = (m_i32StartY - pt.y) + m_i32StartOffsetY;

		if( m_i32OffsetX < 0 ) m_i32OffsetX = 0;
		if( m_i32OffsetX > m_i32OffsetXMax ) m_i32OffsetX = m_i32OffsetXMax;
		if( m_i32OffsetY < 0 ) m_i32OffsetY = 0;
		if( m_i32OffsetY > m_i32OffsetYMax ) m_i32OffsetY = m_i32OffsetYMax;

		invalidate_view();
	}
}

BOOL
FlareDialogC::on_command( HWND hCtl, uint32 ui32Cmd, uint32 ui32Notify )
{
	if( ui32Cmd == IDC_COMBOSIZE ) {
		if( ui32Notify == CBN_SELCHANGE ) {
			int32	i32Sel = SendMessage( hCtl, CB_GETCURSEL, 0, 0 );
			switch( i32Sel ) {
			case 0: m_ui32Width = m_ui32Height = 32; break;
			case 1: m_ui32Width = m_ui32Height = 64; break;
			case 2: m_ui32Width = m_ui32Height = 128; break;
			case 3: m_ui32Width = m_ui32Height = 256; break;
			}
			update_flare();
			invalidate();
			update_scroll_range();
			return 0;
		}
	}
	else if( ui32Cmd == IDC_EDITSIZE ) {
		if( ui32Notify == EN_KILLFOCUS ) {
			// get window text
			char	szText[256] = "";
			HWND	hEditSize;
			hEditSize = GetDlgItem( m_hDlg, IDC_EDITSIZE );
			GetWindowText( hEditSize, szText, 255 );
			m_f32Size = atof( szText );
			
			update_flare();
			invalidate();
		}
	}
	else if( ui32Cmd == IDC_BUTTONGLOW ) {
		ColorCommonDialogC*	pDlg = (ColorCommonDialogC*)m_pInterface->get_common_dialog( CLASS_COLORCOMMONDIALOG );
		if( pDlg ) {
			pDlg->set_color( m_rGlowColor );
			pDlg->set_parent_wnd( m_hDlg );
			if( pDlg->do_modal() ) {
				m_rGlowColor = pDlg->get_color();
				update_alpha( IDC_STATICGLOWALPHA, m_rGlowColor[3] );
				update_flare();
				invalidate();
			}
		}
	}
	else if( ui32Cmd == IDC_BUTTONBG ) {
		ColorCommonDialogC*	pDlg = (ColorCommonDialogC*)m_pInterface->get_common_dialog( CLASS_COLORCOMMONDIALOG );
		if( pDlg ) {
			pDlg->set_color( m_rBGColor );
			pDlg->set_parent_wnd( m_hDlg );
			if( pDlg->do_modal() ) {
				m_rBGColor = pDlg->get_color();
				update_alpha( IDC_STATICBGALPHA, m_rBGColor[3] );
				update_flare();
				invalidate();
			}
		}
	}
	else if( ui32Cmd == IDC_BUTTONZOOMIN ) {
		if( m_i32Zoom > 100 )
			m_i32Zoom += 50;
		else
			m_i32Zoom += 25;

		if( m_i32Zoom > 600 )
			m_i32Zoom = 600;

		HWND	hEditZoom;
		char	szVal[32];
		_snprintf( szVal, 31, "%d%%", m_i32Zoom );
		hEditZoom = GetDlgItem( m_hDlg, IDC_EDITZOOM );
		SetWindowText( hEditZoom, szVal );

		update_scroll_range();
		invalidate();
	}
	else if( ui32Cmd == IDC_BUTTONZOOMOUT ) {
		if( m_i32Zoom > 100 )
			m_i32Zoom -= 50;
		else
			m_i32Zoom -= 25;

		if( m_i32Zoom < 25 )
			m_i32Zoom = 25;

		HWND	hEditZoom;
		char	szVal[32];
		_snprintf( szVal, 31, "%d%%", m_i32Zoom );
		hEditZoom = GetDlgItem( m_hDlg, IDC_EDITZOOM );
		SetWindowText( hEditZoom, szVal );

		update_scroll_range();
		invalidate();
	}
	else if( ui32Cmd == IDC_COMBO_IMAGE ) {
		if( ui32Notify == CBN_SELCHANGE ) {
			int32	i32Sel = SendMessage( hCtl, CB_GETCURSEL, 0, 0 );
			if( i32Sel != CB_ERR ) {
				FileHandleC*	pHandle = 0;
				int32	i32Idx = SendMessage( hCtl, CB_GETITEMDATA, i32Sel, 0 );
				if( i32Idx != CB_ERR )
					pHandle = m_pInterface->get_filelist()->get_file( i32Idx );

				check_file( pHandle );
				m_pHandle = pHandle;

				update_flare();
				invalidate();
			}
		}
	}
	else if( ui32Cmd == IDOK || ui32Cmd == IDCANCEL ) {

		char	szText[256];

		HWND	hEditName;
		hEditName = GetDlgItem( m_hDlg, IDC_EDITNAME );
		GetWindowText( hEditName, szText, 255 );
		m_sName = szText;

		EndDialog( m_hDlg, ui32Cmd );
		return TRUE;
	}

	return 0;
}

BOOL
FlareDialogC::on_draw_item( LPDRAWITEMSTRUCT lpdis )
{
	if( lpdis->CtlID == IDC_BUTTONGLOW ) {
		HBRUSH	rColorBrush = CreateSolidBrush( color_to_COLOREF( m_rGlowColor ) );
		FillRect( lpdis->hDC, &lpdis->rcItem, rColorBrush );
		DeleteObject( rColorBrush );
		return TRUE;
	}
	else if( lpdis->CtlID == IDC_BUTTONBG ) {
		HBRUSH	rColorBrush = CreateSolidBrush( color_to_COLOREF( m_rBGColor ) );
		FillRect( lpdis->hDC, &lpdis->rcItem, rColorBrush );
		DeleteObject( rColorBrush );
		return TRUE;
	}
	return FALSE;
}

void
FlareDialogC::on_paint( HDC hDC )
{
	int32	i32Width = m_rDIB.get_width();
	int32	i32Height = m_rDIB.get_height();

	i32Width *= m_i32Zoom;
	i32Height *= m_i32Zoom;
	i32Width /= 100;
	i32Height /= 100;
	
	int32	i32ViewWidth = m_rViewRect.right - m_rViewRect.left;
	int32	i32ViewHeight = m_rViewRect.bottom - m_rViewRect.top;

	int32	i32SrcWidth = m_rDIB.get_width();
	int32	i32SrcHeight = m_rDIB.get_height();


	if( i32Width < i32ViewWidth ) {
		RECT	rect;
		rect.left = m_rViewRect.left + i32Width;
		rect.top = m_rViewRect.top;
		rect.right = m_rViewRect.right;
		rect.bottom = m_rViewRect.top + __min( i32Height , i32ViewHeight );
		FillRect( hDC, &rect, (HBRUSH)(COLOR_APPWORKSPACE + 1) );
	}
	if( i32Height < i32ViewHeight ) {
		RECT	rect;
		rect.left = m_rViewRect.left;
		rect.top = m_rViewRect.top + i32Height;
		rect.right = m_rViewRect.left + __min( i32Width, i32ViewWidth );
		rect.bottom = m_rViewRect.bottom;
		FillRect( hDC, &rect, (HBRUSH)(COLOR_APPWORKSPACE + 1) );
	}
	if( i32Width < i32ViewWidth && i32Height < i32ViewHeight ) {
		RECT	rect;
		rect.left = m_rViewRect.left + i32Width;
		rect.top = m_rViewRect.top + i32Height;
		rect.right = m_rViewRect.right;
		rect.bottom = m_rViewRect.bottom;
		FillRect( hDC, &rect, (HBRUSH)(COLOR_APPWORKSPACE + 1) );
	}


	// save old clip region
	RECT	rOldRect;
	HRGN	hOldClipRgn;
	GetClipBox( hDC, &rOldRect );
	hOldClipRgn = CreateRectRgnIndirect( &rOldRect );

	// create new clip region
	HRGN	hRegion;
	hRegion = CreateRectRgnIndirect( &m_rViewRect );
	SelectClipRgn( hDC, hRegion );


	m_rDIB.paste_to_DC( hDC, m_rViewRect.left - m_i32OffsetX, m_rViewRect.top - m_i32OffsetY, i32Width, i32Height );


	// restore old clip region
	SelectClipRgn( hDC, hOldClipRgn );
	DeleteObject( hOldClipRgn );
	DeleteObject( hRegion );

}

BOOL
FlareDialogC::on_set_cursor( POINT pt )
{
	if( m_i32OffsetXMax != 0 || m_i32OffsetYMax != 0 ) {
		if( PtInRect( &m_rViewRect, pt ) ) {
			SetCursor( LoadCursor( g_hInstance, MAKEINTRESOURCE( IDC_HAND ) ) );
			return TRUE;
		}
	}
	return FALSE;
}

void
FlareDialogC::invalidate_view()
{
	InvalidateRect( m_hDlg, &m_rViewRect, FALSE );
}

void
FlareDialogC::invalidate()
{
	InvalidateRect( m_hDlg, NULL, FALSE );
}

void
FlareDialogC::check_file( Import::FileHandleC* pHandle )
{
	set_warning( "" );

	if( !pHandle )
		return;

	ImportableImageI*	pImp = (ImportableImageI*)pHandle->get_importable();
	if( !pImp )
		return;

	pImp->eval_state( 0 );

	if( pImp->get_duration() >= 0 ) {
		set_warning( "Warning: The image has many frames, but only the first frame will be used to make this static image." );
	}

	if( !pImp->get_data() ) {
		set_warning( "Warning: The data of the image cannot be accessed." );
	}
}

