//////////////////////////////////////////////////////////////////////////////
//
//  Copyright 2025 Autodesk, Inc.  All rights reserved.
//
//  Use of this software is subject to the terms of the Autodesk license 
//  agreement provided at the time of installation or download, or which 
//  otherwise accompanies this software in either electronic or hard copy form.   
//
//////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////
//
// detail looks like a circle (in which the user draws details of some 
// parts from drawing) and (optional) leader to text describing the detail
//
// registered commands:
// ADDDETAILSTD - ads standard for detail
// DETAIL - draws a detail in current drawing
// EDITDETAILSTD - allows user to edit detail standard (just a little)
//
//////////////////////////////////////////////////////////////////////

// includes from ObjectARX Wizard
#ifdef _DEBUG
#ifndef _ARXDEBUG
#define _DEBUG_WAS_DEFINED
#undef _DEBUG
#endif //_ARXDEBUG
#endif //_DEBUG
#include "stdafx.h"           // MFC stuff
#ifdef _DEBUG_WAS_DEFINED
#define _DEBUG
#undef _DEBUG_WAS_DEFINED
#endif
// TODO: add your own includes here
#include "editExt_crx.h"
#include "Detail.h"
#include "DetailDlg.h"

// entry point for this application
extern "C" AcRx::AppRetCode acrxEntryPoint( AcRx::AppMsgCode msg, void* );
// message handlers
static void OnkEndMsg      (void);
static void OnkQuitMsg     (void);
static void OnkDependencyMsg(void);
static void OnkNoDependencyMsg(void);
static void OnkPreQuitMsg  (void);
static void OnkLoadDwgMsg  (void);
static void OnkUnloadDwgMsg(void);
static void OnkInvkSubrMsg (void);

// helper functions
static void initApp  (void);
static void unloadApp(void);

// MFC support
extern "C" HINSTANCE _hdllInstance;
extern HWND adsw_acadMainWnd();
extern void InitMFC();
extern void EndMFC();
BOOL InitModule(HINSTANCE, DWORD, LPVOID);

// TODO: add your declarations here or in GB.h
void addDetailStd();
void detail();
void editDetailStd();

// end of declaration

/////////////////////////////////////////////////////////////////////
// acrxEntryPoint(internal)
// This function is the entry point for your application.
/////////////////////////////////////////////////////////////////////
AcRx::AppRetCode acrxEntryPoint(AcRx::AppMsgCode msg, void* ptr)
{
 // AcRx::AppRetCode retVal = AcRx::kRetOK;

 switch (msg) {
    case AcRx::kInitAppMsg:
	 		acrxDynamicLinker->unlockApplication(ptr);
			acrxDynamicLinker->registerAppMDIAware(ptr);
      initApp();
      break;
    case AcRx::kUnloadAppMsg:
      unloadApp();
      break;
    case AcRx::kEndMsg:
      OnkEndMsg();
      break;
    case AcRx::kQuitMsg:
      OnkQuitMsg();
      break;
    case AcRx::kDependencyMsg:
      OnkDependencyMsg();
      break;
    case AcRx::kNoDependencyMsg:
      OnkNoDependencyMsg();
      break;
    case AcRx::kPreQuitMsg:
      OnkPreQuitMsg();
      break;
    case AcRx::kLoadDwgMsg:
      OnkLoadDwgMsg();
      break;
    case AcRx::kUnloadDwgMsg:
      OnkUnloadDwgMsg();
      break;
    case AcRx::kInvkSubrMsg:
      OnkInvkSubrMsg();
      break;
    default:
      break;
  }
  return AcRx::kRetOK;
}


static void OnkEndMsg(void)
{
  // TODO: add your message handler code here

  // end of message handler
}
static void OnkQuitMsg(void)
{
  // TODO: add your message handler code here

  // end of message handler
}
static void OnkDependencyMsg(void)
{
  // TODO: add your message handler code here

  // end of message handler
}
static void OnkNoDependencyMsg(void)
{
  // TODO: add your message handler code here

  // end of message handler
}
static void OnkPreQuitMsg(void)
{
  // TODO: add your message handler code here

  // end of message handler
}
static void OnkLoadDwgMsg(void)
{
  // TODO: add your message handler code here

  // end of message handler
}
static void OnkUnloadDwgMsg(void)
{
  // TODO: add your message handler code here

  // end of message handler
}
static void OnkInvkSubrMsg(void)
{
  // TODO: add your message handler code here

  // end of message handler
}

static TestDetailStdReactor *pStdReact = NULL;

static void initApp(void)
{
  InitMFC();
  // TODO: init your application

   TestDetail::rxInit();
   TestDetailStd::rxInit();
   acrxBuildClassHierarchy();
   // add editing extension protocol
   TestDetailStd::desc()->addX(AcmCEditExt::desc(),new AcmCTestDetailEditExt);

   //  we have to add out reactor to stdManager.
   pStdReact = new TestDetailStdReactor();
   acmStdMgr->attachReactor(pStdReact);

   // commands (see we do not need the first two)
   acedRegCmds->addCommand(_T("TESTAPP"),_T("ADDDETAILSTD"),_T("ADDDETAILSTD"),
                        ACRX_CMD_MODAL |
                        ACRX_CMD_USEPICKSET,
                        addDetailStd);
   acedRegCmds->addCommand(_T("TESTAPP"),_T("EDITDETAILSTD"),_T("EDITDETAILSTD"),
                        ACRX_CMD_MODAL |
                        ACRX_CMD_USEPICKSET,
                        editDetailStd);
   acedRegCmds->addCommand(_T("TESTAPP"),_T("DETAIL"),_T("DETAIL"),
                        ACRX_CMD_MODAL |
                        ACRX_CMD_USEPICKSET,
                        detail);
} // END initApp()

static void unloadApp(void)
{

  acedRegCmds->removeGroup(_T("TESTAPP"));

  acmStdMgr->removeReactor(pStdReact);
  delete pStdReact;

  AcRxObject* pProtocolObj = (TestDetailStd::desc())->delX(AcmCEditExt::desc());
  if (pProtocolObj) delete pProtocolObj;

  // TODO: clean up your application
  deleteAcRxClass(TestDetail::desc());
  deleteAcRxClass(TestDetailStd::desc());

  // END unloadApp()
  EndMFC();
}


// MFC Initialization

#define APP_ARX_NAME _T("Detail.arx")

void InitMFC()
{
  InitModule(GetModuleHandle(APP_ARX_NAME), DLL_PROCESS_ATTACH, NULL);
}

void EndMFC()
{
  InitModule(GetModuleHandle(APP_ARX_NAME), DLL_PROCESS_DETACH, NULL);
}

static AFX_EXTENSION_MODULE arxmfcDLL;

extern BOOL InitModule(HINSTANCE hInstance, DWORD dwReason, LPVOID)
{
  if (dwReason == DLL_PROCESS_ATTACH) {
    if (!AfxInitExtensionModule(arxmfcDLL, hInstance))
      return 0;

    CTemporaryResourceOverride::SetDefaultResource(GetModuleHandle(APP_ARX_NAME));
    // TODO: add other initialization tasks here

    // end of initialization
  } else if (dwReason == DLL_PROCESS_DETACH) {
    AfxTermExtensionModule(arxmfcDLL);
    // TODO: perform other cleanup tasks here

    // end of cleanup
  }
  return 1;
}



// TODO: add your other functions here
// TODO: add your other functions here
Acad::ErrorStatus postToDb(AcDbEntity* ent, AcDbObjectId& objId)
{
  Acad::ErrorStatus      es;
  AcDbBlockTable*        pBlockTable;
  AcDbBlockTableRecord*  pSpaceRecord;

  if ((es = acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable, AcDb::kForRead)) != Acad::eOk) return es;

  //  Determine appropriate space from AutoCAD core function isPspace()
  if ((es = pBlockTable->getAt(ACDB_MODEL_SPACE,pSpaceRecord, AcDb::kForWrite)) != Acad::eOk) return es;
  if ((es = pBlockTable->close()) != Acad::eOk) return es;
  if ((es = pSpaceRecord->appendAcDbEntity(objId, ent)) != Acad::eOk) return es;
  // be carefull, entity remains opened.
  return pSpaceRecord->close();
}

// END
