/***************************************************************************
             mreportengine.h  -  Kugar report engine
             -------------------
   begin     : Sun Aug 15 1999
   copyright : (C) 1999 by Mutiny Bay Software
   email     : info@mutinybaysoftware.com
   copyright : (C) 2002 Alexander Dymo
   email     : cloudtemple@mksat.net
***************************************************************************/

#ifndef MREPORTENGINE_H
#define MREPORTENGINE_H

#include <tqobject.h>
#include <tqpicture.h>
#include <tqpaintdevicemetrics.h>
#include <tqsize.h>
#include <tqmemarray.h>
#include <tqdom.h>
#include <tqguardedptr.h>

#include "mlineobject.h"
#include "mlabelobject.h"
#include "mspecialobject.h"
#include "mfieldobject.h"
#include "mreportsection.h"
#include "mreportdetail.h"
#include "mpagecollection.h"

/**Kugar report engine
  *@author Mutiny Bay Software
  */

namespace Kugar
{

class MReportEngine : public TQObject
{
    Q_OBJECT
  TQ_OBJECT

public:
    enum PageOrientation { Portrait, Landscape };

    enum PageSize {
        A4, B5, Letter, Legal, Executive,
        A0, A1, A2, A3, A5, A6, A7, A8, A9, B0, B1,
        B10, B2, B3, B4, B6, B7, B8, B9, C5E, Comm10E,
        DLE, Folio, Ledger, Tabloid, NPageSize
    };

    MReportEngine();
    MReportEngine( const MReportEngine& mReportEngine );
    MReportEngine operator=( const MReportEngine& mReportEngine );
    virtual ~MReportEngine();

    bool setReportData( const TQString & );
    bool setReportData( TQIODevice * );
    bool setReportData( const TQDomDocument& );
    bool setReportTemplate( const TQString & );
    bool setReportTemplate( TQIODevice * );
    int getRenderSteps()
    {
        return records.length() / 2;
    }
    MPageCollection* renderReport();

    void addRef();
    void removeRef();
public slots:
    void slotCancelRendering();

signals:
    void signalRendertqStatus( int );
    void preferedTemplate( const TQString & );

protected:
    void recalcDimensions();
    void recalcAttribute( const TQString& name, TQDomNamedNodeMap attributes );

private:

    MPageCollection *m_pageCollection;
    bool m_needRegeneration;
    /** Report data document */
    TQDomDocument rd;
    /** Report template document */
    TQDomDocument rt;

    /** Report painter */
    TQPainter p;

    /** Report page size */
    int pageSize;
    /** Report page orientation */
    int pageOrientation;
    /** Report top margin */
    int topMargin;
    /** Report top margin */
    int bottomMargin;
    /** Report top margin */
    int leftMargin;
    /** Report top margin */
    int rightMargin;

    /** Report page width */
    int pageWidth;
    /** Report page height */
    int pageHeight;

    float widthDelta;
    float heightDelta;

    /** Report header */
    MReportSection rHeader;
    /** Page header */
    MReportSection pHeader;
    /** Detail headers */
    TQPtrList<MReportSection> dHeaders;
    /** Detail sections */
    TQPtrList<MReportDetail> details;
    /** Detail footers */
    TQPtrList<MReportSection> dFooters;
    /** Page footer */
    MReportSection pFooter;
    /** Report footer */
    MReportSection rFooter;

    /** Stores the combined heights of the detail levels */
    int heightOfDetails;

    /** Current y position on page */
    int currY;
    /** Current height of page excluding margins */
    int currHeight;
    /** Current page number */
    int currPage;
    /** Current report date */
    TQDate currDate;

    /** Grand total array */
    TQPtrList<TQMemArray<double> > grandTotal;

    /** Cancel rendering flag */
    bool cancelRender;
    int m_refCount;
private:
    // The set of records being rendered.
    TQDomNodeList records;
    /** Clears report formatting */
    void clearFormatting();
    /** Starts a new page of the report */
    void startPage( MPageCollection* pages );
    /** Finishes the current page of the report */
    void endPage( MPageCollection* pages );
    /** Finishes the current page and adds a new page */
    void newPage( MPageCollection* pages );
    /** Draws the report header object to the current page */
    void drawReportHeader( MPageCollection* pages );
    /** Draws the page header to the current page */
    void drawPageHeader( MPageCollection* pages );
    /** Draws the page footer to the current page */
    void drawPageFooter( MPageCollection* pages );
    /** Draws the report footer to the current page */
    void drawReportFooter( MPageCollection* pages );

    /** Gets the metrics for the selected page size */
    TQSize getPageMetrics( int size, int orientation );

    void initData();
    void initTemplate();

    /** Sets the main tqlayout attributes for the report */
    void setReportAttributes( TQDomNode* report );

    int scaleDeltaWidth( int width ) const;
    int scaleDeltaHeight( int width ) const;

    /** Sets the tqlayout attributes for the given report section */
    void setSectionAttributes( MReportSection* section, TQDomNode* report );
    /** Sets the tqlayout attributes for the detail headers and footers */
    void setDetMiscAttributes( MReportSection* section, TQDomNode* report );
    /** Sets the tqlayout attributes for the detail section */
    void setDetailAttributes( TQDomNode* report );
    /** Sets a line's tqlayout attributes */
    void setLineAttributes( MLineObject* line, TQDomNamedNodeMap* attr );
    /** Sets a label's tqlayout attributes */
    void setLabelAttributes( MLabelObject* label, TQDomNamedNodeMap* attr );
    /** Sets a special field's tqlayout attributes */
    void setSpecialAttributes( MSpecialObject* field, TQDomNamedNodeMap* attr );
    /** Sets a field's tqlayout attributes */
    void setFieldAttributes( MFieldObject* field, TQDomNamedNodeMap* attr );
    /** Sets a calculated field's tqlayout attributes */
    void setCalculatedFieldAttributes( MCalcObject* field, TQDomNamedNodeMap* attr );

    /** Copies member data from one object to another.
      * Used by the copy constructor and assignment operator
      */
    void copy( const MReportEngine* mReportEngine );

    /** Finds the detail header object, which is apropriate for the given level */
    MReportSection *findDetailHeader( int level );
    /** Finds the detail object, which is apropriate for the given level */
    MReportDetail *findDetail( int level );
    /** Finds the detail footer object, which is apropriate for the given level */
    MReportSection *findDetailFooter( int level );
};

}

#endif
