#ifndef INCLUDE_NASTBOX2D_H
#define INCLUDE_NASTBOX2D_H
//-----------------------------------------------------------------------------
// NastBox2d.h
//-----------------------------------------------------------------------------
//
//  Copyright (C) 1998 Technische Universitaet Muenchen, Germany
//                   written by Bernhard Brueck
//
//  This file is part of Nast++
//
//-----------------------------------------------------------------------------
//  Mit CNastBox2d wird ein rechteckiger Bereich festgelegt. Die Seiten
//  sind parallel zu den Koordinatenachsen.
//
//                                                     pntMax()
//      +-------------------------------------------------+      --- maxY()
//      |                                                 |       ^
//      |                                                 |       |
//      |                                                 |       |
//      |                                                 |       |
//      |                                                 |       |
//      |                                                 |    
//      |                                                 |     sizeY()
//      |                                                 |       
//      |                                                 |       |
//      |                                                 |       |
//      |                                                 |       |
//      |                                                 |       v
//      +-------------------------------------------------+      --- minY()
//  pntMin()
//
//      |<------------------- sizeX() ------------------->|
//     minX()                                          maxX()
//
//    ^ y
//    |
//    |
//    +--->
//       x
//  z.B.
//
//-----------------------------------------------------------------------------
//  Aenderungen:
//     

#include "NastConfig.h"
#include "NastObject.h"
#include "NastPoint2d.h"

class CNastBox2d : public CNastObject
{
public:
    //-------------------------------------------------------------------------
    //                         Konstruktor + Destruktor
    //-------------------------------------------------------------------------
    // Mit folgenden Angaben laesst sich eine Box erzeugen:
    //   - Angabe der Koordinaten als doubles
    //   - Angabe der Koordinaten als Punkte
    //   - Angabe eines Ursprungs und der Ausdehnung der Box
   
    CNastBox2d( double x0, double y0,

        double x1, double y1 );

    CNastBox2d( const CNastPoint2d &pntFirst,
        	const CNastPoint2d &pntSecond );

    CNastBox2d( const CNastPoint2d &pntOrigin, 
        	const double sizeX, const double sizeY );

    virtual ~CNastBox2d();			            

    CNastBox2d( const CNastBox2d &other);	            
    const CNastBox2d& operator=( const CNastBox2d &other );

    //-------------------------------------------------------------------------
    //                             Memberfunktionen
    //-------------------------------------------------------------------------
    // CNastPoint2d pntMin()  Punkt mit minimalen Koordinaten
    // CNastPoint2d pntMax()  Punkt mit maximalen Koordinaten
    //
    // double sizeX()  Ausdehnung in x-Richtung
    // double sizeY()  Ausdehnung in y-Richtung
    //
    // double minX()   minimale x-Koordinate
    // double minY()   minimale y-Koordinate
    // double maxX()   maximale x-Koordinate
    // double maxY()   maximale y-Koordinate
    //
    // expand(dx,dy)   eine um dx,dy vergroesserte Box
    //

    CNastPoint2d pntMin() const;
    CNastPoint2d pntMax() const;

    double sizeX() const;
    double sizeY() const;

    double minX() const;
    double minY() const;

    double maxX() const;
    double maxY() const;

    bool isInside( const CNastPoint2d &pnt) const;
    bool isInside( const CNastBox2d   &box) const;
    bool isOutside( const CNastPoint2d &pnt) const;
    bool isOutside( const CNastBox2d   &box) const;

    CNastBox2d expand( double dx, double dy);
    
    //-------------------------------------------------------------------------
    //                                  Debug
    //-------------------------------------------------------------------------
    //  debugInfo    gibt Information ueber den Zustand des Objekts aus
    //  assertValid  testet das Objekt auf Integritaet
    //
    virtual void debugDump( CNastDumpContext &dumpContext ) const;
    virtual void assertValid() const;


private:
    //-------------------------------------------------------------------------
    //                            Membervariablen
    //-------------------------------------------------------------------------
    CNastPoint2d m_pntMin;
    CNastPoint2d m_pntMax;
};


//-------------------------------------------------------------------------
//                                  inline
//-------------------------------------------------------------------------

//  Punkt mit minimalen Koordinaten
inline CNastPoint2d CNastBox2d::pntMin() const
{
    return m_pntMin;
}

//  Punkt mit maximalen Koordinaten
inline CNastPoint2d CNastBox2d::pntMax() const
{
    return m_pntMax;
}

//  Ausdehnung in x-Richtung
inline double CNastBox2d::sizeX() const
{
    return m_pntMax.x() - m_pntMin.x();
}

//  Ausdehnung in y-Richtung
inline double CNastBox2d::sizeY() const
{
    return m_pntMax.y() - m_pntMin.y();
}

//  minimale x-Koordinate
inline double CNastBox2d::minX() const
{
    return m_pntMin.x();
}

//  minimale y-Koordinate
inline double CNastBox2d::minY() const
{
    return m_pntMin.y();
}

// maximale x-Koordinate
inline double CNastBox2d::maxX() const
{
    return m_pntMax.x();
}

// maximale y-Koordinate
inline double CNastBox2d::maxY() const
{
    return m_pntMax.y();
}


inline bool 
CNastBox2d::isInside( const CNastPoint2d &pnt) const
{
    return pnt.x() + NAST_GEOMETRIE_EPS >= m_pntMin.x() &&
           pnt.x() - NAST_GEOMETRIE_EPS <= m_pntMax.x() &&
           pnt.y() + NAST_GEOMETRIE_EPS >= m_pntMin.y() &&
           pnt.y() - NAST_GEOMETRIE_EPS <= m_pntMax.y();
}

inline bool 
CNastBox2d::isInside( const CNastBox2d &box ) const
{
    return box.m_pntMin.x() + NAST_GEOMETRIE_EPS >= m_pntMin.x() &&
           box.m_pntMin.y() + NAST_GEOMETRIE_EPS >= m_pntMin.y() &&
           box.m_pntMax.x() - NAST_GEOMETRIE_EPS <= m_pntMax.x() &&
           box.m_pntMax.y() - NAST_GEOMETRIE_EPS <= m_pntMax.y();
}

inline bool 
CNastBox2d::isOutside( const CNastPoint2d &pnt) const
{
    return pnt.x() - NAST_GEOMETRIE_EPS <= m_pntMin.x() ||
           pnt.x() + NAST_GEOMETRIE_EPS >= m_pntMax.x() ||
           pnt.y() - NAST_GEOMETRIE_EPS <= m_pntMin.y() ||
           pnt.y() + NAST_GEOMETRIE_EPS >= m_pntMax.y();
}

inline bool 
CNastBox2d::isOutside( const CNastBox2d &box) const
{
    return box.m_pntMax.x() - NAST_GEOMETRIE_EPS <= m_pntMin.x() ||
           box.m_pntMax.y() - NAST_GEOMETRIE_EPS <= m_pntMin.y() ||
           box.m_pntMin.x() + NAST_GEOMETRIE_EPS >= m_pntMax.x() ||
           box.m_pntMin.y() + NAST_GEOMETRIE_EPS >= m_pntMax.y();
}

inline CNastBox2d 
CNastBox2d::expand( double dx, double dy)
{
    return CNastBox2d( m_pntMin.x() - dx,
        	       m_pntMin.y() - dy,
        	       m_pntMax.x() + dx,
        	       m_pntMax.y() + dy );
}


#endif // INCLUDE_NASTBOX2D_H

