/*===========================================================================
 *
 * File:	Dfto3dsview.CPP
 * Author:	Dave Humphrey (uesp@m0use.net)
 * Created On:	Saturday, June 23, 2001
 *
 * Implements the CDfto3dsView class.
 *
 *=========================================================================*/

	/* Include Files */
#include "stdafx.h"
#include "dfto3ds.h"
#include "dfto3dsDoc.h"
#include "dfto3dsView.h"
#include "uesp/dagger/df3dexpo.h"
#include "afxpriv.h"
#include "Dfexport3dsdialog.h"


/*===========================================================================
 *
 * Begin Local Variable Definitions
 *
 *=========================================================================*/

	/* Debug definitions and variables */
#ifdef _DEBUG
  #define new DEBUG_NEW
  #undef THIS_FILE
  static char THIS_FILE[] = __FILE__;
#endif

IMPLEMENT_DYNCREATE(CDfto3dsView, CFormView)
/*===========================================================================
 *		End of Local Variable Definitions
 *=========================================================================*/


/*===========================================================================
 *
 * Class CDfto3dsView Message Map
 *
 *=========================================================================*/
BEGIN_MESSAGE_MAP(CDfto3dsView, CFormView)
  //{{AFX_MSG_MAP(CDfto3dsView)
  ON_LBN_SELCHANGE(IDC_ARCH3DOBJECT_LIST, OnSelchangeArch3dobjectList)
  ON_UPDATE_COMMAND_UI(ID_FILE_EXPORTDXF, OnUpdateFileExportdxf)
  ON_UPDATE_COMMAND_UI(ID_FILE_EXPORT3DS, OnUpdateFileExportdxf)
  ON_UPDATE_COMMAND_UI(ID_FILE_EXPORTALL, OnUpdateFileExportdxf)
  ON_COMMAND(ID_FILE_EXPORTDXF, OnFileExportdxf)
  ON_COMMAND(ID_FILE_EXPORT3DS, OnFileExport3ds)
  ON_COMMAND(ID_FILE_EXPORTALL, OnFileExportAll3ds)
  ON_WM_CONTEXTMENU()
  ON_MESSAGE(WM_HELPHITTEST, OnHelpHitTest)
  //}}AFX_MSG_MAP
END_MESSAGE_MAP()
/*===========================================================================
 *		End of CDfto3dsView Message Map
 *=========================================================================*/


/*===========================================================================
 *
 * Class Dfto3dsView Constructor
 *
 *=========================================================================*/
CDfto3dsView::CDfto3dsView()  : CFormView(CDfto3dsView::IDD) {
  //{{AFX_DATA_INIT(CDfto3dsView)
  //}}AFX_DATA_INIT
 }
/*===========================================================================
 *		End of Class Dfto3dsView Constructor
 *=========================================================================*/


/*===========================================================================
 *
 * Class CDfto3dsView Destructor
 *
 *=========================================================================*/
CDfto3dsView::~CDfto3dsView() {
 }
/*===========================================================================
 *		End of Class CDfto3dsView Destructor
 *=========================================================================*/


/*===========================================================================
 *
 * Class CDfto3dsView Method - void ClearObjectTexts (void);
 *
 * Clears all of the object texts.
 *
 *=========================================================================*/
void CDfto3dsView::ClearObjectTexts (void) {
  //DEFINE_FUNCTION("CDfto3dsView::ClearObjectTexts()");
  m_ValueText.SetWindowText("");
  m_SizeText.SetWindowText("");
  m_OffsetText.SetWindowText("");
  m_VersionText.SetWindowText("");

  m_PointOffsetText.SetWindowText("");
  m_FaceOffsetText.SetWindowText("");
  m_NormalsOffsetText.SetWindowText("");
  m_Data1OffsetText.SetWindowText("");
  m_Data2OffsetText.SetWindowText("");
 
  m_PointCountText.SetWindowText("");
  m_FaceCountText.SetWindowText("");
  m_Data2CountText.SetWindowText("");
  
 }
/*===========================================================================
 *		End of Class Method CDfto3dsView::ClearObjectTexts()
 *=========================================================================*/


/*===========================================================================
 *
 * Class CDfto3dsView Method - void CreateObjectList (void);
 *
 * Update the object list with the contents of the current Arch3D file.
 *
 *=========================================================================*/
void CDfto3dsView::CreateObjectList (void) {
  CDfto3dsDoc* pDocument = GetDocument();
  CString      Buffer; 
  short	       Index;
  long         Value;

	/* Clear the current list contents */
  m_ObjectList.ResetContent();

  for (Index = 0; Index < pDocument->GetNum3DFiles(); Index++) {
    Value = pDocument->GetFileValue(Index);
    //Buffer.Format("%5d) 0x%08lX  (%ld kb)", (int)Index+1, pDocument->GetFileValue(Index), (long) (pDocument->GetFileSize(Index)/1000));
    Buffer.Format("%5d) %03ld-%02ld  (%ld kb)", (int)Index+1, (long)(Value/100), Value - 100*(long)(Value/100), (long) (pDocument->GetFileSize(Index)/1000));
    m_ObjectList.AddString(Buffer);
   }

	/* Update the listbox selected item */
  if (pDocument->GetNum3DFiles() > 0) 
    m_ObjectList.SetCurSel(0);
  else
    m_ObjectList.SetCurSel(-1);

	/* Update the object texts */
  OnSelchangeArch3dobjectList();
 }
/*===========================================================================
 *		End of Class Method CDfto3dsView::CreateObjectList()
 *=========================================================================*/


/*===========================================================================
 *
 * Class CDfto3dsView Method - void DoDataExchange (pDX);
 *
 *=========================================================================*/
void CDfto3dsView::DoDataExchange(CDataExchange* pDX) {
  CFormView::DoDataExchange(pDX);

  //{{AFX_DATA_MAP(CDfto3dsView)
  DDX_Control(pDX, IDC_OBJECT_DATA1OFFSET, m_Data1OffsetText);
  DDX_Control(pDX, IDC_OBJECT_NORMALOFFSET, m_NormalsOffsetText);
  DDX_Control(pDX, IDC_OBJECT_POINTOFFSET, m_PointOffsetText);
  DDX_Control(pDX, IDC_OBJECT_DATA2OFFSET, m_Data2OffsetText);
  DDX_Control(pDX, IDC_OBJECT_FACEOFFSET, m_FaceOffsetText);
  DDX_Control(pDX, IDC_OBJECT_DATA2COUNT, m_Data2CountText);
  DDX_Control(pDX, IDC_OBJECT_FACECOUNT, m_FaceCountText);
  DDX_Control(pDX, IDC_OBJECT_POINTCOUNT, m_PointCountText);
  DDX_Control(pDX, IDC_OBJECT_VERSION, m_VersionText);
  DDX_Control(pDX, IDC_OBJECT_SIZE, m_SizeText);
  DDX_Control(pDX, IDC_OBJECT_OFFSET, m_OffsetText);
  DDX_Control(pDX, IDC_OBJECT_VALUE, m_ValueText);
  DDX_Control(pDX, IDC_ARCH3DOBJECT_LIST, m_ObjectList);
  //}}AFX_DATA_MAP
 }
/*===========================================================================
 *		End of Class Method CDfto3dsView::DoDataExchange()
 *=========================================================================*/


/*===========================================================================
 *
 * Class CDfto3dsView Method - boolean IsSelectedObjectValid (void);
 *
 *=========================================================================*/
boolean CDfto3dsView::IsSelectedObjectValid (void) {
  CDfto3dsDoc* pDocument = GetDocument();
  int	       Index = m_ObjectList.GetCurSel();

	/* Ensure a list item is selected */
  if (Index == LB_ERR) return (FALSE);

	/* Ensure the selected index is a valid object index */
  if (Index < 0 || Index >= pDocument->GetNum3DFiles()) return (FALSE);

	/* Ensure the current loaded object is valid */
  if (pDocument->GetCurrentObject() == NULL) return (FALSE);

	/* Must be a valid object */
  return (TRUE);
 }   
/*===========================================================================
 *		End of Class Event CDfto3dsView::IsSelectedObjectValid()
 *=========================================================================*/


/*===========================================================================
 *
 * Class CDfto3dsView Method - BOOL PreCreateWindow (cs);
 *
 *=========================================================================*/
BOOL CDfto3dsView::PreCreateWindow(CREATESTRUCT& cs) {
  //cs.dwExStyle |= WS_EX_CONTEXTHELP;
  return CFormView::PreCreateWindow(cs);
 }
/*===========================================================================
 *		End of Class Method CDfto3dsView::PreCreateWindow()
 *=========================================================================*/


/*===========================================================================
 *
 * Class CDfto3dsView Event - void OnInitialUpdate ();
 *
 *=========================================================================*/
void CDfto3dsView::OnInitialUpdate() {
  CFormView::OnInitialUpdate();
  GetParentFrame()->RecalcLayout();
  ResizeParentToFit();
 }
/*===========================================================================
 *		End of Class Event CDfto3dsView::OnInitialUpdate()
 *=========================================================================*/


/*===========================================================================
 *
 * Class CDfto3dsView Diagnostics
 *
 *=========================================================================*/
#ifdef _DEBUG

void CDfto3dsView::AssertValid() const {
  CFormView::AssertValid();
 }

void CDfto3dsView::Dump(CDumpContext& dc) const {
  CFormView::Dump(dc);
 }

CDfto3dsDoc* CDfto3dsView::GetDocument() {
  ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDfto3dsDoc)));
  return (CDfto3dsDoc*)m_pDocument;
 }

#endif
/*===========================================================================
 *		End of Class CDfto3dsView Diagnostics
 *=========================================================================*/


/*===========================================================================
 *
 * Class CDfto3dsView Event - void OnUpdate (pSender, lHint, pHint);
 *
 *=========================================================================*/
void CDfto3dsView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) {
  CreateObjectList();
 }
/*===========================================================================
 *		End of Class Event CDfto3dsView::OnUpdate()
 *=========================================================================*/


/*===========================================================================
 *
 * Class CDfto3dsView Event - void OnSelchangeArch3dobjectList ();
 *
 *=========================================================================*/
void CDfto3dsView::OnSelchangeArch3dobjectList() {
  int Index = m_ObjectList.GetCurSel();

	/* Check for error or no selection */
  if (Index == LB_ERR) 
    ClearObjectTexts();
  else
    SetObjectTexts(Index);

 }
/*===========================================================================
 *		End of Class Event CDfto3dsView::OnSelchangeArch3dobjectList()
 *=========================================================================*/


/*===========================================================================
 *
 * Class CDfto3dsView Method - void SetObjectTexts (Index);
 *
 * Updates the object texts to the given indexed DF 3d object.
 *
 *=========================================================================*/
void CDfto3dsView::SetObjectTexts (const int Index) {
  DEFINE_FUNCTION("CDfto3dsView::SetObjectTexts()");
  CDfto3dsDoc*  pDocument = GetDocument();
  CDF3dObject*  pObject;
  CString       Buffer;
  boolean       Result;

	/* Ensure valid input */
  ASSERT(Index < (int)pDocument->GetNum3DFiles());

	/* Attempt to load the given 3D object */
  Result = pDocument->LoadArch3DObject(Index);

  if (!Result) {
    ErrorHandler.Notify("Arch3D Object Error!");
    ClearObjectTexts();
    return;
   }

	/* Get the newly loaded 3D object */
  pObject = pDocument->GetCurrentObject();
  ASSERT(pObject != NULL);

  Buffer.Format("%ld  (0x%08lX)", pDocument->GetFileValue(Index), pDocument->GetFileValue(Index));
  m_ValueText.SetWindowText(Buffer);

  Buffer.Format("%ld  (0x%08lX)", pDocument->GetFileSize(Index), pDocument->GetFileSize(Index));
  m_SizeText.SetWindowText(Buffer);

  Buffer.Format("0x%08lX", pDocument->GetFileOffset(Index), pDocument->GetFileOffset(Index));
  m_OffsetText.SetWindowText(Buffer);

  Buffer.Format("%ld  (0x%04lX)", pObject->GetData1Offset(), pObject->GetData1Offset());
  m_Data1OffsetText.SetWindowText(Buffer);

  Buffer.Format("%ld  (0x%04lX)", pObject->GetNormalOffset(), pObject->GetNormalOffset());
  m_NormalsOffsetText.SetWindowText(Buffer);

  Buffer.Format("%ld  (0x%04lX)", pObject->GetPointOffset(), pObject->GetPointOffset());
  m_PointOffsetText.SetWindowText(Buffer);

  Buffer.Format("%ld  (0x%04lX)", pObject->GetData2Offset(), pObject->GetData2Offset());
  m_Data2OffsetText.SetWindowText(Buffer);

  Buffer.Format("%ld  (0x%04lX)", pObject->GetFaceOffset(), pObject->GetFaceOffset());
  m_FaceOffsetText.SetWindowText(Buffer);

  Buffer.Format("%ld", pObject->GetNumData2());
  m_Data2CountText.SetWindowText(Buffer);

  Buffer.Format("%ld", pObject->GetNumFaces());
  m_FaceCountText.SetWindowText(Buffer);

  Buffer.Format("%ld", pObject->GetNumPoints());
  m_PointCountText.SetWindowText(Buffer);

  Buffer.Format("%4.4s", pObject->GetVersion());
  m_VersionText.SetWindowText(Buffer);
 }
/*===========================================================================
 *		End of Class Method CDfto3dsView::SetObjectTexts()
 *=========================================================================*/


/*===========================================================================
 *
 * Class CDfto3dsView Event - void OnUpdateFileExportdxf (pCmdUI);
 *
 *=========================================================================*/
void CDfto3dsView::OnUpdateFileExportdxf(CCmdUI* pCmdUI) {

  if (IsSelectedObjectValid())  
    pCmdUI->Enable(TRUE);
  else
    pCmdUI->Enable(FALSE);

 }
/*===========================================================================
 *		End of Class Event CDfto3dsView::OnUpdateFileExportdxf()
 *=========================================================================*/


/*===========================================================================
 *
 * Class CDfto3dsView Event - void OnFileExportdxf ();
 *
 *=========================================================================*/
void CDfto3dsView::OnFileExportdxf() {
  CDfto3dsDoc*  pDocument = GetDocument();
  CDF3dObject*  pObject = pDocument->GetCurrentObject();
  CString	Filename;
  char		DialogTitle[] = "Export DXF File";
  int           Result;

	/* Ensure there is something to export */
  if (!IsSelectedObjectValid()) {
    ErrorHandler.AddError(ERR_BADINPUT, "No Daggerfall 3D object selected to export!");
    ErrorHandler.Notify("Export DXF Error!");
    return;
   }

	 /* Initialize the file dialog */
  Filename.Format ("%s%08lX.dxf", (const char*)GetExport3DSPath(), pDocument->GetFileValue(m_ObjectList.GetCurSel()));
  CFileDialog   FileDlg(FALSE, ".DXF", Filename, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
			"DXF Files (*.dxf)|*.dxf|All Files (*.*)|*.*||", NULL);
  FileDlg.m_ofn.lpstrTitle = DialogTitle;

	/* Ask user for filename */
  Result = FileDlg.DoModal();
  if (Result != IDOK) return;

	/* Get filename to load and update registry paths */
  Filename = FileDlg.GetPathName();
  SetExportDXFPath(FileDlg.GetPathName());

	/* Attempt to export the file */
  Result = ExportDF3dObjectToDXF(Filename, *pObject);
  if (!Result) ErrorHandler.Notify("Export DXF Error!");
 }
/*===========================================================================
 *		End of Class Event CDfto3dsView::OnFileExportdxf()
 *=========================================================================*/


/*===========================================================================
 *
 * Class CDfto3dsView Event - void OnFileExport3ds ();
 *
 *=========================================================================*/
void CDfto3dsView::OnFileExport3ds() {
  CDfto3dsDoc*  pDocument = GetDocument();
  CDF3dObject*  pObject = pDocument->GetCurrentObject();
  CString	Filename;
  char		DialogTitle[] = "Export 3DS File";
  int           Result;

	/* Ensure there is something to export */
  if (!IsSelectedObjectValid()) {
    ErrorHandler.AddError(ERR_BADINPUT, "No Daggerfall 3D object selected to export!");
    ErrorHandler.Notify("Export 3DS Error!");
    return;
   }

	/* Initialize the file dialog */
  Filename.Format ("%s%08lX.3ds", (const char*)GetExport3DSPath(), pDocument->GetFileValue(m_ObjectList.GetCurSel()));
  CFileDialog  FileDlg(FALSE, ".3DS", Filename, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
			"3DS Files (*.3ds)|*.3ds|All Files (*.*)|*.*||", NULL);
  FileDlg.m_ofn.lpstrTitle = DialogTitle;

	/* Ask user for filename */
  Result = FileDlg.DoModal();
  if (Result != IDOK) return;

  	/* Get filename to load and update registry paths */
  Filename = FileDlg.GetPathName();
  SetExport3DSPath(FileDlg.GetPathName());

	/* Attempt to export the file */
  Result = ExportDF3dObjectTo3DS(Filename, *pObject);
  if (!Result) ErrorHandler.Notify("Export 3DS Error!");
 }
/*===========================================================================
 *		End of Class Event CDfto3dsView::OnFileExport3ds()
 *=========================================================================*/


/*===========================================================================
 *
 * Function - void CDfto3dsView::OnFileExportAll3ds (void);
 *
 * Debug function that outputs all the Daggerfall 3D objects to the
 * appropriately named 3DS file.  
 *
 *=========================================================================*/
void CDfto3dsView::OnFileExportAll3ds () {
  DEFINE_FUNCTION("CDfto3dsView::OnFileExportAll3ds()");
  CDfExport3dsDialog ExportDialog;
  CDfto3dsDoc*  pDocument = GetDocument();
  CString	Filename;
  char		DialogTitle[] = "Export All 3DS Files";
  int           Result;

	/* Ensure the user wishes to continue */
  Result = MessageBox("This option will attempt to export all Daggerfall's 3D objects to 3DS\r\nfiles.  This produces 11,000 3DS and BMP files taking up 40 MB\r\nof space to the chosen directory.  Do you wish to continue?", "DFto3DS: Export All to 3DS", MB_OKCANCEL | MB_ICONQUESTION );
  if (Result != IDOK) return;

	/* Initialize the file dialog */
  Filename.Format ("%s0000000.3ds", (const char*)GetExport3DSPath());
  CFileDialog  FileDlg(FALSE, ".3DS", Filename, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
			"3DS Files (*.3ds)|*.3ds|All Files (*.*)|*.*||", NULL);
  FileDlg.m_ofn.lpstrTitle = DialogTitle;

	/* Ask user for filename */
  Result = FileDlg.DoModal();
  if (Result != IDOK) return;

  	/* Get filename to load and update registry paths */
  Filename = FileDlg.GetPathName();
  SetExport3DSPath(FileDlg.GetPathName());

	/* Attempt to export each of the 3DS files */
  Result = pDocument->ExportAll3DS(ExportDialog);
  if (!Result) ErrorHandler.Notify("Export 3DS Error!");

	/* Update the currently selected item */
  OnSelchangeArch3dobjectList();
 }
/*===========================================================================
 *		End of Class Event CDfto3dsView::OnFileExportAll3ds()
 *=========================================================================*/


/*===========================================================================
 *
 * Class CDfto3dsView Event - void OnContextMenu (pWnd, Point);
 *
 *=========================================================================*/
void CDfto3dsView::OnContextMenu(CWnd* pWnd, CPoint Point) {
  CMenu  Menu;
  CMenu* pPopupMenu;

	/* Ignore if not the object list control */
  if (pWnd->GetDlgCtrlID() != IDC_ARCH3DOBJECT_LIST) return;
  VERIFY(Menu.LoadMenu(IDR_OBJECTLIST_MENU));
  pPopupMenu = Menu.GetSubMenu(0);
  ASSERT(pPopupMenu != NULL);

  pPopupMenu->TrackPopupMenu (TPM_LEFTALIGN | TPM_RIGHTBUTTON, Point.x, Point.y, this);
 }
/*===========================================================================
 *		End of Class Event CDfto3dsView::OnContextMenu()
 *=========================================================================*/


/*===========================================================================
 *
 * Class CDfto3dsView Event - LRESULT OnHelpHitTest (wParam, lParam);
 *
 *=========================================================================*/
LRESULT CDfto3dsView::OnHelpHitTest(WPARAM, LPARAM lParam) {
  POINT Point;
  Point.x = LOWORD(lParam);
  Point.y = HIWORD(lParam);
  
  CWnd* pWnd = ChildWindowFromPoint(Point, CWP_SKIPINVISIBLE | CWP_SKIPDISABLED | CWP_SKIPTRANSPARENT);

  if (pWnd == NULL || pWnd->m_hWnd == this->m_hWnd) {
    return (IDD_DFTO3DS_FORM + HID_BASE_RESOURCE);
   }

  //(GetDlgCtrlID() + HID_BASE_RESOURCE);
  return (pWnd->GetDlgCtrlID() + HID_BASE_CONTROL);
 }
/*===========================================================================
 *		End of Class Event CDfto3dsView::OnHelpHitTest()
 *=========================================================================*/