//////////////////////////////////////////////////////////////////////////////
//
//  Copyright 2025 by Autodesk, Inc.  All rights reserved.
//
// This computer source code and related instructions and comments 
// are the unpublished confidential and proprietary information of 
// Autodesk, Inc. and are protected under applicable copyright and 
// trade secret law.  They may not be disclosed to, copied or used 
// by any third party without the prior written consent of Autodesk, Inc.
//
//////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "acm.h"
#include "acmdef.h"
#include "cauxent.h"
#include "symstd.h"
#include "leader.h"
#include "symbol.h"
#include "stdMgr.h"
#include "surfsym.h"
#include "surfsymlib.h"
#include "dbobjptr.h"

Acad::ErrorStatus postToDb(AcDbEntity* ent, AcDbObjectId& objId);

// creating symbol with leader - landing is expected.
void surftext()
{
  // Create Surface Texture object on current UCS plan
  AcmSurfaceTexture* pSurfaceTexture = new AcmSurfaceTexture();
  if (pSurfaceTexture->setSymbolDefaults() != Acm::eOk) {
    acutPrintf(_T("\nCannot setup surface symbol for current standard."));
    delete pSurfaceTexture;
    return;
  }

  // Prompt for symbol library to be used for the created symbol
  Acad::ErrorStatus es = Acad::eOk;
  bool isSymLibExist = false;
  ACHAR symLibName[133];
  AcDbObjectId symLibId = AcDbObjectId::kNull;
  AmdtSurfTextLibrary* pSurfTextLib = NULL;

  if (RTNORM == ads_getstring(0, _ACRX_T("Enter symbol library: "), symLibName, 133)) {
    // Get surface texture symbol library dictionary
    if (getAcmSurfaceTextureLibrary(symLibId, NULL, true)) {
      if (Acad::eOk == acdbOpenObject(pSurfTextLib, symLibId, AcDb::kForRead)) {
        // Get standard
        AcDbObjectPointer<AcmStandard> pStd(pSurfaceTexture->standardId(), AcDb::kForRead);
        es = pStd.openStatus();
        if (es == Acad::eOk) {
          // Get surface texture symbol standard
          AcDbObjectPointer<AcmSurfTextStd> pSurfTextStd(pSurfaceTexture->serverId(), AcDb::kForRead);
          es = pSurfTextStd.openStatus();
          if (es == Acad::eOk) {
            // Check if selected symbol library exist
            if (pSurfTextLib->isItemExist(symLibName, pStd->originalName(), pSurfTextStd->isA()->name()))
              isSymLibExist = true;
            else {
              acutPrintf(ACRX_T("\n%s cannot be found.\n"), symLibName);
            }
          }
        }
      }
    }
  }

  if (!isSymLibExist) {
    // create non-default symbol - be careful and don't delete this pointer !!
    AcmCSurfText *pSubSym = (AcmCSurfText*)pSurfaceTexture->getCSubSymbolsList()->activeSubSymbol();

    pSubSym->setValue(Acm::SurfTextRaMax,_T("Ra0.8"));
    pSubSym->setValue(Acm::SurfTextRaMin,_T("Ra0.2"));
  }

  // Add leader
  AcGePoint3dArray ptArr;
  for (int i=0; i<2; i++) {
    AcGePoint3d pt;
    int ret = ads_getpoint(NULL, _T("\nSelect point :"),asDblArray(pt));
    if( ret == RTCAN ) {
      ptArr.setLogicalLength(0);
      break;
    }
    if( ret == RTNONE ) break;
    ptArr.append(pt);
  }

  if (ptArr.length() == 0) {
    delete pSurfaceTexture;

    if (pSurfTextLib)
      pSurfTextLib->close();
 
    return;
  }

  if (ptArr.length() == 1) {
    pSurfaceTexture->setOrigin(ptArr[0]);
  }

  if (ptArr.length() == 2) {
    // autoAdjust is default.
    pSurfaceTexture->addLeader(ptArr);
    pSurfaceTexture->autoAdjust();
  }
  
  // Get the angle from the user if no Leader present 
  if (pSurfaceTexture->numOfLeaders() == 0) { 
    double ang = 0.0;
    if( ads_getangle(asDblArray(pSurfaceTexture->origin()),_T("\nSelect angle :"),&ang) == RTNORM)
      pSurfaceTexture->setAngle(ang);
  }

  // Post the new symbol to database
  AcDbObjectId objId;
  if (postToDb(pSurfaceTexture, objId) != Acad::eOk) {
    delete pSurfaceTexture;
    return;
  }

  if (pSurfTextLib) {
    // Load selected symbol library to the surface Texture symbol
    // Note that symbol library can only be loaded after the symbol is added to the database
    if (isSymLibExist) {
      if (Acad::eOk != pSurfTextLib->loadItem(symLibName, pSurfaceTexture)) {
        acutPrintf(ACRX_T("\nFail to load the selected symbol library.\n"));
      }
    }
    // Add the specified symbol library with the settings of the created symbol
    else {
      if (Acad::eOk == pSurfTextLib->upgradeOpen()) {
        AcDbObjectId symLibObjId = AcDbObjectId::kNull;
        if (Acad::eOk != pSurfTextLib->appendItem(symLibName, pSurfaceTexture, symLibObjId)) {
          acutPrintf(ACRX_T("\nFail to add the symbol library.\n"));
        }
      }
    }

    pSurfTextLib->close();
  }
 
  pSurfaceTexture->close();
}


void surfList()
{
  ads_name entres;
  ads_point ptres;
  if( ads_entsel(_T("\nSelect Surface Texture symbol :"), entres,ptres) != RTNORM) return;

  AcDbObjectId surfId;

  if( acdbGetObjectId(surfId,entres) != Acad::eOk ) return;

  actrTransactionManager->startTransaction();

  AcDbObject* pObj;
  if( actrTransactionManager->getObject(pObj,surfId,AcDb::kForWrite) != Acad::eOk) {
     actrTransactionManager->abortTransaction();
     return;
  }

  AcmSurfaceTexture *pSurf = AcmSurfaceTexture::cast(pObj);
  if( !pSurf) {
     acutPrintf(_T("\nObject is not a surface texture."));
     actrTransactionManager->abortTransaction();
     return;
  }

  if( actrTransactionManager->getObject(pObj, pSurf->serverId(), AcDb::kForWrite) != Acad::eOk ){
     actrTransactionManager->abortTransaction();
    return;
  }
  
  AcmSurfTextStd *pServer = AcmSurfTextStd::cast(pObj);
  if( !pServer ) {
     actrTransactionManager->abortTransaction();
     return;
  }
  acutPrintf(_T("\nDetailed Surface Texture listing"));
  
  CString rev,msg;
  Adesk::UInt16 year;
  if( pServer->getRevision(rev,year) == Acm::eOk) {
    msg.Format(_T("\nServed by %s"),rev);
    acutPrintf(msg);
  }

  // supply standard dependent information
  pServer->initFields(pSurf->getCSubSymbolsList());
  pServer->checkVisibility(pSurf->getCSubSymbolsList());

  AcmCSurfText *pSubSym = (AcmCSurfText*)pSurf->getCSubSymbolsList()->activeSubSymbol();

  Acm::Variable var[] = { Acm::SurfTextRaMax,Acm::SurfTextRaMin,Acm::SurfTextProduction,
      Acm::SurfTextProduction2,Acm::SurfTextAllowance,Acm::SurfTextDirLay,Acm::SurfTextSampLeanght,
      Acm::SurfTextCutoff,Acm::SurfTextOtherValue,Acm::SurfTextOtherMin,Acm::SurfTextMaxRspac,
      Acm::SurfTextReference,Acm::SurfTextWavines,Acm::SurfTextComment };

  int size = sizeof(var) / sizeof(var[0]);
  CString str;       
  CVarDlgInfo dlgStat;
  LPCTSTR curValue;
  AcmCObjArray<AcmSymbolDesc4CL> dirLayLst;

  for (int i=0;i<size;i++) {
    if (Acm::kVisible == pSubSym->variableStatus(var[i])) {
      pSubSym->getVarDlgInfo(var[i],dlgStat);
      if( var[i] == Acm::SurfTextDirLay ) {
        // need to obtain the description for it :
        pServer->getLaySymbolList(dirLayLst);
        int dirLayNum = _ttoi(pSubSym->value(var[i]));
        AcmSymbolDesc4CL *pDesc = nullptr;
        int j;     
		for(j=0; j<dirLayLst.length(); j++) {
          pDesc =  dirLayLst[j];
          if( pDesc->info() ==  dirLayNum ) break;
        }
        if( j < dirLayLst.length()) {
          curValue = pDesc->description();
        }
        else {
          curValue = _T("");
        }
      }
      else {  
        curValue = pSubSym->value(var[i]);
      }
      acutPrintf(_T("\n%s : %s"), dlgStat.tooltip(),curValue);
    }
  }

  actrTransactionManager->endTransaction();
}
