#ifndef __CPAR_H
#define __CPAR_H
////////////////////////////////////////////////////////////////////////////////
//
// LibObj.h
// <LibObj.cpp>
//
////////////////////////////////////////////////////////////////////////////////
#include "resource.h"

#include "PropManager\CPropMen.h"
#include "Events\DocumentFrameEvent.h"
#include <PArray.h>
#include <SArray.h>

#define   NULL_EPSILON      1E-30 //      

//-----------------------------------------------------------------------------
// 3D 
// ---
struct Point3D
{
  double x;
  double y;
  double z;
  Point3D(  )
    : x( 0.0 )
    , y( 0.0 )
    , z( 0.0 ){}
  Point3D( double _x, double _y, double _z )
    : x( _x )
    , y( _y )
    , z( _z ){}
  
  Point3D( Point3D & other )
    : x( other.x )
    , y( other.y )
    , z( other.z ){}
  
  Point3D& operator-=(const Point3D& other)
  {
    x -= other.x;
    y -= other.y;
    z -= other.z;
    return *this;
  }  
  
};


//-----------------------------------------------------------------------------
// 3D 
// ---
struct Vector3D
{
  double x;
  double y;
  double z;
  Vector3D(  )
    : x( 0.0 )
    , y( 0.0 )
    , z( 0.0 ){}
  Vector3D( double _x, double _y, double _z )
    : x( _x )
    , y( _y )
    , z( _z ){}
  
  Vector3D( Vector3D & other )
    : x( other.x )
    , y( other.y )
    , z( other.z ){}
  
};



//-----------------------------------------------------------------------------
//
// ---
struct Matrix3D
{
  double el[4][4];
  Matrix3D() { Init(); } //   
  
  Matrix3D( Point3D &original, //  
            Vector3D &normal,   //   
            Vector3D &axisX,    //  
            Vector3D &axisY )   //  
  {
    Init( original, normal, axisX, axisY );
  }
  
  //       
  Matrix3D( ISurface & surf, 
            bool       isSameSense,  //          
            double     u,      //   
            double     v )     //  
  {
    Init( surf, isSameSense, u, v );
  }

  //    SafeArray-
  Matrix3D( double * el16 );
  
  Vector3D & GetAxisX () const { return (Vector3D &)*el[0]; } //  
  Vector3D & GetAxisY () const { return (Vector3D &)*el[1]; } //  
  Vector3D & GetAxisZ () const { return (Vector3D &)*el[2]; } //  
  Point3D  & GetOrigin() const { return (Point3D  &)*el[3]; }
  
  void      Init(); //     
  
  void      Init( Point3D  &original, //  
                  Vector3D &normal,   //   
                  Vector3D &axisX,    //  
                  Vector3D &axisY );  //  
  
  void      Init( ISurface & surf,   //  
                  bool isSameSense,  //         
                  double     u,      //  u 
                  double     v );    //  v;   
  
  void      Init( const Matrix3D &A, const Matrix3D &B ); // 

 void        operator *= ( const Matrix3D &m ) { Multiply( m ); } //   

 bool        operator == ( const Matrix3D &m ) const; //   ( - Math3D::lengthEpsilon)

 void        Multiply( const Matrix3D &b ); //    this = this * b;

};


//-----------------------------------------------------------------------------
//     
// ---
struct ExternalTeselationParam
{
  _variant_t       points;        //  
  _variant_t       normals;       //  
  _variant_t       indexes;       //  
  //    _variant_t colors;    //   
  // AdvancedColor                        
  COLORREF         color;         //  
  double           ambient;       //  
  double           diffuse;       // 
  double           specularity;   // 
  double           shininess;     //  
  double           transparency;  // 
  double           emission;      // 
  bool             edge;     
  ExternalTeselationParam( IEntityPtr & obj, IPartPtr & topPart     );
  ExternalTeselationParam( PArray<ExternalTeselationParam> & params );
  
  bool IsValid()
  {
    return transparency    > 0.0 &&
      points.vt  == (VT_ARRAY | VT_R8) &&    
      indexes.vt == (VT_ARRAY | VT_I4);  
  }
  
  void Init( IExternalTessellationObjectPtr & obj)
  {
    if ( obj )
    {
      if ( edge )
      {
        obj->SetEdges( points, indexes, _variant_t()/*colors*/ ); 
      }
      else
        obj->SetTessellation( points, indexes, normals, _variant_t()/*colors*/ );
      obj->SetAdvancedColor( color, ambient, diffuse, specularity, shininess, transparency, emission );
    }
  }

  void InitByFace( IFaceDefinitionPtr &faceDef );
  void InitByEdge( IEdgeDefinitionPtr &edgeDef );
  
  void PacEdges( PArray<ExternalTeselationParam> & params ); //      
  
};

//-----------------------------------------------------------------------------
//
// ---
struct TeselationNodeParam
{
  PArray<IFaceDefinitionPtr>      m_faces;   // 
  SArray<long>                    m_iids;    //      
  long                            m_index;   //  
  bool                            m_visible; //  

  TeselationNodeParam() : m_index(0), m_visible(false) {}
 
  virtual ~TeselationNodeParam() {}

  long GetID() { return m_index; }
 
  virtual void Save( _bstr_t & pasword, IUserDataStoragePtr & s );
  virtual bool Load( IUserDataStoragePtr & s, long & index, long version );
  
};


//-----------------------------------------------------------------------------
//
// ---
struct ArrowParam : public TeselationNodeParam
{
  
  ArrowParam() : TeselationNodeParam() {}
  
  virtual ~ArrowParam() {}

  void Make( IFaceDefinitionPtr & face, IDocumentFramePtr & frame, PArray<ExternalTeselationParam> & arrowParams );

  void Make( IDocumentFramePtr & frame, PArray<ExternalTeselationParam> & arrowParams );

};



////////////////////////////////////////////////////////////////////////////////
//
//   
//
////////////////////////////////////////////////////////////////////////////////
class LibObj : public PropertyManagerObject,
               public DocumentFrameEventCalback,
               public ADVCTreeEventsCallBack,
               public ATreeViewEventCallBack
{

protected :
  int            m_command; 
  bool           m_LoadTree;         //     
  
  bool           m_TreeVisible;      //    
  _DVCTreePtr    m_TreeCtrl;         // 
  ITreeViewPtr   m_TreeVeiw;         // 
  ABaseEvent *   m_documentFrameEvent;
  ABaseEvent *   m_treeCtrlEvent;
  ABaseEvent *   m_treeViewEvent;


  _variant_t     NOPARAM;            //  
  static         LibObj * editObj;   //  

//  ---
  PArray<ExternalTeselationParam> arrowParams;      // 
  PArray<ArrowParam>              m_arrows;
  ArrowParam  *                   m_newArrow;    
  long                            m_arrowsIndex;    //   
//---

  CMenu                           m_treeMenu;       //    

public:

  //  
     LibObj( IDocumentFramePtr & frame );
   virtual ~LibObj();
           
           
     bool              IsMyFrame( IDocumentFramePtr & frame );
     IDocumentFramePtr GetFrame();                             //   

     void              CreateForce();                              //   
     void              OnOfTree();                                 //      

     void              Refresh();                                  //               

     void              CreateTree();                               //      
     void              CloseTree();                                //   
     void              SaveTree();                                 //    
     void              LoadTree();                                 //    

     void              FillTree( IImageListPtr & treeImageList );  //  
     
     template <class T>
     void              FillTreeNodes( LPCTSTR key, long nameID, PArray<T>& nodeElements );
     
     IImageListPtr     InitTreeImageList();                        //     
     


//   ##################################################################
  //      
  // prButtonClick -  .
  virtual bool OnButtonClick( long buttonID );
    
  //prChangeControlValue -   
  virtual bool OnChangeControlValue( /*IPropertyControl* cntrl,*/ long ctrlID, const VARIANT& newVal );
  
  // prControlCommand   
  virtual bool OnControlCommand( long ctrlID, long buttonID );

  // prButtonUpdate        -    .
  virtual bool OnButtonUpdate(long buttonID, long* check, VARIANT_BOOL* _enable);
  
  //     
  virtual void       ShowControls();
//   ##################################################################
  
// DocumentFrameEventCalback #########################################################
  // frBeginPaintGL        -      OpenGL
  virtual BOOL BeginPaintGL ( IDocumentFramePtr & docFrame, ksGLObjectPtr & glObj, long drawMode );
  // frAddGabarit          -   
  virtual BOOL AddGabarit( IDocumentFramePtr & docFrame, IGabaritObjectPtr & gabObj );
  // frCloseFrame          -  
  virtual BOOL CloseFrame( IDocumentFramePtr & docFrame );
// DocumentFrameEventCalback #########################################################

// ADVCTreeEventsCallBack #########################################################
  virtual void OnMenuCommand ( long Id );
// ADVCTreeEventsCallBack #########################################################

// ATreeCtrlEventCallBack #########################################################
  virtual void OnExpandOrCollapse( struct INode * Node, bool collapse );
  virtual void OnNodeClick       ( struct INode * Node );
// ATreeCtrlEventCallBack #########################################################
  

  static bool WINAPI LibObj::SELECTFILTERPROC( IEntity* entity );
  static int  WINAPI LibObj::SELECTCALLBACKPROC( IEntity* entity, IRequestInfo* info ); 
  
  BOOL OnSelectFace         ( IFaceDefinitionPtr & face );
  void CreateForce          ( IFaceDefinitionPtr & face ); //   
  

  void SelectFacesForForce();
  void SelectFaces( long procID, long promtID );

  void OnOffTesselations( SArray<long> & iids, bool vis, bool oldVis, bool del );

  
  bool AddNode( LPCTSTR key, long nameID, int index ); 
  
  LPCTSTR MakeNodeName( LPCTSTR name, int index ); 

  bool IsArrowsVisible();
  void MakeTessellations();
  void OffAllTessellations();
  void LoadArrowParams();
};


////////////////////////////////////////////////////////////////////////////////
// 
//
bool GetFullName( LPCTSTR inName, LPTSTR outName, int outNameLen );
LibObj * FindOrCreateLibObj( IDocumentFramePtr & docFrame, bool create );

void   GetNewKompasAPI();
 
//------------------------------------------------------------------------------
//    
// ---
template <class T>
int FindT( T& o, SArray<T>& arr ) {
  for( int i = 0, count = arr.Count(); i < count; i++ )
    if ( o == arr[i] )
      return i;
    return -1;
}

//------------------------------------------------------------------------------
//    
// ---
template <class T>
int FindT( T& o, PArray<T>& arr ) {
  for( int i = 0, count = arr.Count(); i < count; i++ )
    //    if ( !memcmp( &o, &arr[i], sizeof(T) ) )
    if ( o == *arr[i] )
      return i;
    return -1;
}

//------------------------------------------------------------------------------
//     id
// ---
template <class T>
int GetIndexByID( long id, PArray<T>& arr ) {
  if ( id ) {
    for( int i = 0, count = arr.Count(); i < count; i++ )
      if ( arr[i]->GetID() == id )
        return i;
  }
  return -1;
}

extern AFX_EXTENSION_MODULE OneWindowDLL;
#endif
