//----------------------------------------------------------------------------
//  Project Test_At3dx_Lights
//  MicroMouse Productions
//  Copyright © 2011-2012. All Rights Reserved.
//  Author: Wayne Hogue
//
//----------------------------------------------------------------------------

// MSVC_Test_At3dx_LightsDlg.cpp : implementation file
//

#include "stdafx.h"
#include "MSVC_Test_At3dx_Lights.h"
#include "MSVC_Test_At3dx_LightsDlg.h"
#include "..\at3dx_my_functions.h"
#include "..\at3ddll.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CMSVC_Test_At3dx_LightsDlg dialog

CMSVC_Test_At3dx_LightsDlg::CMSVC_Test_At3dx_LightsDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CMSVC_Test_At3dx_LightsDlg::IDD, pParent)
  , m_InputFileType_Group(0)
  , m_Light0(FALSE)
  , m_Light1(FALSE)
  , m_UseTextures(FALSE)
  , m_UseOglReplace(FALSE)
  , m_UseWhiteBase(FALSE)
  , m_AlwaysShowCameraCursor(FALSE)
  , m_ReversePan(FALSE)
  , m_ReverseZoom(FALSE)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

  dllOpen    = 0;
  fileLoaded = 0;

  memset(inName, 0, sizeof(char) * MAX_PATH);

  inputFileType = 0;

  // Display textures
  //
  useTexturesFlag = 1;

  // Let texture colors be affected by the lighting
  //
  oglReplaceFlag = 0;

  // When displaying textures use white as the diffuse color
  // instead of the assigned diffuse color for the layer
  //
  useWhiteBaseFlag = 1;

  // Reverse direction of pan
  //
  reversePanFlag = 1;

  // Reverse direction of zoom
  //
  reverseZoomFlag = 1;

  // Default setting for camera cursor
  //
  alwaysShowCameraCursorFlag = 0;
}

void CMSVC_Test_At3dx_LightsDlg::DoDataExchange(CDataExchange* pDX)
{
  CDialog::DoDataExchange(pDX);
  DDX_Radio(pDX, IDC_TYPE_KMZ, m_InputFileType_Group);
  DDV_MinMaxInt(pDX, m_InputFileType_Group, 0, 1);
  DDX_Check(pDX, IDC_LIGHT_0, m_Light0);
  DDX_Check(pDX, IDC_LIGHT_1, m_Light1);
  DDX_Check(pDX, IDC_USE_TEXTURES, m_UseTextures);
  DDX_Check(pDX, IDC_USE_OGL_REPLACE, m_UseOglReplace);
  DDX_Check(pDX, IDC_USE_WHITE_BASE, m_UseWhiteBase);
  DDX_Check(pDX, IDC_ALWAYS_SHOW_CAMERA_CURSOR, m_AlwaysShowCameraCursor);
  DDX_Check(pDX, IDC_REVERSE_PAN, m_ReversePan);
  DDX_Check(pDX, IDC_REVERSE_ZOOM, m_ReverseZoom);
}

BEGIN_MESSAGE_MAP(CMSVC_Test_At3dx_LightsDlg, CDialog)
  ON_WM_DESTROY()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
  ON_BN_CLICKED(IDC_DO_START_DLL, &CMSVC_Test_At3dx_LightsDlg::OnBnClicked_DoStartDll)
  ON_BN_CLICKED(IDC_DO_STOP_DLL, &CMSVC_Test_At3dx_LightsDlg::OnBnClicked_DoStopDll)
  ON_BN_CLICKED(IDC_TYPE_KMZ, &CMSVC_Test_At3dx_LightsDlg::OnBnClicked_TypeKmz)
  ON_BN_CLICKED(IDC_TYPE_OBJ, &CMSVC_Test_At3dx_LightsDlg::OnBnClicked_TypeObj)
  ON_BN_CLICKED(IDC_READ_3D_FILE, &CMSVC_Test_At3dx_LightsDlg::OnBnClicked_Read3dFile)
  ON_BN_CLICKED(IDC_LIGHT_0, &CMSVC_Test_At3dx_LightsDlg::OnBnClicked_Light0)
  ON_BN_CLICKED(IDC_LIGHT_1, &CMSVC_Test_At3dx_LightsDlg::OnBnClicked_Light1)
  ON_BN_CLICKED(IDC_USE_TEXTURES, &CMSVC_Test_At3dx_LightsDlg::OnBnClicked_UseTextures)
  ON_BN_CLICKED(IDC_USE_OGL_REPLACE, &CMSVC_Test_At3dx_LightsDlg::OnBnClicked_UseOglReplace)
  ON_BN_CLICKED(IDC_USE_WHITE_BASE, &CMSVC_Test_At3dx_LightsDlg::OnBnClicked_UseWhiteBase)
  ON_BN_CLICKED(IDC_ALWAYS_SHOW_CAMERA_CURSOR, &CMSVC_Test_At3dx_LightsDlg::OnBnClicked_AlwaysShowCameraCursor)
  ON_BN_CLICKED(IDC_REVERSE_PAN, &CMSVC_Test_At3dx_LightsDlg::OnBnClicked_ReversePan)
  ON_BN_CLICKED(IDC_REVERSE_ZOOM, &CMSVC_Test_At3dx_LightsDlg::OnBnClicked_ReverseZoom)
END_MESSAGE_MAP()


// CMSVC_Test_At3dx_LightsDlg message handlers

BOOL CMSVC_Test_At3dx_LightsDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon

	// TODO: Add extra initialization here

  // by default, only Light 0 is turned on
  m_Light0 = TRUE;
  m_Light1 = FALSE;

  // set initial file type to read
  //
  m_InputFileType_Group = 0;

  UpdateData(FALSE);

	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CMSVC_Test_At3dx_LightsDlg::OnDestroy() 
{
	CDialog::OnDestroy();
	
	// TODO: Add your message handler code here

	// free all memory used by the DLL
	//
	if (dllOpen) Stop_DLL();
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CMSVC_Test_At3dx_LightsDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this function to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CMSVC_Test_At3dx_LightsDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}


void CMSVC_Test_At3dx_LightsDlg::Start_DLL(void)
{
  if (dllOpen) return;

  dllOpen = At3d_Start();

  if (!dllOpen) return;
  
  // Defaults for this DLL and other software can change without notice
  // Recommended practice is to set the defaults you want for your program
  // for those DLL features you will be using
  //
  // Following are the defaults chosen for this Demo
  //
  // To detect mouse scroll wheel messages the DLL has to know the
  // handle to the main window of the application which
  // receives all the messages from the Windows Operating System
  //
  At3d_SetAppHandle(GetSafeHwnd());

  // Set size of DLL window
  //
  At3d_Size(600, 500);

  // Set position of DLL window
  //
  At3d_Position(2, 2);

  // Make DLL window a child of a window in the application
  //
  At3d_SetParent(GetSafeHwnd());

  // If the DLL window does not have a parent
  // At3d_SetParent(0);
  // a button will appear on the Windows Taskbar
  // use this function to set the name that will appear
  //
  At3d_SetCaption("DLL (at3d)");

  // use the OpenGL viewer
  //
  At3d_WriteFlag(LIBFLAG_USE_OPENGL, 1);

  // light both sides of polygons
  //
  At3d_WriteFlag(LIBFLAG_OGL_2SIDED_LIGHTING, 1);

  // do NOT cull back faces
  //
  At3d_WriteFlag(LIBFLAG_OGL_CULL_BACKFACES, 0);

  m_UseTextures = (useTexturesFlag) ? TRUE : FALSE;
  At3d_WriteFlag(LIBFLAG_OGL_USE_TEXTURES, useTexturesFlag);

  // do NOT display the default texture when
  // - the texture file can not be found
  // - the texture file format is not supported
  // - no texture file was assigned
  //
  At3d_WriteFlag(LIBFLAG_OGL_USE_DEFAULT_TEXTURE, 0);

  m_UseOglReplace = (oglReplaceFlag) ? TRUE : FALSE;
  At3d_WriteFlag(LIBFLAG_OGL_REPLACE, oglReplaceFlag);

  m_UseWhiteBase = (useWhiteBaseFlag) ? TRUE : FALSE;
  At3d_WriteFlag(LIBFLAG_OGL_WHITE_BASE, useWhiteBaseFlag);

  m_ReversePan = (reversePanFlag) ? TRUE : FALSE;
  At3d_WriteFlag(LIBFLAG_REVERSE_PAN_DIRECTION, reversePanFlag);

  m_ReverseZoom = (reverseZoomFlag) ? TRUE : FALSE;
  At3d_WriteFlag(LIBFLAG_REVERSE_ZOOM_DIRECTION, reverseZoomFlag);

  m_AlwaysShowCameraCursor = (alwaysShowCameraCursorFlag) ? TRUE : FALSE;
  At3d_WriteFlag(LIBFLAG_ALWAYS_SHOW_CAMERA_CURSOR, alwaysShowCameraCursorFlag);

  // do before setting lights
  //
  UpdateData(FALSE);

  SetLight0();
  SetLight1();

  // Make DLL window visible
  //
  At3d_Show();
}

void CMSVC_Test_At3dx_LightsDlg::Stop_DLL(void)
{
  if (!dllOpen) return;

  // free all memory used by the DLL
	//
  At3d_Stop();
  dllOpen = 0;
}

void CMSVC_Test_At3dx_LightsDlg::Read_3D_File(void)
{
  if (!dllOpen) return;

  char path[_MAX_PATH];
  char drive0[_MAX_DRIVE];
	char dir0[_MAX_DIR];
	char name0[_MAX_FNAME];
	char ext0[_MAX_EXT];
    
  if (inName[0] != 0)
  {
    my_splitpath(inName, drive0, _MAX_DRIVE, dir0, _MAX_DIR, name0, _MAX_FNAME,
                 ext0, _MAX_EXT);

    my_strcpy(path, _MAX_PATH, drive0);
    my_strcat(path, _MAX_PATH, dir0);

    my_strcat(name0, _MAX_FNAME, ext0);
  }
  else
  {
    path[0]  = '\0';
    name0[0] = '\0';
  }

  char* inputNamePtr;
  char* inputExtensionPtr;
  __int32 inputType;

  if (!inputFileType)
  {
    inputNamePtr      = "Google Earth";
    inputExtensionPtr = ".kmz";
    inputType         = INTYPE_GOOGLE_EARTH;
  }
  else
  {    
    inputNamePtr      = "Wavefront";
    inputExtensionPtr = ".obj";
    inputType         = INTYPE_WAVEFRONT;
  }

  CString filter = inputNamePtr;
  filter += "|*";
  filter += inputExtensionPtr;
  filter += "|All|*.*|";

  CFileDialog dlg(TRUE, NULL, inName,
					OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST,
					filter, 0);

	if( dlg.DoModal() == IDOK )
  {
		my_strcpy(inName, MAX_PATH, (char*)LPCTSTR(dlg.GetPathName()));

    // before reading make sure flags are set properly
    // (note: flags maintain their setting until changed with this function)
    //
    At3d_WriteFlag(LIBFLAG_REMOVE_DUPLICATE_VERTICES, 1);
    At3d_WriteFlag(LIBFLAG_REMOVE_DUPLICATE_FACES, 1);
    At3d_WriteFlag(LIBFLAG_SHOW_READ_MESSAGES, 0);

    // read file
    //
    fileLoaded = At3d_Read(INTYPE_WAVEFRONT, inName, 1.0);
  }
}

void CMSVC_Test_At3dx_LightsDlg::OnBnClicked_DoStartDll()
{
  Start_DLL();
}

void CMSVC_Test_At3dx_LightsDlg::OnBnClicked_DoStopDll()
{
  Stop_DLL();
}

void CMSVC_Test_At3dx_LightsDlg::OnBnClicked_TypeKmz()
{
  inputFileType = 0;
}

void CMSVC_Test_At3dx_LightsDlg::OnBnClicked_TypeObj()
{
  inputFileType = 1;
}

void CMSVC_Test_At3dx_LightsDlg::OnBnClicked_Read3dFile()
{
  Read_3D_File();
}

void CMSVC_Test_At3dx_LightsDlg::OnBnClicked_Light0()
{
  if (dllOpen) SetLight0();
}

void CMSVC_Test_At3dx_LightsDlg::SetLight0(void)
{
  if (!dllOpen) return;

  UpdateData(TRUE);
  __int32 enabledFlag = (m_Light0) ? 1 : 0;

  float ambient[4];
  float diffuse[4];
  float specular[4];
  float position[3];

  ambient[0] = 0.0;
  ambient[1] = 0.0;
  ambient[2] = 0.0;
  ambient[3] = 1.0;

  diffuse[0] = 1.0;
  diffuse[1] = 1.0;
  diffuse[2] = 1.0;
  diffuse[3] = 1.0;

  specular[0] = 0.0;
  specular[1] = 0.0;
  specular[2] = 0.0;
  specular[3] = 1.0;

  position[0] = 0.0;
  position[1] = 0.0;
  position[2] = 1.0;

  __int32 result = At3d_Set_OGL_Directional_Light(0, enabledFlag,
                                                  ambient, diffuse,
                                                  specular, position);

  // to update OpenGL light settings immediately do a redraw
  //
  if (result) At3d_DrawWireframe();
}

void CMSVC_Test_At3dx_LightsDlg::OnBnClicked_Light1()
{
  if (dllOpen) SetLight1();
}

void CMSVC_Test_At3dx_LightsDlg::SetLight1(void)
{
  if (!dllOpen) return;

  UpdateData(TRUE);
  __int32 enabledFlag = (m_Light1) ? 1 : 0;

  float ambient[4];
  float diffuse[4];
  float specular[4];
  float position[3];

  ambient[0] = 0.0;
  ambient[1] = 0.0;
  ambient[2] = 0.0;
  ambient[3] = 1.0;

  diffuse[0] = 0.5;
  diffuse[1] = 0.5;
  diffuse[2] = 0.5;
  diffuse[3] = 1.0;

  specular[0] = 0.0;
  specular[1] = 0.0;
  specular[2] = 0.0;
  specular[3] = 1.0;

  position[0] = 0.0;
  position[1] = 1.0;
  position[2] = 0.5;

  __int32 result = At3d_Set_OGL_Directional_Light(1, enabledFlag,
                                                  ambient, diffuse,
                                                  specular, position);

  // to update OpenGL light settings immediately do a redraw
  //
  if (result) At3d_DrawWireframe();
}

void CMSVC_Test_At3dx_LightsDlg::OnBnClicked_UseTextures()
{
  if (!dllOpen) return;

  UpdateData(TRUE);
  useTexturesFlag = (m_UseTextures) ? 1 : 0;

  At3d_WriteFlag(LIBFLAG_OGL_USE_TEXTURES, useTexturesFlag);
}

void CMSVC_Test_At3dx_LightsDlg::OnBnClicked_UseOglReplace()
{
  if (!dllOpen) return;

  UpdateData(TRUE);
  oglReplaceFlag = (m_UseOglReplace) ? 1 : 0;

  At3d_WriteFlag(LIBFLAG_OGL_REPLACE, oglReplaceFlag);
}

void CMSVC_Test_At3dx_LightsDlg::OnBnClicked_UseWhiteBase()
{
  if (!dllOpen) return;

  UpdateData(TRUE);
  useWhiteBaseFlag = (m_UseWhiteBase) ? 1 : 0;

  At3d_WriteFlag(LIBFLAG_OGL_WHITE_BASE, useWhiteBaseFlag);
}

void CMSVC_Test_At3dx_LightsDlg::OnBnClicked_AlwaysShowCameraCursor()
{
  if (!dllOpen) return;

  UpdateData(TRUE);
  alwaysShowCameraCursorFlag = (m_AlwaysShowCameraCursor) ? TRUE : FALSE;
    
  At3d_WriteFlag(LIBFLAG_ALWAYS_SHOW_CAMERA_CURSOR, alwaysShowCameraCursorFlag);
}

void CMSVC_Test_At3dx_LightsDlg::OnBnClicked_ReversePan()
{
  if (!dllOpen) return;

  UpdateData(TRUE);
  reversePanFlag = (m_ReversePan) ? 1 : 0;

  At3d_WriteFlag(LIBFLAG_REVERSE_PAN_DIRECTION, reversePanFlag);
}

void CMSVC_Test_At3dx_LightsDlg::OnBnClicked_ReverseZoom()
{
  if (!dllOpen) return;

  UpdateData(TRUE);
  reverseZoomFlag = (m_ReverseZoom) ? 1 : 0;
  
  At3d_WriteFlag(LIBFLAG_REVERSE_ZOOM_DIRECTION, reverseZoomFlag);
}
