/////////////////////////////////////////////////////////////////////
// (C) Copyright 1993-2005 by Autodesk, Inc. 
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted, 
// provided that the above copyright notice appears in all copies and 
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting 
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS. 
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE.  AUTODESK, INC. 
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to 
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable.
//
//
/////////////////////////////////////////////////////////////////////
// includes from ObjectARX Wizard
#ifdef _DEBUG
#define _DEBUG_WAS_DEFINED
#undef _DEBUG
#endif
#include "stdafx.h"           // MFC stuff
#ifdef _DEBUG_WAS_DEFINED
#define _DEBUG
#undef _DEBUG_WAS_DEFINED
#endif
//#include <afxtempl.h>
// TODO: add your own includes here

// 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 "C" HWND adsw_acadMainWnd();
extern void InitMFC();
extern void EndMFC();
BOOL InitModule(HINSTANCE, DWORD, LPVOID);

// TODO: add your declarations here
Acad::ErrorStatus postToDb(AcDbEntity* ent, AcDbObjectId& objId);
void setPartData();
void getPartData();
void allPartData();

void createBomTable();
void createBorderBomTable();
void getBomTable();
void setBomTableData();
void eraseBomTable();

void createItem();
void createItemUnassoc();
void getItemRef();
void findItemItemNo();
void setItemNo();
void setItemRef();
void eraseItemItemNo();
void eraseItemRef();

void removeRef();
void addRef();
void addGrRep();
void removeGrRep();

void createPartData();

// Functions for new APIs added in ACM2007
void exportBOM();
void importBOM();
void setPartAttribute();
void setItemAttribute();
void mergeItems();
void getItemBalloons();
void getItemDefinition();
void getItemExtendedData();
void setItemExtendedData();

// 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 void initApp(void)
{
  InitMFC();
  // TODO: init your application

   acedRegCmds->addCommand(_T("TESTAPP"),_T("SETPARTDATA"),_T("SETPARTDATA"),
                        ACRX_CMD_MODAL |
                        ACRX_CMD_USEPICKSET,
                        setPartData);
   acedRegCmds->addCommand(_T("TESTAPP"),_T("GETPARTDATA"),_T("GETPARTDATA"),
                        ACRX_CMD_MODAL |
                        ACRX_CMD_USEPICKSET,
                        getPartData);
   acedRegCmds->addCommand(_T("TESTAPP"),_T("ALLPARTDATA"),_T("ALLPARTDATA"),
                        ACRX_CMD_MODAL |
                        ACRX_CMD_USEPICKSET,
                        allPartData);
   acedRegCmds->addCommand(_T("TESTAPP"),_T("CREATEPARTDATA"),_T("CREATEPARTDATA"),
                        ACRX_CMD_MODAL |
                        ACRX_CMD_USEPICKSET,
                        createPartData);

   acedRegCmds->addCommand(_T("TESTAPP"),_T("CREATEBOMTABLE"),_T("CREATEBOMTABLE"),
                        ACRX_CMD_MODAL |
                        ACRX_CMD_USEPICKSET,
                        createBomTable);
   acedRegCmds->addCommand(_T("TESTAPP"),_T("CREATEBORDERBOMTABLE"),_T("CREATEBORDERBOMTABLE"),
                        ACRX_CMD_MODAL |
                        ACRX_CMD_USEPICKSET,
                        createBorderBomTable);
   acedRegCmds->addCommand(_T("TESTAPP"),_T("GETBOMTABLE"),_T("GETBOMTABLE"),
                        ACRX_CMD_MODAL |
                        ACRX_CMD_USEPICKSET,
                        getBomTable);
   acedRegCmds->addCommand(_T("TESTAPP"),_T("SETBOMTABLEDATA"),_T("SETBOMTABLEDATA"),
                        ACRX_CMD_MODAL |
                        ACRX_CMD_USEPICKSET,
                        setBomTableData);
   acedRegCmds->addCommand(_T("TESTAPP"),_T("ERASEBOMTABLE"),_T("ERASEBOMTABLE"),
                        ACRX_CMD_MODAL |
                        ACRX_CMD_USEPICKSET,
                        eraseBomTable);

   acedRegCmds->addCommand(_T("TESTAPP"),_T("CREATEITEM"),_T("CREATEITEM"),
                        ACRX_CMD_MODAL |
                        ACRX_CMD_USEPICKSET,
                        createItem);
   acedRegCmds->addCommand(_T("TESTAPP"),_T("CREATEITEMU"),_T("CREATEITEMU"),
                        ACRX_CMD_MODAL |
                        ACRX_CMD_USEPICKSET,
                        createItemUnassoc);
   acedRegCmds->addCommand(_T("TESTAPP"),_T("GETITEMREF"),_T("GETITEMREF"),
                        ACRX_CMD_MODAL |
                        ACRX_CMD_USEPICKSET,
                        getItemRef);
   acedRegCmds->addCommand(_T("TESTAPP"),_T("FINDITEMNO"),_T("FINDITEMNO"),
                        ACRX_CMD_MODAL |
                        ACRX_CMD_USEPICKSET,
                        findItemItemNo);
   acedRegCmds->addCommand(_T("TESTAPP"),_T("SETITEMREF"),_T("SETITEMREF"),
                        ACRX_CMD_MODAL |
                        ACRX_CMD_USEPICKSET,
                        setItemRef);
   acedRegCmds->addCommand(_T("TESTAPP"),_T("SETITEMNO"),_T("SETITEMNO"),
                        ACRX_CMD_MODAL |
                        ACRX_CMD_USEPICKSET,
                        setItemNo);
   acedRegCmds->addCommand(_T("TESTAPP"),_T("ERASEITEMREF"),_T("ERASEITEMREF"),
                        ACRX_CMD_MODAL |
                        ACRX_CMD_USEPICKSET,
                        eraseItemRef);
   acedRegCmds->addCommand(_T("TESTAPP"),_T("ERASEITEMNO"),_T("ERASEITEMNO"),
                        ACRX_CMD_MODAL |
                        ACRX_CMD_USEPICKSET,
                        eraseItemItemNo);

   acedRegCmds->addCommand(_T("TESTAPP"),_T("ADDREF"),_T("ADDREF"),
                        ACRX_CMD_MODAL |
                        ACRX_CMD_USEPICKSET,
                        addRef);
   acedRegCmds->addCommand(_T("TESTAPP"),_T("REMOVEREF"),_T("REMOVEREF"),
                        ACRX_CMD_MODAL |
                        ACRX_CMD_USEPICKSET,
                        removeRef);
   acedRegCmds->addCommand(_T("TESTAPP"),_T("ADDGRREP"),_T("ADDGRREP"),
                        ACRX_CMD_MODAL |
                        ACRX_CMD_USEPICKSET,
                        addGrRep);
   acedRegCmds->addCommand(_T("TESTAPP"),_T("REMOVEGRREP"),_T("REMOVEGRREP"),
                        ACRX_CMD_MODAL |
                        ACRX_CMD_USEPICKSET,
                        removeGrRep);

   // Commands for new APIs added in ACM2007
   acedRegCmds->addCommand(_T("TESTAPP"),_T("EXPORTBOM"),_T("EXPORTBOM"),
                        ACRX_CMD_MODAL |
                        ACRX_CMD_USEPICKSET,
                        exportBOM);
   acedRegCmds->addCommand(_T("TESTAPP"),_T("IMPORTBOM"),_T("IMPORTBOM"),
                        ACRX_CMD_MODAL |
                        ACRX_CMD_USEPICKSET,
                        importBOM);

   acedRegCmds->addCommand(_T("TESTAPP"),_T("SETPARTATTRIBUTE"),_T("SETPARTATTRIBUTE"),
                        ACRX_CMD_MODAL |
                        ACRX_CMD_USEPICKSET,
                        setPartAttribute);
   acedRegCmds->addCommand(_T("TESTAPP"),_T("SETITEMATTRIBUTE"),_T("SETITEMATTRIBUTE"),
                        ACRX_CMD_MODAL |
                        ACRX_CMD_USEPICKSET,
                        setItemAttribute);

   acedRegCmds->addCommand(_T("TESTAPP"),_T("MERGEITEMS"),_T("MERGEITEMS"),
                        ACRX_CMD_MODAL |
                        ACRX_CMD_USEPICKSET,
                        mergeItems);
   acedRegCmds->addCommand(_T("TESTAPP"),_T("GETITEMBALLOONS"),_T("GETITEMBALLOONS"),
                        ACRX_CMD_MODAL |
                        ACRX_CMD_USEPICKSET,
                        getItemBalloons);

   acedRegCmds->addCommand(_T("TESTAPP"),_T("GETITEMDEFINITION"),_T("GETITEMDEFINITION"),
                        ACRX_CMD_MODAL |
                        ACRX_CMD_USEPICKSET,
                        getItemDefinition);

   acedRegCmds->addCommand(_T("TESTAPP"),_T("GETITEMEXTENDEDDATA"),_T("GETITEMEXTENDEDDATA"),
                        ACRX_CMD_MODAL |
                        ACRX_CMD_USEPICKSET,
                        getItemExtendedData);

   acedRegCmds->addCommand(_T("TESTAPP"),_T("SETITEMEXTENDEDDATA"),_T("SETITEMEXTENDEDDATA"),
                        ACRX_CMD_MODAL |
                        ACRX_CMD_USEPICKSET,
                        setItemExtendedData);

} // END initApp()

static void unloadApp(void)
{
   acedRegCmds->removeGroup(_T("TESTAPP"));

  // TODO: clean up your application

  // END unloadApp()
  EndMFC();
}

#define APP_ARX_NAME _T("TestBom.arx")

// MFC Initialization

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
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
