/////////////////////////////////////////////////////////////////////
// (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.
//
//
/////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "acm.h"
#include "acmdef.h"
#include "cauxent.h"
#include "symstd.h"
#include "leader.h"
#include "symbol.h"
#include "Weldsym.h"

#include "mibase.h"
#include "migeom.h"
#include "miStatus.h"

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

//MCAD API
AmiStatus amiPick2 ( TCHAR* prompt, AmiKeyType type, struct resbuf* entmask,
                    AmiPickObj& pickObj, Adesk::Boolean allowGhost );
AmiStatus amiGetKeyFromPick ( AmiPickObj* pPickObj, AmiKeyType& type, 
                              AmiObjectKey*& pObjKey );


Adesk::Boolean
setWeldingValues(AcmWelding* pWelding)
{
  AcmWeldingStd *pWeldStd;
  if (Acad::eOk != acdbOpenObject(pWeldStd,pWelding->serverId(),AcDb::kForRead))
    return Adesk::kFalse;

  //set default subwelding as empty
  pWelding->setType(Acm::kNoneSymbol,Adesk::kTrue);
  pWelding->setType(Acm::kNoneSymbol,Adesk::kFalse);

  //set welding symbol as field all-around weld
  pWelding->setFieldWeld(Adesk::kTrue);
  pWelding->setAreaDescType(Acm::kWeldAllAround);

  //get all supported weld types from standard
  AcmCObjArray<AcmCSymbolDesc> weldList;
  pWeldStd->getWelds(pWelding->subWelding(0), Acm::kForArrowSide, weldList);

  //printout welds selection
  acutPrintf(_T("\nOffered welds for arrow side:"));
  acutPrintf(_T("\n  0 : None weld symbol"));
  AcmCWeldService *pServ;
  for (int register i=0;i<weldList.length();i++) {
    pServ = pWeldStd->getService(weldList[i]->type());
    assert(pServ);
    acutPrintf(_T("\n%3d : %s"),i+1,pServ->serviceName());
  }
  
  //user have select weld type
  int ret = 0;
  int rc = ads_getint(_T("\n\nSelect weld type :"),&ret);
  if ((rc != RTNORM) || (ret < 0) || (ret > weldList.length())) {
    pWeldStd->close();
    return Adesk::kFalse;
  }
  //set selected weld type
  if (ret == 0) {
    pWelding->setType(Acm::kNoneSymbol);
    return Adesk::kTrue;
  } else {
    pWelding->setType(weldList.at(ret-1)->type());
  }
  
  //init texts, labels and other values in symbol for obtain dlgInfo
  //It also inits variables which are possible to set for selected weld types
  //each weld type should have only several valid values such are size,depth,pitch...
  //This also checks all associations between welds on arrow and other side
  //(it should be identification line, ...)
  //You can call AcmCWeldService::initFields separately for each valid AcmCWeld
  //in each subwelding. Following function call initialization for whole subwelding
  pWeldStd->initFields(pWelding->subWelding(0));
  pWeldStd->close();

  //allow user to select all valid values for selected weld type
  Acm::Variable wVar[] = { Acm::WeldSize, Acm::WeldThickness, Acm::WeldLength,
    Acm::WeldNumber, Acm::WeldSpacing, Acm::WeldAngle, Acm::WeldDepth, Acm::WeldPitch,
    Acm::WeldGap, Acm::WeldClearance, Acm::WeldBacking,Acm::WeldNotes };

  int size = sizeof(wVar) / sizeof(wVar[0]);
  acutPrintf(_T("\nSet values for:\n"));

  CString prompt;
  for (int i=0;i<size;i++) {
    //is value valid for selected type
    if (pWelding->variableStatus(wVar[i]) != Acm::kVisible) continue;

    //obtain information (label text only in our case)
    CVarDlgInfo dlgInfo;
    pWelding->getVarDlgInfo(wVar[i],dlgInfo);
    
    //user set new value
    CString resultStr;
    prompt.Format(_T("%s :"),dlgInfo.label());
    rc = ads_getstring(1,prompt,resultStr.GetBuffer(133));
    resultStr.ReleaseBuffer();
    if (rc == RTCAN) return Adesk::kFalse;
    
    //value set to the symbol
    pWelding->setValue(wVar[i],(LPCTSTR)resultStr);
  }

  return Adesk::kTrue;
}

// test example how to create welding - symbol with simple leader, no landing
void welding()
{
  // create new instance of AcmWelding and set symbol defaults
  AcmWelding *pWelding = new AcmWelding(); 
  assert(pWelding);
  if( pWelding->setSymbolDefaults() != Acm::eOk) {
    acutPrintf(_T("\nCannot setup welding symbol for current standard."));
    delete pWelding;
    return;
  }

  // get starting and ending point of leader
  int res;
  AcGePoint3dArray ptArr;
  for( int i = 0; i<2; i++ ) {
    AcGePoint3d pt;
    res = ads_getpoint(NULL, _T("\nSelect point :"),asDblArray(pt));
    if (res != RTNORM){
      delete pWelding;
      return;
    }
    ptArr.append(pt);
  }
  pWelding->addLeader(ptArr);

  //set orientation of welding symbol
  if (ptArr[0].x < ptArr[1].x)
    pWelding->setOrientation(Acm::kRightSide);
  else
    pWelding->setOrientation(Acm::kLeftSide);

  // set values for welding
  if (!setWeldingValues(pWelding)) {
     delete pWelding;
     return;
  }
  
  // Post to Database
  //
  AcDbObjectId objId;
  if (postToDb(pWelding, objId) != Acad::eOk) {
    delete pWelding;
    return;
  }

  AmiPickObj pickObj;
  AmiObjectKey* pKey = NULL;
  Ami::KeyType type;
  AmiStatus as = Ami::eOk;
  as = amiPick2( _T("Select geometry:"), Ami::curveKey, NULL, pickObj, Adesk::kFalse);
  if (as.success()) {
    as = amiGetKeyFromPick(&pickObj, type, pKey);
    if (as.failure()) {
      TSTDSTRING strErrText = as.text();
      acutPrintf(_T("\nFail to get selected geometry. %s"), strErrText.c_str());
    }
  }
  //You can attach symbol now. attachGeomRef accept only keys derived from
  //AmiGeomKey.
  if (pKey) {
    Acm::ErrorStatus es = pWelding->attachGeomRef(pKey, AcGePoint3d::kOrigin);
    if (Acm::eOk != es)
      acutPrintf(_T("\nFail to attach to geometry"));

    pKey->release();
  }

  pWelding->close();
}
