////////////////////////////////////////////////////////////////////////////////
//
// gayka.cpp -    Visual C++ - 
//
////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <afxdllx.h> 
#include <initguid.h>

#include <libdb.h>
#include <libold.h>
#include <Libhppar.h>
#include "GaykaDlg.h"
#include <ksConstants.h>
#include "math.h"
#include "Gayka.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


//-------------------------------------------------------------------------------
// 
// ---
AFX_EXTENSION_MODULE StepDLL = { NULL, NULL };


//-------------------------------------------------------------------------------
//   
//    DLL
// ---
extern "C" int APIENTRY
DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved )
{
  UNREFERENCED_PARAMETER( lpReserved );

  if ( dwReason == DLL_PROCESS_ATTACH )
  {
    TRACE0( "DLL Initializing!" );
 
    if ( !AfxInitExtensionModule( StepDLL, hInstance ) )
      return 0;

    new CDynLinkLibrary( StepDLL );
  }
  else if ( dwReason == DLL_PROCESS_DETACH )
  {
    TRACE0( "DLL Terminating!" );
    AfxTermExtensionModule( StepDLL );
  }
  return 1;
}


//-------------------------------------------------------------------------------
//    (  )
// ---
void Gayka_K( float ls, float l, float d1, float s, float D, float l1, float H, short j, int j1, float d2, int j2 ) 
{
  float x[9], y[9];
  float c, h1, rb;
  float xc2, yc2, xcbl, ycbl, xcbp, ycbp, ycml;
  //   _
  // j1=1 -  , j1=0 -   
  // j2=1 -  1, j2=2 -  2

  D  = (float)( s / CosD( 30 ) );
  c  = (float)( ( D - d2 ) / 2 * TanD( 30 ) );
  h1 = (float)( D * 0.5 *  SinD( 30 ) );

  rb = ( h1 * h1 + c * c ) / 2 / c;

  x[1] = ls; y[1] = 0;
  if ( j2 == 1 )
  {
    x[2] = ls;       y[2] = (float)( j * ( d2 * 0.5 ) );
    x[3] = (ls + c); y[3] = (float)( j * ( D * 0.5 ) );
    x[7] = ls + c;   y[7] = j * h1;
  }
  else 
  {
    x[2] = ls; y[2] = (float)( j * ( D * 0.5 ) );
    x[7] = ls; y[7] = j * h1;
  }
  x[4] = ls + H - c; y[4] = (float)( j * ( D * 0.5 ) );
  x[5] = ls + H;     y[5] = (float)( j * ( d2 * 0.5 ) );
  x[6] = ls + H;     y[6] = 0;

  x[8] = ls + H - c; y[8] = j * h1;
  xc2  = ls + l;     yc2 = (float)( j * ( D * 0.5 - l1 ) );

  xcbl = ls + rb; ycbl = 0;
  xcbp = ls + H - rb; ycbp = 0;
  ycml = (float)( j * ( (D *0.5 - h1) / 2 + h1 ) );

  if ( j2 == 1) 
  {
    LineSeg( x[1], y[1], x[2], y[2], 1 );
    LineSeg( x[2], y[2], x[3], y[3], 1 );
    LineSeg( x[3], y[3], x[4], y[4], 1 );
    LineSeg( x[4], y[4], x[5], y[5], 1 );
    LineSeg( x[5], y[5], x[6], y[6], 1 );
    LineSeg( x[7], y[7], x[8], y[8], 1 );
    ArcByPoint( xcbl, ycbl, rb, x[1], y[1], x[7], y[7],(short) -j, 1 );
    ArcByPoint( xcbp, ycbp, rb, x[6], y[6], x[8], y[8], j, 1 );
    ArcBy3Points( ls + c * 0.5, (D * 0.5 - (D - d2) / 4) * j,
                  ls, ycml, x[7], y[7], 1 );
    ArcBy3Points( ls + H - c * 0.5, (D * 0.5 - (D - d2) / 4) * j, ls + H,
                  ycml, x[8], y[8], 1 );
  }
  else 
  {
    LineSeg( x[1], y[1], x[2], y[2], 1 );
    LineSeg( x[2], y[2], x[4], y[4], 1 );
    LineSeg( x[4], y[4], x[5], y[5], 1 );
    LineSeg( x[5], y[5], x[6], y[6], 1 );
    LineSeg( x[7], y[7], x[8], y[8], 1 );
    ArcByPoint( xcbp, ycbp, rb, x[6], y[6], x[8], y[8], j, 1 );
    ArcBy3Points( ls + H - c * 0.5, (D * 0.5 - (D - d2) / 4) * j,
                  ls + H, ycml, x[8], y[8], 1 );
  }

  if ( j1 == 1) 
  {
    Circle( xc2, yc2, d1 * 0.5, 1 );
    LineSeg( xc2 - 2, yc2, xc2 + 2, yc2, 2 );
    LineSeg( xc2, yc2 - 2, xc2, yc2 + 2, 2 );
  }
} 


//-------------------------------------------------------------------------------
//    (   )
// ---
void Gayka_K_Side( float ls, float s, float D, float d2, float H, int j, int j2 ) 
{
  float x, y;
  float x2, y2;
  // j2=1 -  1, j2=2 - 

  float c = (float)( ( D - d2 ) / 2 * tand( 30 ) );

  y = (float)( j * s * 0.5 );
  if (j2 == 1)  
  {
    x = ls + c;
    LineSeg( ls, 0, ls, j * d2 * 0.5, 1 );
    LineSeg( ls, j * d2 * 0.5, x, y, 1 );
    ArcBy3Points( ls + c, j * (s * 0.5), ls, s * 0.25 * j, ls + c, 0, 1 );
  }
  else 
  {
    x = ls;
    LineSeg( x, 0, x, y, 1 );
  }

  if ( j2 == 3 ) 
  {
    x2 =ls + H;
    y2 = y;
  }
  else 
  {
    x2 = ls + H - c;
    y2 = (float)( j * d2 * 0.5 );
  }
  LineSeg( x, y, x2, y, 1 );
  if ( j2 != 3 )  
  {
    LineSeg( x2, y, ls + H, y2 , 1 );
    ArcBy3Points( ls + H - c, j * (s * 0.5), ls + H,s * 0.25 * j,
                  ls + H - c, 0, 1 );
  }
  LineSeg( ls + H, y2, ls + H, 0, 1 );
  if ( j > 0 )
    LineSeg( x, 0, x2, 0, 1 );
}


//-------------------------------------------------------------------------------
//    (  -  )
// ---
void Gayka_K_Y( float ls, GAYKA5915 *tmp, int j ) 
{
  float h1;
  tmp->D = (float)( tmp->s / cosd( 30 ) );

  h1 = (float)( tmp->D * 0.5 * sind( 30 ) );

  LineSeg( ls, 0, ls, j * (tmp->D * 0.5 ), 1 );
  LineSeg( ls, j * ( tmp->D * 0.5), ls + tmp->h, j * (tmp->D * 0.5), 1 );
  LineSeg( ls + tmp->h, j * (tmp->D * 0.5), ls + tmp->h, 0, 1 );
  LineSeg( ls, j * h1, ls + tmp->h, j * h1, 1 );
} 


//-------------------------------------------------------------------------------
//    ( -/- )
// ---
void Gayka5915::Gayka_P_K( int j ) 
{
  float c, dd, c1 = 0, c2 = 0;
  float y, x = 0, x1, x2, x3, y3, y2;

  c = (float)( ( m_paramGayka.D - m_paramGayka.d2 ) / 2 * tand( 30 ) );

  if ( !(m_paramGayka.maskAdjustment & ISPOLN) && !(m_paramGayka.maskAdjustment & SIMPLE) )
    y = (float)( j * m_paramGayka.d2 * 0.5 );
  else
    y = (float)( j * m_paramGayka.D * 0.5 );

  LineSeg( 0, 0, 0, y, 1 );

  if ( !(m_paramGayka.maskAdjustment & ISPOLN) && !(m_paramGayka.maskAdjustment & SIMPLE) ) 
  {
    x = c;
    LineSeg( 0, y, x, j * (m_paramGayka.D * 0.5), 1 );
  }
  dd = (float)( m_paramGayka.dr - 2 * MODSTEP_REAL * m_paramGayka.p );

  if ( !(m_paramGayka.maskAdjustment & SIMPLE) ) 
  {
    x3 = m_paramGayka.h - c ;
    y3 = (float)( j * m_paramGayka.d2 * 0.5 );
    y2 = (float)( j * m_paramGayka.da * 0.5 );
  }
  else 
  {
    x3 = m_paramGayka.h;
    y3 = (float)( j * m_paramGayka.D * 0.5 );
    y2 = (float)( j * dd * 0.5 );
  }

  LineSeg( x, j * (m_paramGayka.D * 0.5), x3, j * m_paramGayka.D * 0.5, 1 );
  if ( !(m_paramGayka.maskAdjustment & SIMPLE) )
    LineSeg( x3, j * m_paramGayka.D * 0.5, m_paramGayka.h, y3, 1 );
  LineSeg( m_paramGayka.h, y3, m_paramGayka.h, 0, 1 );

  x1 = m_paramGayka.h;
  x2 = x1;
  if ( !(m_paramGayka.maskAdjustment & SIMPLE) ) 
  {
    c1 = (float)( (m_paramGayka.da - dd) * 0.5 );
    c2 = (float)( ( m_paramGayka.da - m_paramGayka.dr ) * 0.5 );
    if ( !(m_paramGayka.maskAdjustment & ISPOLN) )
      x2 = x2 - c2;
  }

  if ( !(m_paramGayka.maskAdjustment & ISPOLN) && !(m_paramGayka.maskAdjustment & SIMPLE) ) 
  {
    x1 = x1 - c1;
    LineSeg( m_paramGayka.h, j * m_paramGayka.da * 0.5, x1, j * 0.5 * dd, 1 );
    LineSeg( x1, j * dd * 0.5, x1, 0, 1 );
  }

  LineSeg( x1, j * 0.5 * dd, c1, j * 0.5 * dd, 1 );

  if ( !(m_paramGayka.maskAdjustment & SIMPLE) ) 
  {
    LineSeg( c1, j * 0.5 * dd, 0, j * 0.5 * m_paramGayka.da, 1);
    LineSeg( c1, j * dd * 0.5, c1, 0, 1 );
  }

  Hatch( 0, m_paramGayka.hatchAngle, m_paramGayka.hatchStep, 0, 0, 0 );
      LineSeg( 0, y2, 0, y, 1 );
    if ( !(m_paramGayka.maskAdjustment & ISPOLN) && !(m_paramGayka.maskAdjustment & SIMPLE) )
      LineSeg( 0, y, x, j * (m_paramGayka.D * 0.5), 1 );
    LineSeg( x, j * (m_paramGayka.D * 0.5), x3, j * m_paramGayka.D * 0.5, 1 );
    if ( !(m_paramGayka.maskAdjustment & SIMPLE) )
      LineSeg( x3, j * m_paramGayka.D * 0.5, m_paramGayka.h, y3, 1 );

    if ( !(m_paramGayka.maskAdjustment & ISPOLN) && !(m_paramGayka.maskAdjustment & SIMPLE) )
      LineSeg( m_paramGayka.h, y3, m_paramGayka.h, j * m_paramGayka.da * 0.5, 1 );
    else
      LineSeg( m_paramGayka.h, y3, m_paramGayka.h, j * dd * 0.5, 1 );


    if ( !(m_paramGayka.maskAdjustment & ISPOLN) && !(m_paramGayka.maskAdjustment & SIMPLE) )
      LineSeg( m_paramGayka.h, j * m_paramGayka.da * 0.5, x1, j * 0.5 * dd, 1 );
    LineSeg( x1, j * 0.5 * dd, c1, j * 0.5 * dd, 1 );
    if ( !(m_paramGayka.maskAdjustment & SIMPLE) )
      LineSeg( c1, j * 0.5 * dd, 0, j * 0.5 * m_paramGayka.da, 1 );
  EndObj();
  LineSeg( c2, j * 0.5 * m_paramGayka.dr, x2, j * 0.5 * m_paramGayka.dr, 2 );
} 


//-------------------------------------------------------------------------------
//    ()
// ---
void Gayka5915::Gayka_Sverhu() 
{
  float D, s;
  float h1, dd;

  s  = (float)( m_paramGayka.s * 0.5 );
  D  = (float)( s / CosD( 30 ) );
  dd = (float)( m_paramGayka.dr - 2 * MODSTEP_REAL * m_paramGayka.p );

  h1 = (float)( D * SinD( 30 ) ); 

  LineSeg( -s, h1, 0, D, 1 );
  LineSeg( 0, D, s, h1, 1 );
  LineSeg( s, h1, s, -h1, 1 );
  LineSeg( s, -h1, 0, -D, 1 );
  LineSeg( 0, -D, -s, -h1, 1 );
  LineSeg( -s, -h1, -s, h1, 1 );

  if( !(m_paramGayka.maskAdjustment & SIMPLE) )
    Circle( 0, 0, m_paramGayka.d2 * 0.5, 1 );
  Circle( 0, 0, dd * 0.5, 1 );
  ArcByPoint( 0, 0, m_paramGayka.dr * 0.5, m_paramGayka.dr * 0.5 * SinD(15),
       m_paramGayka.dr * 0.5 * CosD(15), m_paramGayka.dr * 0.5 * CosD(15),
       -m_paramGayka.dr * 0.5 * SinD(15), 1, 2 );

  if ( !(m_paramGayka.maskAdjustment & AXIS_OFF ) ) 
  {
    if ( D >= 6 )  
    {
      LineSeg( -3 - s, 0, s + 3, 0, 3 );
      LineSeg( 0, -3 - D, 0, 3 + D, 3 );
    }
    else  
    {
      LineSeg( -1 - s, 0, s + 1, 0, 3 );
      LineSeg( 0, -1 - D, 0, 1 + D, 3 );
    }
  }
}


//------------------------------------------------------------------------------
//    
// ---
LPTSTR LoadStr( int id ) 
{ 
  static TCHAR buf[512]; 
  //       
  ksConvertLangStrExT( StepDLL.hModule, id, buf, 512 );
  return buf;
}


//-------------------------------------------------------------------------------
//   
// ---
int _ConnectDB( reference bd, TCHAR *name ) 
{
  static TCHAR fullName[256];
  bool res = false;
  if( GetModuleFileName( StepDLL.hModule, fullName, sizeof(fullName) ) ) 
  {
    TCHAR *c = _tcsrchr( fullName, _T('\\'));
    if ( c ) 
    {
      *(c + 1) = _T('\0');
      _tcscat( fullName, name );
      OFSTRUCT ofs;
      if ( OpenFile(_bstr_t(fullName), &ofs, OF_EXIST) != HFILE_ERROR )
        res = true;
      else 
      {
        *(c + 1) = _T('\0');
        _tcscat( fullName, _T("load\\") );
        _tcscat( fullName, name );
        if ( OpenFile(_bstr_t(fullName), &ofs, OF_EXIST) != HFILE_ERROR )
          res = true;
      }
    }
  }
  return res ? ConnectDBT( bd, fullName ) : ConnectDBT( bd, name );
}


//-------------------------------------------------------------------------------
//   
// ---
bool OpenGaykaBase( SimpleBase &base ) 
{
  bool res = false;
  base.bg = CreateDBT(_T("TXT_DB"));

  if( _ConnectDB(base.bg, _T("5915.loa")) ) 
  {
    //  
    base.rg1 = Relation( base.bg );
      RChar( "", 20, 0 );
      RFloatT(_T("dr"));
    EndRelation(); 
    if ( DoStatementT(base.bg, base.rg1, _T("1 1") ) ) 
    {
      //  
      base.rg2 = Relation( base.bg );
        RFloatT(_T("dr"));
        RFloatT(_T(""));
        RFloatT(_T(""));
        RFloatT(_T(""));
        RFloatT(_T(""));
        RFloatT(_T(""));
        RFloatT(_T(""));
        RFloatT(_T(""));
        RFloatT(_T(""));
        RFloatT(_T(""));
        RFloatT(_T(""));
        RFloatT(_T(""));
      EndRelation();
      if ( DoStatementT( base.bg, base.rg2, _T("")) ) 
        res = true;
    }
  }
  return res;
}


//--------------------------------------------------------------------------
//      
//--------------------------------------------------------------------------
bool ReadGaykaBase( float d, SimpleBase &base, GAYKA5915 *pGayka ) 
{
  bool res = false;

  struct { float dr; 
           float p1; 
           float p2; 
           float s; 
           float D; 
           float da; 
           float h; 
           float d2; 
           float m; 
           float s1; 
           float D1; 
           float m1; } tmpGayka;
  TCHAR s[256];
  _stprintf( s, _T("dr=%.1f"), d );
  if ( ConditionT(base.bg, base.rg2, s) ) 
  {   
    bool read = !!ReadRecord( base.bg, base.rg2, &tmpGayka );
    if ( read )
    {
      pGayka->dr = tmpGayka.dr;
      pGayka->da = tmpGayka.da;
      pGayka->h  = tmpGayka.h;
      pGayka->d2 = tmpGayka.d2;

      if ( pGayka->maskAdjustment & PITCH )
        pGayka->p = tmpGayka.p2;
      else
        pGayka->p = tmpGayka.p1;

      if ( fabs( tmpGayka.p2 - tmpGayka.p1 ) < 0.001 ) 
        pGayka->maskAdjustment |= PITCHOFF;
      else
        pGayka->maskAdjustment &= ~PITCHOFF;

      if ( fabs(tmpGayka.s1)> 0.001 )
        pGayka->maskAdditional |= KEY_S_GRAY;
      else 
      {
        pGayka->maskAdditional &= ~KEY_S_GRAY;
        pGayka->maskAdditional &= ~KEY_S;
      }
   
      if ( pGayka->maskAdditional & KEY_S ) 
      {
        pGayka->s     = tmpGayka.s1; //   
        pGayka->D     = tmpGayka.D1; //   
        pGayka->massa = tmpGayka.m1; // 
      }
      else 
      {
        pGayka->s     = tmpGayka.s; //   
        pGayka->D     = tmpGayka.D; //   
        pGayka->massa = tmpGayka.m; // 
      }

      res = true;
    }
  }
  return res;
}


//-------------------------------------------------------------------------------
//   
// ---
void CloseGaykaBase ( SimpleBase &base ) 
{
  DeleteDB( base.bg );
}


//-------------------------------------------------------------------------------
// 
// ---
Gayka5915 * Gayka5915::m_pCallbackCurrentGayka = NULL;
bool Gayka5915::m_flagSwitch = false;
reference Gayka5915::m_refSpcObject = 0;


//------------------------------------------------------------------------------
//   ,   Cursor
// ---
int WINAPI Gayka5915::CALLBACKPROCCURSOR( int comm, double *x, double *y,
                                          RequestInfoT *info, 
                                          void *phantom, 
                                          int dynamic )
{
  Phantom *rub = (Phantom *)phantom;
  if( !dynamic ) // 
  { 
    switch ( comm ) 
    {
      case ID_ANGLE  :
        m_flagSwitch = true;
        return 0;
      case ID_VID     :
      case ID_TOPVID  :
      case ID_SIDEVID :
      case ID_VIDSEC  :
        m_pCallbackCurrentGayka->m_paramMacro.drawType =(short) comm;
        break;
      case ID_HATCH_ANGLE :
        m_pCallbackCurrentGayka->SetHatchAngle();
        break;
      case ID_HATCH_STEP :
        m_pCallbackCurrentGayka->SetHatchStep();
        break;
      case ID_PARAM :
        m_pCallbackCurrentGayka->MacroElementParam();
        break;
      case -1: //   
      {
        m_pCallbackCurrentGayka->SetParamGr();
        StoreTmpGroup( rub->type1.gr );
        m_pCallbackCurrentGayka->SetPlacementGr( *x, *y, m_pCallbackCurrentGayka->m_paramMacro.angle );

        if ( m_pCallbackCurrentGayka->DrawSpcObj( rub->type1.gr ) ) 
        {
          ClearGroup( rub->type1.gr );
          return 0;
        }
        ClearGroup( rub->type1.gr );
        if( m_pCallbackCurrentGayka->m_flagMode )
          return 0;
        break;
      }
    }
    info->commands = (TCHAR *)m_pCallbackCurrentGayka->ChoiceMenuId();
    m_pCallbackCurrentGayka->GetGroup( rub->type1.gr );
  }
  return 1;
}


//------------------------------------------------------------------------------
//   ,   Placement
// ---
int WINAPI Gayka5915::CALLBACKPROCPLACEMENT( int comm, double *x, double *y, double *angle,
                                             RequestInfoT *info, 
                                             void *phantom, 
                                             int dynamic )
{ 
  Phantom *rub = (Phantom *)phantom;
  if( !dynamic ) //  
  { 
    switch ( comm ) 
    {
      case ID_ANGLE  :
      {
        m_flagSwitch = true;
        return 0;
      }
      case ID_VID       :
      case ID_TOPVID    :
      case ID_SIDEVID   :
      case ID_VIDSEC    :
      {
        m_pCallbackCurrentGayka->m_paramMacro.drawType =(short)comm;
        break;
      }
      case ID_HATCH_ANGLE :
      {
        m_pCallbackCurrentGayka->SetHatchAngle();
        break;
      }
      case ID_HATCH_STEP :
      {
        m_pCallbackCurrentGayka->SetHatchStep();
        break;
      }
      case ID_PARAM :
      {
        m_pCallbackCurrentGayka->MacroElementParam();
        break;
      }
      case -1: //   
      {
        m_pCallbackCurrentGayka->m_paramMacro.angle = (float)*angle;       
        m_pCallbackCurrentGayka->SetParamGr();
        StoreTmpGroup( rub->type1.gr );
        m_pCallbackCurrentGayka->SetPlacementGr( *x, *y, m_pCallbackCurrentGayka->m_paramMacro.angle );

        if ( m_pCallbackCurrentGayka->DrawSpcObj( rub->type1.gr ) ) 
        {
          ClearGroup( rub->type1.gr );
          return 0;
        }
        ClearGroup( rub->type1.gr );
        if( m_pCallbackCurrentGayka->m_flagMode )
          return 0;
        break;
      }
    }
    info->commands = (TCHAR *)m_pCallbackCurrentGayka->ChoiceMenuId();
    m_pCallbackCurrentGayka->GetGroup( rub->type1.gr );
  }
  else 
  {
    m_pCallbackCurrentGayka->m_paramMacro.angle = (float)*angle;
  }
  return 1;
}



//-------------------------------------------------------------------------------
//   
// ---
unsigned int WINAPI LIBRARYID()
{
  return ID_LIBID;
}


//-------------------------------------------------------------------------------
//   
// ---
void WINAPI LIBRARYENTRY( unsigned int comm )
{
  if ( ksGetCurrentDocument( 1 ) ) //   2D 
  {
    switch (comm) 
    {
      case ID_GAYKA :
      {
        Gayka5915* pGayka = new Gayka5915();
	      if ( pGayka ) 
        {
  		    pGayka->Draw();
	  	    delete pGayka;
        }
        break;
      }  
    }
  }
  else 
		ErrorT( LoadStr( ID_ERROR_2DDOC ) ); //    
}


// HOT_POINTS ##################################################################

#if !defined(_IFUNC)
# define _IFUNC STDMETHODCALLTYPE
#endif   

//-------------------------------------------------------------------------------
//     Hot-
// ---
class Gayka5915HP : public ILibHPObject 
{
  protected :
    Gayka5915 gayka;
    int count;
  public :
    Gayka5915HP() : count (0) { gayka.SetFlagMode( true ); }
    ~Gayka5915HP();
  public:
    /* IUnknown */
    virtual unsigned long _IFUNC AddRef();
    virtual unsigned long _IFUNC Release();
    virtual HRESULT				_IFUNC QueryInterface(const GUID far& iid, void far*far* iface);

    /* ILibHPObject */
    virtual int  _IFUNC LibHotPnt_GetMenu       ()                                        { return gayka.GetMenu(); }
    virtual BOOL _IFUNC LibHotPnt_Prepare       ( int index )                             { return TRUE; }
    virtual BOOL _IFUNC LibHotPnt_Complete      ( int index, BOOL success )               { return gayka.EditComplete( index, success ); }
    virtual BOOL _IFUNC LibHotPnt_Get           ( HotPointDescription* point, int index ) { return gayka.GetHotPoints( point, index ); }
    virtual BOOL _IFUNC LibHotPnt_Set           ( HotPointDescription* point, int index ) { return gayka.SetHotPoint( point, index ) ? true : false; }
    virtual BOOL _IFUNC LibHotPnt_GetCursorText ( int index, char** text )                { return gayka.GetCursorText( index, text ); }
    virtual BOOL _IFUNC LibHotPnt_ExecuteCommand( int id )                                { return gayka.ExecuteCommand( id ); }
};


//------------------------------------------------------------------------------
// AddRef
// ---
unsigned long _IFUNC Gayka5915HP::AddRef() 
{
  count++;
  return count;
}


//------------------------------------------------------------------------------
// Release
// ---
unsigned long _IFUNC Gayka5915HP::Release() 
{
  count--;
  unsigned long res = count;
  if( !count )
    delete this;
  return res;
}


//------------------------------------------------------------------------------
// QueryInterface
// ---
HRESULT _IFUNC Gayka5915HP::QueryInterface( const GUID far& iid, void far*far* iface )
{
  if ( iid == IID_ILibHPObject ) 
  {
    *iface = this;
    return S_OK;
  }
  *iface = NULL;
  return E_NOINTERFACE;
}


//-------------------------------------------------------------------------------
// 
// ---
Gayka5915HP::~Gayka5915HP() 
{
}   


//-------------------------------------------------------------------------------
//       Hot 
// ---
void WINAPI LibObjInterfaceEntry( int idType, unsigned int comm, ILibHPObject** object ) 
{
  if ( object ) 
  {
    if ( idType == 1 ) //   Hot  
    switch (comm) 
    {
      case ID_GAYKA : 
      {
        *object = new Gayka5915HP(); 
        (*object)->AddRef(); 
        break;
      }
    }
  }
}  


//------------------------------------------------------------------------------
//   Hot 
// ---
bool Gayka5915::GetHotPoints( HotPointDescription* point, int index ) 
{
  bool res = false;
	switch ( index ) 
  {
  	case 0 : //  
    {  
      point->x    = 0;
      point->y    = 0;
			point->text = "0";
      res = true;
      break;
    }
    case 1 : //    
    {  
      point->x          = 0;
      point->y          = m_paramGayka.dr / 2.0;
      point->cursorInst = StepDLL.hModule;
      point->cursorId   = CURSOR_DIAMETER;
      point->text       = "Dr";
      res = true;
      break;
    }
    case 2 : //   
    {  
      static char textHP[255]; //      static
      sprintf( textHP, "A = %.2f", fmod(m_paramMacro.angle, 360.0) ); 
      point->x          = m_paramMacro.drawType == ID_TOPVID ? (m_paramGayka.s / 2.0) : m_paramGayka.h;
      point->y          = 0;
      point->cursorInst = StepDLL.hModule;
      point->cursorId   = CURSOR_ROTATE;
      point->text       = textHP;
      res = true;
      break;
    }
  }
  return res;
}


//-------------------------------------------------------------------------------
//   Hot 
// ---
bool Gayka5915::GetCursorText( int index, char** text ) 
{
  bool res = false;
  static char cursorText[255]; //      static
  switch ( index ) 
  {
    case 2 :
    {
			sprintf( cursorText, "A = %.2f", fmod(m_paramMacro.angle, 360.0) );
      *text = cursorText;
      res = true;
      break;
    }
    case 1 :
    {
			sprintf( cursorText, "D = %.2f\nH = %.2f", m_paramGayka.dr, m_paramGayka.h );
      *text = cursorText;
      res = true;
      break;
    }
  }   
  return res;
}


//-------------------------------------------------------------------------------
//   Hot 
// ---
bool Gayka5915::ChangeHotPointParam( double d ) 
{
  bool res = false;
  struct { char s[20]; float dr; } record;

  //   dR  d
  float dr    = 0.0;
  float drOld = m_paramGayka.dr;

  SimpleBase base;
  OpenGaykaBase( base );

  while( true ) 
  {
    if ( ReadRecord(  base.bg, base.rg1, &record ) ) 
    {
      if ( dr <= d )
        dr = record.dr;
      else
        break;
    }
    else
      break;
  }

  //   
  if ( fabs( dr - drOld ) > 0.01 )
    res = ReadGaykaBase( dr, base, &m_paramGayka );

  CloseGaykaBase( base );

  return res;
}


//------------------------------------------------------------------------------
//   Hot 
// ---
bool Gayka5915::SetHotPoint( HotPointDescription* point, int index )
{ 
  switch ( index ) 
  {
    case 0 :
    {
      m_refMacro = 0; //  
      SetPlacementGr( point->x, point->y, 0.0 );
      break;
    }
    case 1 :
    {
      if ( ChangeHotPointParam( fabs(point->y * 2) ) ) 
      {  

        reference group = 0;
        GetGroup( group );
        SetParamGr();
        SetPlacementGr( 0., 0., 0. );
        StoreTmpGroup( group );
        ClearGroup( group );
      }
      break;
    }
    case 2 : 
    {
      m_refMacro = 0; //  
      float angle;
      if ( point->y == 0 )
        angle = 0.0;
      else if ( point->x == 0 )
        angle = 90.0;
      else
        angle = (float)AtanD( point->y / point->x );

      m_paramMacro.angle += angle;
      SetPlacementGr( 0., 0., angle );
      break;
    }
  }
  return TRUE;
}


//------------------------------------------------------------------------------
//     ,    
// ---
bool Gayka5915::EditComplete( int index, BOOL success ) 
{
  if ( index == 1 && success ) 
  {
  	DrawSpcObj( 0 );  
    //     ,    
    if ( m_refSpcObject && ksEditWindowSpcObject( m_refSpcObject ) ) 
      DrawPosLeader( m_refSpcObject );
  }
  return true;
}


//------------------------------------------------------------------------------
// 
// ---
int Gayka5915::GetMenu() 
{
  HMENU menu = LoadMenu( StepDLL.hModule, MAKEINTRESOURCE( GAIKA_POPUPMENU ) );
  CheckMenuItem( menu, m_paramMacro.drawType, MF_BYCOMMAND | MF_CHECKED );
  if ( m_paramMacro.drawType != ID_VIDSEC )
  {
  	EnableMenuItem( menu, ID_HATCH_ANGLE,  MF_BYCOMMAND | MF_GRAYED );
  	EnableMenuItem( menu, ID_HATCH_STEP, MF_BYCOMMAND | MF_GRAYED );
  }
  return int(menu);
}


//------------------------------------------------------------------------------
//  
// ---
bool Gayka5915::ExecuteCommand( int id ) 
{
  switch ( id ) 
  {
    case ID_PARAM :
    {
      if ( MacroElementParam() )
			  EditComplete( 1, true );
      break;
    }
    case ID_VID     :
    case ID_TOPVID  :
    case ID_SIDEVID :
    case ID_VIDSEC  :
    {
      m_paramMacro.drawType = (short)id;
      break;
    }
    case ID_HATCH_ANGLE :
    {  
      SetHatchAngle();
      break;
    }
    case ID_HATCH_STEP :
    {  
      SetHatchStep();
      break;
    }

    reference group;
    GetGroup( group );
    SetParamGr();
    SetPlacementGr( 0., 0., 0. );
    StoreTmpGroup( group );
    ClearGroup( group );
  }
  return true;
}

// HOT_POINTS ################################################################## 


//-------------------------------------------------------------------------------
// 
// ---
Gayka5915::Gayka5915() : 
  m_refMacro(0), 
  m_flagMode(true)
{
  memset(&m_paramMacro, 0, sizeof(m_paramMacro) ); 
  memset(&m_paramGayka, 0, sizeof(m_paramGayka) ); 

  if( !GetMacroParam( 0, *this, GetSize() ) ) 
  {
    m_paramMacro.angle           = 0;
    m_paramMacro.drawType        = ID_VID;
    m_paramGayka.hatchAngle      = 45;
    m_paramGayka.hatchStep       = 2;     
    m_paramGayka.dr              = 20;  
    m_paramGayka.p               = (float)2.5;    
    m_paramGayka.version         = 1;
    m_paramGayka.indexMassa      = 0;
    m_paramGayka.s               = 30; 
    m_paramGayka.D               = 33;  
    m_paramGayka.da              = (float)21.6;  
    m_paramGayka.h               = 16;
    m_paramGayka.d2              = (float)27.7;  
    m_paramGayka.classAccuracy   = 2; 
    m_paramGayka.maskAdjustment  = 0;        
    m_paramGayka.maskAdditional  = 0;
    m_paramGayka.massa           = (float)71.44;
  }
  else 
  {
    if ( !m_paramGayka.version ) 
    {
      m_paramGayka.version         = 1;
    }
  }
}


//-------------------------------------------------------------------------------
// 
// ---
void Gayka5915::Assign( Gayka5915& other ) 
{         
  memcpy( &m_paramMacro, &other.m_paramMacro, sizeof(m_paramMacro) ); //   
  memcpy( &m_paramGayka, &other.m_paramGayka, sizeof(m_paramGayka) ); //    5915
  m_flagMode = other.m_flagMode;
}


//-------------------------------------------------------------------------------
//  
// ---
Gayka5915::Gayka5915( Gayka5915& other ) 
{
	Assign( other );
}


//-------------------------------------------------------------------------------
//  
// ---
bool Gayka5915::MacroElementParam() 
{
	bool res = false;
	Gayka5915 bufGayka( *this );

  SimpleBase base;
	if ( OpenGaykaBase( base ) ) 
  {
		GaykaDlg* dlg = new GaykaDlg( bufGayka, base );
		if ( dlg ) 
    {
			EnableTaskAccess( 0 );        //    
			res = dlg->DoModal() == IDOK;	//  
			EnableTaskAccess( 1 );        //    
			delete dlg;
		}

		if ( res ) 
			Assign( bufGayka );

		CloseGaykaBase( base );
	}
	return res;
}


//-------------------------------------------------------------------------------
//  
// ---
void Gayka5915::Draw()  
{
  if ( !ReturnResult() ) 
  {  
    bool flagRepeat = true;  
    m_pCallbackCurrentGayka = this; 
    m_flagMode = !!EditMacroMode(); //      ( 
                                    //   , 0 -    )  

    if ( !MacroElementParam() )
      return; 

    double x, y; 
    
    struct Phantom phantom;
    phantom.type1.xBase = 0;
    phantom.type1.yBase = 0;
    phantom.type1.scale = 1;
    phantom.phType      = 1;
    phantom.type1.gr    = 0;
    
    while ( flagRepeat ) 
    {
      m_flagSwitch = false;
      GetGroup ( phantom.type1.gr );
      phantom.type1.ang = m_paramMacro.angle;

      int menuId = ChoiceMenuId(); //  

      RequestInfoT info; //     
      memset(&info, 0, sizeof(info) );
      info.commands = (TCHAR *)menuId;
      info.dynamic  = 1;
      info.title    = info.prompt = LoadStr( ID_INFO_TITLE );
     
      
      if ( m_paramMacro.typeSwitch ) 
      {
        //      Cursor
        info.callBack = &CALLBACKPROCCURSOR;
        flagRepeat = !!CursorExT( &info, &x, &y, &phantom, NULL );
      }
      else 
      {
        //      Placement
        info.callBack = &CALLBACKPROCPLACEMENT;
        flagRepeat = !!PlacementExT( &info, &x, &y,
                                     &phantom.type1.ang,
                                     &phantom, NULL );
      }

      //     ,    
      if( m_refSpcObject )
      {
        if ( ksEditWindowSpcObject( m_refSpcObject ) ) 
        {
          DrawPosLeader( m_refSpcObject );
        }
        
        if( !m_flagMode )
          flagRepeat = true;
        
        m_refSpcObject = 0;
      }

      //    Placement  Cursor - ,  
      if ( m_flagSwitch )
      {
        flagRepeat = true;
        m_paramMacro.typeSwitch = !m_paramMacro.typeSwitch;
      }
    }
  }
}


//-------------------------------------------------------------------------------
//    
//     Cursor  Placement
// ---
void Gayka5915::DrawPosLeader( reference refSpcObj ) 
{
  bool flagRepeat = true;
  reference posLeater = 0;
  while ( flagRepeat ) 
  {
    RequestInfoT info; 
    memset(&info, 0, sizeof(info) );
    info.commands = (TCHAR*)MENU_POS_LEADER;     
    info.prompt   = LoadStr( ID_INDICATE_LEADER ); 
    double x, y; 
    int comm = CursorExT( &info, &x, &y, 0, NULL );
    switch ( comm ) 
    {
      case ID_LEADER_CREATE: //    
      {
        posLeater = ksCreateViewObject( POSLEADER_OBJ );
        flagRepeat = false;
        break;
      }
      case ID_LEADER_CONNECT: //  
      {
        memset(&info, 0, sizeof(info) );
        info.commands = LoadStr( ID_INDICATE_LEADER ); 
        if( CursorExT( &info, &x, &y, 0, NULL ) ) 
        {
          posLeater = FindObj( x, y, 100 ); //   -   x,y
          if ( !(posLeater && GetObjParam( posLeater, 0, 0, 0 ) == POSLEADER_OBJ ) ) 
          {
            ErrorT( LoadStr(ID_ERROR_LEADER) ); 
            posLeater = 0;
            flagRepeat = true;
          }
          else
            flagRepeat = false;
          break;
        }
        else
          flagRepeat = false;
        break;
      }
      case -1:
      {
        posLeater = FindObj( x, y, 100 ); //   -   x,y
        if ( !(posLeater && GetObjParam( posLeater, 0, 0, 0) == POSLEADER_OBJ )) 
        {
          ErrorT( LoadStr(ID_ERROR_LEADER) ); 
          posLeater = 0;
          flagRepeat = true;
        }
        else
          flagRepeat = false;
        break;
      }
      case 0 :
      {
        flagRepeat = false;
        break;
      }
    }
  } 
  
  //   ,      
  if ( posLeater  ) 
  {
    //      
    if ( ksSpcObjectEdit( refSpcObj ) ) 
    {
      //   
      ksSpcIncludeReference( posLeater, true );
      //   
      ksSpcObjectEnd();
    }
  }
}


//-------------------------------------------------------------------------------
//   
// ---
reference Gayka5915::StaticEditSpcObj( reference geom ) 
{
  if ( !m_paramMacro.flagSpcCreate )
    return 0;

  reference refSpcObj = ksGetSpcObjForGeomWithLimit( NULL,             //   
                                                     0,                //   
                                                     geom,
                                                     0,                // 1 -      , 0 -    
                                                     1,                // 1 -  , 0-  
                                                     STANDART_SECTION, //  
                                                     297327484710.0 );
  if ( refSpcObj && !ksSpcObjectEdit( refSpcObj ) )
    return 0;
 
  //      
  if( !!refSpcObj || ksSpcObjectCreate( NULL ,               //   
                                        0,                   //   
                                        STANDART_SECTION, 0, //    
                                        297327484710.0,0 ) ) //  
  {    
    int spcValue;
    // 
    if( !(m_paramGayka.maskAdjustment & ISPOLN) )
      ksSpcVisible( SPC_NAME, 2, 0 );
    else 
    {
      spcValue = 2;
      ksSpcVisible( SPC_NAME, 2, 1 );
      ksSpcChangeValue( SPC_NAME , 2, &spcValue, UINT_ATTR_TYPE  );
    }

    // 
     ksSpcChangeValue( SPC_NAME , 4, &m_paramGayka.dr, FLOAT_ATTR_TYPE  );

    //   
    if( !(m_paramGayka.maskAdjustment &PITCH) )
    {
      //     
      ksSpcVisible( SPC_NAME, 5, 0 );
      ksSpcVisible( SPC_NAME, 6, 0 ); // 
    }
    else 
    {
      ksSpcVisible( SPC_NAME, 5, 1 );
      ksSpcVisible( SPC_NAME, 6, 1 ); // 
      ksSpcChangeValue( SPC_NAME , 6, &m_paramGayka.p, FLOAT_ATTR_TYPE );
    }

    //   
    ksSpcVisible( SPC_NAME, 7, 0 );

    //   
    ksSpcVisible( SPC_NAME, 8, 0 );

    //  
    ksSpcVisible( SPC_NAME, 9, 0 );

    //  
    ksSpcVisible( SPC_NAME, 10, 0 );

    // 
    spcValue = 5915;
    ksSpcChangeValue( SPC_NAME, 12, &spcValue, UINT_ATTR_TYPE  );
   
    //  
    double massa = m_paramGayka.massa * ( !m_paramGayka.indexMassa ? 1 : m_paramGayka.indexMassa == 1 ? 0.356 : 1.08 ) / COUNT_MASSA;
    TCHAR buf[256];
    _stprintf( buf, _T("%f"), massa );
    ksSpcMassaT( buf ); 

    //  
    if ( geom )
      ksSpcIncludeReference( geom, SPC_CLEAR_GEOM  );

    return ksSpcObjectEnd();
  }
  return 0;
}


//-------------------------------------------------------------------------------
//   
// ---
bool Gayka5915::DrawSpcObj( reference geom ) 
{
  if ( ReturnResult() == etError10 ) //  
    ResultNULL();

  m_refSpcObject = StaticEditSpcObj( geom ); 

  if( !m_paramMacro.flagSpcCreate && m_refSpcObject ) 
  {
    if ( ksSpcObjectEdit( m_refSpcObject ) ) 
    {
      ksSpcIncludeReference( 0, 0 ); //  ,         
      ksSpcObjectEnd();
    }  
    DeleteObj( m_refSpcObject );
    m_refSpcObject = 0;
  }  
  return !!m_refSpcObject;
}


//-------------------------------------------------------------------------------
//  
// ---
void Gayka5915::GetGroup( reference &refGroup )
{
  int k2;
  if ( !(m_paramGayka.maskAdjustment & ISPOLN) )
    k2=1;
  else
    k2=2;

  if ( refGroup )
    DeleteObj( refGroup );
  refGroup = NewGroup( 1 );
  macro();
  switch (m_paramMacro.drawType) 
  {
    case ID_VID :  // 
      if ( !(m_paramGayka.maskAdjustment & SIMPLE) ) 
      {
       Gayka_K( 0, 0, 0, m_paramGayka.s, m_paramGayka.D, 0, m_paramGayka.h, 1, 0, m_paramGayka.d2, k2 );
       Gayka_K( 0, 0, 0, m_paramGayka.s, m_paramGayka.D, 0, m_paramGayka.h, -1, 0, m_paramGayka.d2, k2 );
      }
      else 
      {
       Gayka_K_Y( 0, &m_paramGayka,  1 );
       Gayka_K_Y( 0, &m_paramGayka, -1 );
      }
      if ( !(m_paramGayka.maskAdjustment & AXIS_OFF ) )
        LineSeg( -3, 0, m_paramGayka.h + 3, 0, 3 );
    break;
    case ID_SIDEVID : //  
      if ( !(m_paramGayka.maskAdjustment & AXIS_OFF ) )
        LineSeg( -3, 0, m_paramGayka.h + 3, 0, 3 );
      if ( m_paramGayka.maskAdjustment & SIMPLE )
        k2 = 3;
      Gayka_K_Side( 0, m_paramGayka.s, m_paramGayka.D, m_paramGayka.d2, m_paramGayka.h, 1, k2 );
      Gayka_K_Side( 0, m_paramGayka.s, m_paramGayka.D, m_paramGayka.d2, m_paramGayka.h, -1, k2 );
    break;
    case ID_TOPVID : //  
      Gayka_Sverhu();
    break;
    case ID_VIDSEC : // -/-
      if( !(m_paramGayka.maskAdjustment & SIMPLE) ) 
      {
        Gayka_K( 0, 0, 0, m_paramGayka.s, m_paramGayka.D, 0, m_paramGayka.h, 1, 0, m_paramGayka.d2, k2 );
        Gayka_P_K( -1 );
      }
      else 
      {
        Gayka_K_Y( 0, &m_paramGayka, 1 );
        Gayka_P_K( -1 );
      }
      if ( !( m_paramGayka.maskAdjustment & AXIS_OFF ) )
        LineSeg( -3, 0, m_paramGayka.h + 3, 0, 3 );
    break;
  }

  m_refMacro = end_obj();
  EndGroup();
}


//-------------------------------------------------------------------------------
// 
// ---
int Gayka5915::ChoiceMenuId() 
{
  if ( !m_paramMacro.typeSwitch )
    return m_paramMacro.drawType == ID_VID ?  MENU_G5915_1 : m_paramMacro.drawType == ID_TOPVID  ? MENU_G5915_2 :
           m_paramMacro.drawType == ID_SIDEVID ? MENU_G5915_4 : MENU_G5915_3;
  else
    return m_paramMacro.drawType == ID_VID ?  MENU_G5915_5 : m_paramMacro.drawType == ID_TOPVID  ? MENU_G5915_6 :
           m_paramMacro.drawType == ID_SIDEVID ? MENU_G5915_8 : MENU_G5915_7;
}

//-------------------------------------------------------------------------------
//   - 
// ---
void Gayka5915::SetHatchAngle() 
{
  double angle;
  EnableTaskAccess( 0 );
  if ( ReadDoubleT(_T("  "), m_paramGayka.hatchAngle, -90, 90, &angle) )
		m_paramGayka.hatchAngle = (float)angle;
  EnableTaskAccess( 1 );
}

//-------------------------------------------------------------------------------
//   - 
// ---
void Gayka5915::SetHatchStep()
{
  double step;
  EnableTaskAccess( 0 );
  if ( ReadDoubleT(_T("  "), m_paramGayka.hatchStep, 0.1, 1000, &step) )
	  m_paramGayka.hatchStep = (float)step;
  EnableTaskAccess( 1 );
}


//-------------------------------------------------------------------------------
//  
// ---
void Gayka5915::SetParamGr()
{
  if( m_refMacro )
    ksSetMacroParam( m_refMacro, *this, GetSize(), 0, 0, -1, MP_HOTPOINTS );
}

//-------------------------------------------------------------------------------
//  
// ---
void Gayka5915::SetPlacementGr( double x, double y, double angle )
{
  SetMacroPlacement( m_refMacro, x, y, angle, 1 );
}
