// $Source: /usr/local/SimSoft/SoftShop/XMath/HMatrx3D/HMatrx3D.h,v $
// $Revision: 1.20 $
// $Author: baum $
// $Date: 2001/11/29 15:52:25 $
//
// Login name of the user who locked the revision
// $Locker:  $
// Tag name used to checkout the file
// $Name: Release-20 $
// State assigned to revision
// $State: Exp $
//
//
// $Log: HMatrx3D.h,v $
// Revision 1.20  2001/11/29 15:52:25  baum
// -In Kalender.cpp und Kalender.h Handsteuerung eingebaut
//

#include "Angle.h"
#include "Vec3D.h"

#ifndef _HMATRX3D_H
#define _HMATRX3D_H	1

#ifdef _HMATRX3D_CPP
#  undef _impexp
#  define _impexp __declspec(dllexport)
#elif defined BUILD_XMATH_DLL
#  undef _impexp
#  define _impexp
#else
#  undef _impexp
#  define _impexp __declspec(dllimport)
#endif

#if defined __GNUC__ || defined __hpux
#  undef _impexp
#  define _impexp
#endif

// Please note, that following common mathematical conventions
// the XMath-subsystem defines Vectors to be column vectors.
// All Vector- and Matrix-operations are implemented suitably.

#define HDim3D	4

//==================================================================
//		Class-Header
//		for class HMatrx3D
//==================================================================

class _impexp HMatrx3D {
  public:
    //Konstruktoren
    HMatrx3D ();
    HMatrx3D (const HMatrx3D&);
    HMatrx3D (double, double, double, double,
              double, double, double, double,
              double, double, double, double,
              double, double, double, double);

    //Destruktor
    ~HMatrx3D ();

    //Zuweisungsoperator
    HMatrx3D& operator = (const HMatrx3D&);

    //Vergleichsoperatoren
    bool operator == (const HMatrx3D&) const;
    bool operator != (const HMatrx3D&) const;

    //arithmetische Operatoren
    HMatrx3D  operator +  (const HMatrx3D&) const;
    HMatrx3D& operator += (const HMatrx3D&);
    HMatrx3D  operator -  (const HMatrx3D&) const;
    HMatrx3D& operator -= (const HMatrx3D&);
    HMatrx3D  operator *  (const double&)   const;
    HMatrx3D& operator *= (const double&);
    HMatrx3D  operator *  (const HMatrx3D&) const;
    HMatrx3D& operator *= (const HMatrx3D&);
    Vec3D     operator *  (const Vec3D&)    const;

    //Wertrueckgabe
    // oglIndex is an Array-Index from 0 to 15
    double operator [] (unsigned oglIndex)          const;
    double operator () (unsigned row, unsigned col) const;

    // Get a Pointer of Matrix-Array for OpenGL
    const double* OpenGLForm () const;

    //Transponierte Matrix
    HMatrx3D trans () const;

    //Inverse Matrix
    HMatrx3D inv () const;

    //Determinante
    double det () const;

    //Print-Funktion
    ostream& print (ostream&) const;

  private:
    //datamembers
    double ObjVal [HDim3D] [HDim3D];

    //Adjunkt
    double adj (unsigned, unsigned) const;

  // friend
    friend Vec3D  Vec3D::operator *  (const HMatrx3D&) const;
    friend Vec3D& Vec3D::operator *= (const HMatrx3D&);
    friend _impexp HMatrx3D& FrustumHMatrx3D (HMatrx3D& target,
                                      const double& left,   const double& right,
                                      const double& bottom, const double& top,
                                      const double& nearClip, const double& farClip);
    friend _impexp HMatrx3D& OrthoHMatrx3D (HMatrx3D& target,
                                    const double& left,   const double& right,
                                    const double& bottom, const double& top,
                                    const double& nearClip, const double& farClip);
    friend _impexp HMatrx3D& LookAtHMatrx3D (HMatrx3D& target,
                                     const Vec3D& eyePos,
                                     const Vec3D& viewCenter,
                                     const Vec3D& viewUp);

}; // class HMatrx3D

//==================================================================
//		Functions-Header
//		for globale Functions from HMatrx3D.h
//==================================================================

// Unit-Matrix
extern const HMatrx3D _impexp EM3D;


_impexp HMatrx3D moveHMatrx3D (const Vec3D&);

_impexp HMatrx3D scaleHMatrx3D (const Vec3D&);

_impexp HMatrx3D rotHMatrx3D (const Vec3D&, const Angle&);

_impexp HMatrx3D XrotHMatrx3D (const Angle&);

_impexp HMatrx3D YrotHMatrx3D (const Angle&);

_impexp HMatrx3D ZrotHMatrx3D (const Angle&);


_impexp HMatrx3D& FrustumHMatrx3D (HMatrx3D& target,
                                   const double& left,   const double& right,
                                   const double& bottom, const double& top,
                                   const double& nearClip, const double& farClip);

_impexp HMatrx3D& PerspectiveHMatrx3D (HMatrx3D& target,
                                       const double& fieldOfView, const double& aspect,
                                       const double& nearClip, const double& farClip);

_impexp HMatrx3D& OrthoHMatrx3D (HMatrx3D& target,
                                 const double& left,   const double& right,
                                 const double& bottom, const double& top,
                                 const double& nearClip, const double& farClip);

_impexp HMatrx3D& LookAtHMatrx3D (HMatrx3D& target,
                                  const Vec3D& eyePos,
                                  const Vec3D& viewCenter,
                                  const Vec3D& viewUp);

inline ostream& operator << (ostream& o, const HMatrx3D& m) {
  return m.print (o);
}

#endif
