// ************************************************************************************************************
// Author: Marcin Załęczny
// Release Date: 2010-11-08
// Last modified date: 2010-11-09
// Licence: The GNU Lesser General Public License, version 3.0 (LGPLv3)
// ************************************************************************************************************
#ifndef __MZSTDXPS_XPS_PAGE_H__
#define __MZSTDXPS_XPS_PAGE_H__

#include "mzstdxpsCommon.h"
#include "mzXmlDocument.h"
#include "mzXpsRelationships.h"
#include "mzObject.h"
#include "mzString.h"


class CXpsDocument;
class DECLSPEC_MZSTDXPS CXpsRenderTransform : public CObject {
public:
    float m11;
    float m12;
    float m21;
    float m22;
    float dx;
    float dy;

    WINAPI CXpsRenderTransform();
    WINAPI CXpsRenderTransform(float m11, float m12, float m21, float m22, float dx, float dy);
    virtual WINAPI ~CXpsRenderTransform();

    VOID WINAPI setParamsForRotation(float angleRad);
    VOID WINAPI setParamsForSkewing(float xSkewFactor, float ySkewFactor);
    VOID WINAPI setParamsForReversingXAxis();
    VOID WINAPI setParamsForReversingYAxis();
    VOID WINAPI setParamsForScaling(float xScaleFactor, float yScaleFactor);
    VOID WINAPI setParamsForTranslation(float dx, float dy);
    VOID WINAPI addParamsForTranslation(float dx, float dy);
    VOID WINAPI reset();
    
    virtual CString WINAPI toString();
};

class DECLSPEC_MZSTDXPS CXpsPage : public CXmlDocument {
public:
	WINAPI CXpsPage(CXpsDocument* doc, UINT pagenum, BOOL useCommonPagePT = TRUE);
	WINAPI CXpsPage(CXpsDocument* doc, UINT pagenum, CString width, CString height, BOOL useCommonPagePT = TRUE);
    virtual WINAPI ~CXpsPage();
    virtual VOID WINAPI saveXmlFile(CString fname);

    CString WINAPI pointToString(float x, float y);
    
    CXmlNode* WINAPI addFixedResourcesSection();
    CXmlNode* WINAPI createFixedResourceRectangle(CString resourceId, float x1, float y1, float width, float height);
    CXmlNode* WINAPI addCanvas(CXmlNode* parentNode = NULL);
    // Canvas with RenderTransform
    CXmlNode* WINAPI addCanvas(CXmlNode* parentNode, float m11, float m12, float m21, float m22, float dx, float dy);
    CXmlNode* WINAPI addCanvas(CXmlNode* parentNode, CXpsRenderTransform* rt);
    CXmlNode* WINAPI addPath(CXmlNode* canvasNode, CString data, CString borderColor,
                             float borderThickness, CString strokeLineJoin, float strokeMiterLimit,
                             CString fillColor, float borderDashGap, float borderDashLine, CString clip);
    CXmlNode* WINAPI addLine(CXmlNode* canvasNode, float x1, float y1, float x2, float y2, CString color, float thickness, float strokeMiterLimit, float borderDashGap = 0, float borderDashLine = 0);
    CXmlNode* WINAPI addHLine(CXmlNode* canvasNode, float x, float y, float width, CString color, float thickness, float strokeMiterLimit, float borderDashGap = 0, float borderDashLine = 0);
    CXmlNode* WINAPI addDashedHLine(CXmlNode* canvasNode, float x, float y, float width, CString color, float thickness, float strokeMiterLimit, float borderDashGap, float borderDashLine);
    CXmlNode* WINAPI addVLine(CXmlNode* canvasNode, float x, float y, float height, CString color, float thickness, float strokeMiterLimit, float borderDashGap = 0, float borderDashLine = 0);
    CXmlNode* WINAPI addDashedVLine(CXmlNode* canvasNode, float x, float y, float height, CString color, float thickness, float strokeMiterLimit, float borderDashGap, float borderDashLine);
    CXmlNode* WINAPI addRectangle(CXmlNode* canvasNode, float x1, float y1, float width, float height,
                        CString color, float borderThickness, float strokeMiterLimit,
                        CString fillColor=COMMON_EMPTY_STRING, float borderDashGap = 0,
                        float borderDashLine = 0);
    CXmlNode* WINAPI addRectangleLB(CXmlNode* canvasNode, float x1, float y1, float width, float height, CString color, float borderThickness, float strokeMiterLimit, float borderDashGap = 0, float borderDashLine = 0);
    CXmlNode* WINAPI addRectangleBR(CXmlNode* canvasNode, float x1, float y1, float width, float height, CString color, float borderThickness, float strokeMiterLimit, float borderDashGap = 0, float borderDashLine = 0);
    CXmlNode* WINAPI addRectangleLBR(CXmlNode* canvasNode, float x1, float y1, float width, float height, CString color, float borderThickness, float strokeMiterLimit, float borderDashGap = 0, float borderDashLine = 0);
    CXmlNode* WINAPI addDateFieldDDMMYYYY(CXmlNode* canvasNode, float x, float y, float width, float height, float groupSpacing, float fontSize, CString fontFilename, CString color, float borderThickness, float strokeMiterLimit, float borderDashGap = 0, float borderDashLine = 0);
    CXmlNode* WINAPI addSquare(CXmlNode* canvasNode, float x1, float y1, float width, CString color, float borderThickness, float strokeMiterLimit, CString fillColor=COMMON_EMPTY_STRING, float borderDashGap = 0, float borderDashLine = 0);
    CXmlNode* WINAPI addCircle(CXmlNode* canvasNode, float cx, float cy, float r, CString color, float borderThickness, CString fillColor=COMMON_EMPTY_STRING, float borderDashGap = 0, float borderDashLine = 0);
    CXmlNode* WINAPI addLabel(CXmlNode* canvasNode, float x, float y, CString text, float width, float height, CString fontFilename, float fontSize, CString color, CString styleSimulation = L"None", CString borderColor = COMMON_EMPTY_STRING, CString fillColor=COMMON_EMPTY_STRING, float borderThickness = 0.0, float strokeMiterLimit = 1.0, float paddingLeft = 4.0, float paddingTop = 4.0, float rotationAngle = 0.0);
    CXmlNode* WINAPI addGlyph(CXmlNode* canvasNode, float x, float y, CString text, CString fill, CString fontFilename, float fontSize, float rotationAngle = 0, CString styleSimulation = L"None", CXpsRenderTransform* rt = NULL);
    CXmlNode* WINAPI addVerticalGlyph(CXmlNode* canvasNode, float x, float y, CString text, CString fill, CString fontFilename, float fontSize, BOOL clockwise = TRUE, CString styleSimulation = L"None");
    CString WINAPI getIndicesAttrForText(CString text, INT deltaIndiceSpacing = 0);
    CXmlNode* WINAPI addGlyphWithIndices(CXmlNode* canvasNode, float x, float y, CString text, CString fill, CString fontFilename, float fontSize, INT deltaIndiceSpacing = 0, float rotationAngle = 0);
    CXmlNode* WINAPI addCollectionOfGlyphs(CXmlNode* canvasNode, float startX, float startY, CString text, CString fill, CString fontFilename, float fontSize, float deltaX, float deltaY = 0, float rotationAngle = 0);

    CXmlNode* WINAPI addLabeledTextField(CXmlNode* canvasNode, float x, float y, CString label,
                        float width, float height, CString fontFilename, float fontSize, CString color,
                        CString styleSimulation = L"None", float textFieldUnitWidth = 10.0,
                        CString borderColor = COMMON_EMPTY_STRING, CString textFieldFillColor=L"#ffffff",
                        CString labelLineBorderColor=COMMON_EMPTY_STRING, CString labelLineFillColor=COMMON_EMPTY_STRING,
                        float borderThickness = 0.0,
                        float strokeMiterLimit = 1.0, float labelPaddingLeft = 4.0, float labelPaddingTop = 4.0,
                        float rotationAngle = 0.0);
    CXmlNode* WINAPI addTextInRectangles(CXmlNode* canvasNode, float x, float y, CString text, float unitWidth,
                        float unitHeight, float spacing, CString fontFilename, float fontSize, CString color,
                        CString styleSimulation = L"None", CString borderColor = COMMON_EMPTY_STRING,
                        CString fillColor=L"#ffffff", float borderThickness = 1, float strokeMiterLimit = 1.0,
                        float rotationAngle = 0.0);
    CXmlNode* WINAPI drawCharsForAdjustingFontMetrics(CXmlNode* canvasNode, float x, float y, CString text, CString fontFilename, float fontSize, CString color, CString styleSimulation, float height, float* letterWidthsArray);

    CXmlNode* WINAPI getResourceDictionary();
    BOOL WINAPI getIndexDataForChar(WCHAR ch, INT& index, INT& spacing);

protected:
    // Pointer on parent document - not to release
    CXpsDocument* _doc;
    UINT _pagenum;    
    CXpsRelationships* _rels;         // File 'XPS_HOME/Documents/[_number]/Pages/_rels/[pagenum].fpage.rels
    float _currentFontSize; // current default font size - used every time font size in text-drawing function
                            // call is ommited

    VOID WINAPI _commonInit(CString width, CString height, BOOL useCommonPagePT);
    BOOL WINAPI _getIndexData(INT pos, WCHAR* indices_string, INT& index, INT& spacing);

    static WCHAR* _small_letters;
    static WCHAR* _small_letters_indices;
    static INT _small_letters_len;
    static WCHAR* _big_letters;
    static WCHAR* _big_letters_indices;
    static INT _big_letters_len;
    static WCHAR* _small_pl_letters;
    static WCHAR* _small_pl_letters_indices;
    static INT _small_pl_letters_len;
    static WCHAR* _big_pl_letters;
    static WCHAR* _big_pl_letters_indices;
    static INT _big_pl_letters_len;
    static WCHAR* _digits;
    static WCHAR* _digits_indices;
    static INT _digits_len;
    static WCHAR* _special_chars;
    static WCHAR* _special_chars_indices;
    static INT _special_chars_len;
    static WCHAR* _digits_upper_chars;
    static WCHAR* _digits_upper_chars_indices;
    static INT _digits_upper_chars_len;
};

#endif
