//***********************************************************//
// Demo:    Lens Flare Editor
// Author:  terror
// Spec:    demo for gamedev.ru
//***********************************************************//
#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <windowsx.h>
#include <stdio.h>
#include <commdlg.h>
#include <gl/gl.h>
#include "resource.h"
#include "dlgref.h"
#include "render.h"
#include "utils.h"
#include "Lens.h"

#pragma comment ( lib, "opengl32.lib" )
#pragma comment ( lib, "glu32.lib" )
#pragma comment ( lib, "jpeg.lib"  )

// current lens project
Lens_t proj;

window_t  GLWindow;
window_t  Opt;
HGLRC     hRC;
Point_t   MousePos;
int FoundTex=0;
HWND LensList;
HWND CrtList;
HWND CrtPList;
HWND TexList;
extern uint texLens[999];
extern bool ShowLensTex;
extern bool ShowBackTex;
extern int  CurrentLensTex;


void ReleaseOpenGL ( void );
void ApplyLensSettings ( int id );
void ApplyProjectSettings ( void );
void SaveProject ( void );
void OpenProject ( void );
vector4 GetNewColor   ( void );


DLGPROC GLDlgProc ( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
	if ( msg == WM_MOUSEMOVE )
	{
		MousePos.x = LOWORD(lParam);
		MousePos.y = HIWORD(lParam);
	}

	return 0;
}


DLGPROC OptProc ( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
	switch ( msg )
	{
		case WM_COMMAND:
		{
			switch (LOWORD(wParam))
			{
				case ID_FILEOPEN:
					OpenProject(); break;
				case ID_FILESAVE:
					SaveProject(); break;

				case IDC_APPLYPROJ:
				{
					ApplyProjectSettings();
					break;
				}

				case IDC_SHOWBACK:
				{
					ShowBackTex = !ShowBackTex;
					break;
				}

				case IDC_SHOWLENSTEX:
				{
					CurrentLensTex = ComboBox_GetCurSel ( TexList );
					ShowLensTex = !ShowLensTex;
					break;
				}

				case IDC_APPLYSET:
				{
					int lid = ComboBox_GetCurSel ( LensList );
					ApplyLensSettings(lid);
					break;
				}

				case IDC_COLORCH:
				{
					int lid = ComboBox_GetCurSel ( LensList );
					proj.Lens[lid].Color = GetNewColor();
					break;
				}

				case ID_ABOUTBTN:
				{
					char s[1024];
					char s1[64]; char s2[64]; char s3[64]; char s4[64]; char s5[128];
					strcpy ( s1, "Программа редактирования Lens Effect Flare." );
					strcpy ( s2, "Автор: terror" );
					strcpy ( s3, "Дата: 11.03.2003" );
					strcpy ( s4, "Версия: 0.1" );
					strcpy ( s5, "check dis out GAMEDEV.RU in da house !" );
					sprintf ( s, "%s\n\n%s\n%s\n%s\n\n%s", s1, s2, s3, s4, s5 );
					MessageBox ( Opt.hWnd, s, "О программе", MB_ICONQUESTION|MB_OK|MB_SYSTEMMODAL);
					break;
				}

				case ID_EXITB:
				{
					ReleaseOpenGL();
					Opt.DLG_ReleaseDialog();
					GLWindow.DLG_ReleaseDialog();
					PostQuitMessage(0);
					return 0;
				}
			}

			return 0;
		}
	}

	return 0;
}


void ApplyProjectSettings ( void )
{
	int temp = 0; char p[128] = "";

	GetWindowText ( GetDlgItem(Opt.hWnd,IDC_LSIZE), p, 128 );
	sscanf ( p, "%i", &temp );
	if ( temp <= 0 )
	{
		MessageBox ( 0, "Error. See lens size", "Error", MB_ICONERROR|MB_OK );
		return;
	}
	proj.SetAllLensSize ( temp );
}


void ApplyLensSettings ( int id )
{
	int temp; char buf[128] = "";

	// Get new lens size
	GetWindowText ( GetDlgItem(Opt.hWnd,IDC_LENSSIZE), buf, 128 );
	sscanf ( buf, "%i", &temp );
	if ( temp <= 0 )
	{
		MessageBox ( 0, "Error. See lens size", "Error", MB_ICONERROR|MB_OK );
		return;
	}
	proj.Lens[id].Size = temp;


	// Get new lens texture
	temp = ComboBox_GetCurSel ( TexList );
	proj.Lens[id].TexID = texLens[temp];
}

void SaveLens ( char *filename )
{
	FILE *f = NULL;
	f = fopen ( filename, "wb" );
	if ( f == NULL )
	{
		MessageBox ( 0, "Cant save file", "Error", MB_ICONERROR|MB_OK );
		return;
	}

	const char	SIGNATURE[] = "LNS";
	fwrite ( SIGNATURE, sizeof(const char), sizeof(SIGNATURE), f );
	fwrite ( &proj,     sizeof(proj), 1, f);
	fclose ( f );
}


void SaveProject ( void )
{
	OPENFILENAME ofn;
	char szFile[260];

	GetWindowText ( GetDlgItem(Opt.hWnd,IDC_PNAME), szFile, 260 );
	strcat ( szFile, ".lns" );

	ZeroMemory(&ofn, sizeof(OPENFILENAME));
	ofn.lStructSize = sizeof(OPENFILENAME);
	ofn.hwndOwner = Opt.hWnd;
	ofn.lpstrFile = szFile;
	ofn.nMaxFile = sizeof(szFile);
	ofn.lpstrFilter = "Lens file\0*.LNS\0";
	ofn.nFilterIndex = 1;
	ofn.lpstrFileTitle = NULL;
	ofn.nMaxFileTitle = 0;
	ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;

	if ( GetSaveFileName ( &ofn ))
	{
		SaveLens ( ofn.lpstrFile );
	}
}


void OpenLens ( char *filename )
{
	char SIGNATURE[4];
	FILE *f = NULL;
	f = fopen ( filename, "rb" );
	if ( f == NULL )
	{
		MessageBox ( 0, "Cant open file", "Error", MB_ICONERROR|MB_OK );
		return;
	}

	fread ( SIGNATURE, sizeof(const char), sizeof(SIGNATURE), f );
	fread ( &proj, sizeof(proj), 1, f);
	fclose ( f );
}


void OpenProject ( void )
{
	OPENFILENAME ofn;
	char szFile[260] = "";

	ZeroMemory(&ofn, sizeof(OPENFILENAME));
	ofn.lStructSize = sizeof(OPENFILENAME);
	ofn.hwndOwner = Opt.hWnd;
	ofn.lpstrFile = szFile;
	ofn.nMaxFile = sizeof(szFile);
	ofn.lpstrFilter = "Lens file\0*.LNS\0";
	ofn.nFilterIndex = 1;
	ofn.lpstrFileTitle = NULL;
	ofn.nMaxFileTitle = 0;
	ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;

	if ( GetOpenFileName ( &ofn ))
	{
		OpenLens ( ofn.lpstrFile );
	}
}



vector4 GetNewColor ( void )
{
	CHOOSECOLOR cc;
	static COLORREF acrCustClr[16];
	static DWORD rgbCurrent;
	vector4 color;
	VECTOR4_SET ( color, 0.0f );

	ZeroMemory(&cc, sizeof(CHOOSECOLOR));
	cc.lStructSize = sizeof(CHOOSECOLOR);
	cc.hwndOwner = Opt.hWnd;
	cc.lpCustColors = (LPDWORD) acrCustClr;
	cc.rgbResult = rgbCurrent;
	cc.Flags = CC_FULLOPEN | CC_RGBINIT;

	if ( ChooseColor ( &cc ))
	{
		rgbCurrent = cc.rgbResult;
		color.v[0] = ((float)GetRValue ( rgbCurrent )) / 255.0f;
		color.v[1] = ((float)GetGValue ( rgbCurrent )) / 255.0f;
		color.v[2] = ((float)GetBValue ( rgbCurrent )) / 255.0f;
		color.v[3] = 1.0f;
	}

	return color;
}


void SetupOpenGL ( window_t &wnd )
{
	unsigned int PixelFormat = 0;

	static	PIXELFORMATDESCRIPTOR pfd=
	{
		sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW |
			PFD_SUPPORT_OPENGL |  PFD_DOUBLEBUFFER, PFD_TYPE_RGBA,
			32, 0, 0, 0, 0, 0, 0,	0, 0, 0, 0, 0, 0, 0, 32, 0, 0,
			PFD_MAIN_PLANE, 0, 0, 0, 0
	};

	PixelFormat = ChoosePixelFormat ( wnd.hDC, &pfd );
	SetPixelFormat ( wnd.hDC, PixelFormat, &pfd );
	hRC = wglCreateContext ( wnd.hDC );
	wglMakeCurrent ( wnd.hDC, hRC );
}

void ReleaseOpenGL ( void )
{
	ShutDownGL();
	wglMakeCurrent ( NULL, NULL );
	wglDeleteContext ( hRC );
}


void SetupInterface ( void )
{
	char p[128] = "";

	SetWindowText ( GetDlgItem(Opt.hWnd, IDC_PNAME), "LensProject" );

	sprintf(p,"%i",proj.Count); SetWindowText ( GetDlgItem(Opt.hWnd, IDC_LCOUNT),   p );
	sprintf(p,"%i",proj.Size);  SetWindowText ( GetDlgItem(Opt.hWnd, IDC_LSIZE),    p );
	sprintf(p,"%i",proj.Size);  SetWindowText ( GetDlgItem(Opt.hWnd, IDC_LENSSIZE), p );


	CrtList  = GetDlgItem ( Opt.hWnd, IDC_CREATION );
	CrtPList = GetDlgItem ( Opt.hWnd, IDC_CREATION2 );
	LensList = GetDlgItem ( Opt.hWnd, IDC_SLENS );
		for ( int i = 0; i < 999; i++ )
		{
			strcpy ( p, "" );
			sprintf ( p, "Lens %i", i+1 );
			ComboBox_AddString ( LensList, p  );
		}
	ComboBox_SetCurSel ( LensList, 0 );
	UpdateWindow ( LensList );


	TexList  = GetDlgItem ( Opt.hWnd, IDC_STEX );
		for (int i = 0; i < FoundTex; i++ )
		{
			strcpy ( p, "" );
			sprintf ( p, "Texture %i", i+1 );
			ComboBox_AddString ( TexList, p  );
		}
	ComboBox_SetCurSel ( TexList, 0 );
	UpdateWindow ( TexList );


	ComboBox_AddString ( CrtList, "Based"  );
	ComboBox_AddString ( CrtList, "Center"  );
	ComboBox_AddString ( CrtList, "Increase"  );
	ComboBox_AddString ( CrtList, "Decrease"  );
	ComboBox_SetCurSel ( CrtList, 0 );
	UpdateWindow ( CrtList );

	ComboBox_AddString ( CrtPList, "Division"  );
	ComboBox_AddString ( CrtPList, "Multi"  );
	ComboBox_SetCurSel ( CrtPList, 0 );
	UpdateWindow ( CrtPList );
}


int WINAPI WinMain ( HINSTANCE	hInstance, HINSTANCE	hPrevInstance, LPSTR lpCmdLine, int	nCmdShow )
{
	MSG msg;

	Opt.DLG_CreateDialog      ( IDD_OPT_DLG,    (DLGPROC)OptProc,   hInstance, true );
	GLWindow.DLG_CreateDialog ( IDD_RENDER_DLG, (DLGPROC)GLDlgProc, hInstance, true );

	FindLensTextures();
	SetupOpenGL ( GLWindow );
	InitRender();

	proj.LoadDefault();
		SetupInterface();
		LoadLensTextures();
	proj.LoadDefault();


	while ( GetMessage ( &msg, 0, 0, 0 ))
	{
		TranslateMessage ( &msg );
		DispatchMessage  ( &msg );

		Render();
	}


	return (int)msg.wParam;
}





