/*
 * Copyright (c) 2007-2009 by Oleg Trifonov <otrifonow@gmail.com>
 *
 * This file is free software; you can redistribute it and/or modify
 * it under the terms of either the GNU General Public License version 2
 * or the GNU Lesser General Public License version 2.1, both as
 * published by the Free Software Foundation.
 */

#ifndef _TR_RTF_H_
#define _TR_RTF_H_

#include <string>

#include "trStream.h"
#include "trImage.h"



struct TrRTFDocumentFormat;
struct TrRTFSectionFormat;
struct TrRTFParagraphFormat;
struct TrRTFTableRowFormat;
struct TrRTFTableCellFormat;
struct TrRTFCharacterFormat;

// переводит твипы в сантиметры
inline double twips2cm(int twips) {
	return 1.0*twips/569.0716;
}

// переводит сантиметры в твипы 
inline int cm2twips(double cm) {
	return (int)(cm*569.0716);

}

enum {
	RTF_FONT_DEFAULT = 0,
	RTF_FONT_BOLD = 1,
	RTF_FONT_ITALIC = 2,
	RTF_FONT_UNDERLINED = 4
};

enum {
	RTF_ALIGN_LEFT,
	RTF_ALIGN_RIGHT,
	RTF_ALIGN_CENTER,
	RTF_ALIGN_JUSTIFY
};

class TrRTFWriter {
public:
	TrRTFWriter();
	~TrRTFWriter();

	// задает таблицу шрифтов, вызывается перед созданием документа
	void SetFontTable(char *fonts);
	// задает таблицу цветов, вызывается перед созданием документа
	void SetColorTable(char *colors);
	// задает формат документа, вызывается перед созданием документа
	void SetDocumentFormat(const TrRTFDocumentFormat &ndf);
	
	// создает документ
	bool Create(const char *fileName);
	bool Create(TrStream *s);
	// закрывает документ
	void Close();

	// создает новую секцию
	void StartSection();
	void StartSection(const TrRTFSectionFormat &nsf);

	// создает параграф
	void StartParagraph(const std::string text, bool newPar);
	void StartParagraph(const std::string text, bool newPar, const TrRTFParagraphFormat &npf);

	// загружает рисунок и вставляет в текущую позицию
//	bool LoadImage(const char *fileName, int width = 0, int height = 0);
//	bool LoadImage(TrImage *img, int width = 0, int height = 0);

	// создает ряд таблицы
	void StartTableRow();
	void StartTableRow(const TrRTFTableRowFormat &ntrf);
	// завершает ряд таблицы
	void EndTableRow();

	// создает ячейку в ряду таблицы. получает координату правой границы ячейки 
	void StartTableCell(int rightMargin);
	void StartTableCell(int rightMargin, const TrRTFTableCellFormat &ntcf);
	void StartTableCell(double rightMargin);
	void StartTableCell(double rightMargin, const TrRTFTableCellFormat &ntcf);
	// завершает ячейку таблицы
	void EndTableCell();	

	// получение указателей на свойства форматирования
	TrRTFDocumentFormat* GetDocumentFormat() const { return df; };
	TrRTFSectionFormat* GetSectionFormat() const { return sf; };
	TrRTFParagraphFormat* GetParagraphFormat() const { return pf; };
	TrRTFTableRowFormat* GetTableRowFormat() const { return trf; };
	TrRTFTableCellFormat* GetTableCellFormat() const { return tcf; };


	// процедуры высокого уровня

	// задает поля в сантиметрах
	void SetMargins(double left, double right, double top, double bottom);
	void Write(const std::string &str);
	void Writeln(const std::string &str);
	void Write(const std::string &str, int font);
	void Writeln(const std::string &str, int font);
	// RTF_FONT_xxx
	void Write(const std::string &str, int font, int align);
	void Writeln(const std::string &str, int font, int align);
	// RTF_ALIGN_xxx

	void SetFontType(int font);
	void SetAlign(int align);

	void SetPaperSize(int width, int height, bool landscape = false);
	void SetPaperSize(double width, double height, bool landscape = false);


private:
	TrStream *stream;
	bool deleteStream;

	std::string fontTable;
	std::string colorTable;

	TrRTFDocumentFormat *df;
	TrRTFSectionFormat *sf;
	TrRTFParagraphFormat *pf;
	TrRTFTableRowFormat *trf;
	TrRTFTableCellFormat *tcf;

	// пишет строку в файл
	void WriteStr(const std::string &str);
	void WriteStr(char *str);
	// записывает заголовок RTF-файла
	void writeHeader();
	// записывает блок описания формата документа 
	void writeDocumentFormat();
	// записывает блок описания формата секции
	void writeSectionFormat();
	// записывыет блок описания формата параграфа
	void writeParagraphFormat();
	// получение название бордюра
	const std::string getBorderName(int borderType) const;
	// Gets shading name
	const std::string getShadingName(int shadingType, bool cell) const;
	// конвертирует не ASCII символы в строке esc-последовательностями
	const std::string string2hex(const std::string &str);

};


// Структура формата документа RTF
struct TrRTFDocumentFormat {	
	int viewKind;							// режим просмотра документа
	int viewScale;							// масштаба отображения
	int paperWidth;						// ширина бумаги (по умолчанию 12240)
	int paperHeight;						// высота бумаги (по умолчанию 15840)
	int marginLeft;						// левое поле в twips (по умолчанию 1800)
	int marginRight;						// правое поле в twips (по умолчанию 1800)
	int marginTop;							// верхнее поле в twips (по умолчанию 1440)
	int marginBottom;						// нижнее поле в twips (по умолчанию 1440)
	bool facingPages;						// Facing pages (activates odd/even headers and gutters)
	int gutterWidth;						// Gutter width in twips (по умолчанию 0)
	bool readOnly;							// пользователь может редактировать документ
	bool landscape;						// альбомная ориентация

	TrRTFDocumentFormat() {SetDefault(); };
	void SetMargins(int left, int right, int top, int bottom);
	void SetMargins(double left, double right, double top, double bottom);
	void SetPaperSize(int width, int height, bool landscape = false);
	void SetPaperSize(double width, double height, bool landscape = false);
	void SetDefault();
};



// Структура формата секции документа RTF
struct TrRTFSectionFormat {
	int sectionBreak;					// тип разрывателя секции
	bool newSection;					// новая секция
	bool defaultSection;				// форматировать секцию по умолчанию	
	int pageWidth;						// ширина страницы 
	int pageHeight;					// высота страницы 

	int pageMarginLeft;				// отступ слева
	int pageMarginRight;				// отступ справа
	int pageMarginTop;				// отступ сверху
	int pageMarginBottom;			// отступ снизу
	int pageGutterWidth;				// Sets new page gutter width in twips
	int pageHeaderOffset;			// смещение заголовка (по умолчанию 720)
	int pageFooterOffset;			// Sets page footer offset in twips (the default is 720)
	bool showPageNumber;				// показывать номер страницы
	int pageNumberOffsetX;			// смещение справа до номера страницы
	int pageNumberOffsetY;			// смещение сверзу до номера страницы
	bool cols;							// Sets column section format
	int colsNumber;					// число столбцов в секции
	int colsDistance;					// расстояние между столбцами
	bool colsLineBetween;			// рисовать линию между столбцами
	bool landscape;					// альбомная ориентация

	TrRTFSectionFormat() { SetDefault(); };
	void SetDefault();

	void SetMargins(int left, int right, int top, int bottom);
	void SetMargins(double left, double right, double top, double bottom);
	void SetPaperSize(int width, int height, bool landscape = false);
	void SetPaperSize(double width, double height, bool landscape = false);
};



// RTF tab format structure
struct TrRTFTabsFormat {	
	int tabPosition;						// Sets tab position in twips from left margin
	int tabKind;							// Sets tab kind
	int tabLead;							// Sets tab lead
	
	TrRTFTabsFormat() { SetDefault(); };
	void SetDefault();
};



// RTF bullets and numbering format structure
struct TrRTFNumsFormat {
	int numsLevel;							// Sets paragraph numbered level (11 is bulleted paragraph)
	int numsSpace;							// Sets paragraph text distance from bulleted char
	char numsChar;							// Sets paragraph bullet char

	TrRTFNumsFormat() { SetDefault(); };
	void SetDefault();
};



// RTF borders format structure
struct TrRTFBordersFormat {
	int borderKind;						// Sets paragraph border kind
	int borderType;						// Sets paragraph border type
	int borderWidth;						// Sets paragraph border width in twips
	int borderColor;						// Sets paragraph border color
	int borderSpace;						// Sets border distance from paragraph

	TrRTFBordersFormat() { SetDefault(); };
	void SetDefault();
};



// RTF shading format structure
struct TrRTFShadingFormat {
	int shadingIntensity;					// Sets paragraph shading intensity
	int shadingType;							// Sets paragraph shading type
	int shadingFillColor;					// Sets paragraph shading fill color
	int shadingBkColor;						// Sets paragraph shading background color

	TrRTFShadingFormat() { SetDefault(); };
	void SetDefault();
};



// RTF character format structure
struct TrRTFCharacterFormat {
	int animatedCharacter;					// Sets animated text
	bool boldCharacter;						// Sets text to bold
	bool capitalCharacter;					// Sets text to capital
	int backgroundColor;					// Sets text background color (the default is 0)
	int foregroundColor;					// Sets text foreground color (the default is 0)
	int scaleCharacter;						// Sets text scaling value (the default is 100)
	bool embossCharacter;					// Sets text to embossed
	int expandCharacter;					// Sets expansion or compression of the text
	int fontNumber;							// Sets font number
	int fontSize;							// Sets font size (the default is 24)
	bool italicCharacter;					// Sets text to italic
	bool engraveCharacter;					// Sets text to engrave
	int kerningCharacter;					// Sets kerning of the text
	bool outlineCharacter;					// Sets text to outline
	bool smallcapitalCharacter;				// Sets text to small capital
	bool shadowCharacter;					// Sets text shadow
	bool strikeCharacter;					// Sets text to striketrough
	bool doublestrikeCharacter;				// Sets text to double striketrough
	bool subscriptCharacter;				// Sets text to subscript
	bool superscriptCharacter;				// Sets text to superscript
	int underlineCharacter;					// Sets text to underline

	TrRTFCharacterFormat() { SetDefault(); };
	void SetDefault();

};


// RTF paragraph format structure
struct TrRTFParagraphFormat {
	bool verticalText;					// располагать текст вертикально
	int paragraphBreak;						// Sets paragraph break type
	bool newParagraph;						// New paragraph
	bool defaultParagraph;					// Default paragraph formatting
	int paragraphAligment;					// Sets paragraph aligment
	int firstLineIndent;					// Sets first line indent (the default is 0)
	int leftIndent;							// Sets paragraph left indent (the default is 0)
	int rightIndent;						// Sets paragraph right indent (the default is 0)
	int spaceBefore;						// Sets space before paragraph (the default is 0)
	int spaceAfter;							// Sets space after paragraph (the default is 0)
	int lineSpacing;						// Sets line spacing in paragraph
	std::string  paragraphText;					// Sets paragraph text
	bool tabbedText;						// Sets paragraph tabbed text
	bool tableText;							// Sets paragraph table text

	bool paragraphTabs;						// Paragraph has tabs
	struct TrRTFTabsFormat TABS;			// Paragraf RTF_TAB_FORMAT structure

	bool paragraphNums;						// Paragraph is numbered (bulleted)
	struct TrRTFNumsFormat NUMS;			// Paragraph RTF_NUMS_FORMAT structure

	bool paragraphBorders;					// Paragraph has borders
	struct TrRTFBordersFormat BORDERS;		// Paragraph RTF_BORDERS_FORMAT structure

	bool paragraphShading;					// Paragraph has shading
	struct TrRTFShadingFormat SHADING;		// Paragraph RTF_SHADING_FORMAT structure

	struct TrRTFCharacterFormat CHARACTER;	// Paragraph RTF_CHARACTER_FORMAT structure

	TrRTFParagraphFormat() { SetDefault(); };
	void SetDefault();
};


// RTF table row format structure
struct TrRTFTableRowFormat {
	int rowAligment;							// Sets table row aligment
	int rowHeight;								// Sets table row height (the default is 0)
	int marginLeft;							// Sets default cell left margin
	int marginRight;							// Sets default cell right margin
	int marginTop;								// Sets default cell top margin
	int marginBottom;							// Sets default cell bottom margin
	int rowLeftMargin;						// Sets default row left margin

	TrRTFTableRowFormat() { SetDefault(); };
	void SetDefault();
	void SetMargins(int left, int right, int top, int bottom);
	void SetMargins(double left, double right, double top, double bottom);
};

											      
struct TrRTFTableBorderFormat : public TrRTFBordersFormat {
	bool border;							// Border exists

	TrRTFTableBorderFormat() { SetDefault(); };
	void SetDefault() { border = false; }
};




// RTF table cell format structure
struct TrRTFTableCellFormat {
	int textVerticalAligment;							// Sets text vertical aligment
	int marginLeft;										// Sets cell left margin
	int marginRight;										// Sets cell right margin
	int marginTop;											// Sets cell top margin
	int marginBottom;										// Sets cell bottom margin
	int textDirection;									// Sets text direction

	bool cellShading;										// Cell has shading
	struct TrRTFShadingFormat SHADING;				// Cell RTF_SHADING_FORMAT structure

	struct TrRTFTableBorderFormat borderLeft;		// Cell RTF_TABLEBORDER_FORMAT structure
	struct TrRTFTableBorderFormat borderRight;	// Cell RTF_TABLEBORDER_FORMAT structure
	struct TrRTFTableBorderFormat borderTop;		// Cell RTF_TABLEBORDER_FORMAT structure
	struct TrRTFTableBorderFormat borderBottom;	// Cell RTF_TABLEBORDER_FORMAT structure

	TrRTFTableCellFormat() { SetDefault(); };
	void SetDefault();

	// устанавливает рамку указанной ширины и типа
	void SetBorder(int width, int type);

	// отключает рамку
	void ClearBorder();
	
	void SetMargins(int left, int right, int top, int bottom);
	void SetMargins(double left, double right, double top, double bottom);
};

// Paragraph break defs
#define RTF_PARAGRAPHBREAK_NONE						0
#define RTF_PARAGRAPHBREAK_PAGE						1
#define RTF_PARAGRAPHBREAK_COLUMN					2
#define RTF_PARAGRAPHBREAK_LINE						3

// Paragraph align defs
#define RTF_PARAGRAPHALIGN_LEFT						0
#define RTF_PARAGRAPHALIGN_CENTER					1
#define RTF_PARAGRAPHALIGN_RIGHT						2
#define RTF_PARAGRAPHALIGN_JUSTIFY					3

// Paragraph tab kind defs
#define RTF_PARAGRAPHTABKIND_NONE					0
#define RTF_PARAGRAPHTABKIND_CENTER					1
#define RTF_PARAGRAPHTABKIND_RIGHT					2
#define RTF_PARAGRAPHTABKIND_DECIMAL				3

// Paragraph tab lead defs
#define RTF_PARAGRAPHTABLEAD_NONE					0
#define RTF_PARAGRAPHTABLEAD_DOT						1
#define RTF_PARAGRAPHTABLEAD_MDOT					2
#define RTF_PARAGRAPHTABLEAD_HYPH					3
#define RTF_PARAGRAPHTABLEAD_UNDERLINE				4
#define RTF_PARAGRAPHTABLEAD_THICKLINE				5
#define RTF_PARAGRAPHTABLEAD_EQUAL					6

// Paragraph border kind defs
#define RTF_PARAGRAPHBORDERKIND_NONE				0
#define RTF_PARAGRAPHBORDERKIND_TOP					1
#define RTF_PARAGRAPHBORDERKIND_BOTTOM				2
#define RTF_PARAGRAPHBORDERKIND_LEFT				3
#define RTF_PARAGRAPHBORDERKIND_RIGHT				4
#define RTF_PARAGRAPHBORDERKIND_BOX					5

// Paragraph border type defs
#define RTF_PARAGRAPHBORDERTYPE_STHICK				0
#define RTF_PARAGRAPHBORDERTYPE_DTHICK				1
#define RTF_PARAGRAPHBORDERTYPE_SHADOW				2
#define RTF_PARAGRAPHBORDERTYPE_DOUBLE				3
#define RTF_PARAGRAPHBORDERTYPE_DOT					4
#define RTF_PARAGRAPHBORDERTYPE_DASH				5
#define RTF_PARAGRAPHBORDERTYPE_HAIRLINE			6
#define RTF_PARAGRAPHBORDERTYPE_INSET				7
#define RTF_PARAGRAPHBORDERTYPE_SDASH				8
#define RTF_PARAGRAPHBORDERTYPE_DOTDASH			9
#define RTF_PARAGRAPHBORDERTYPE_DOTDOTDASH		10
#define RTF_PARAGRAPHBORDERTYPE_OUTSET				11
#define RTF_PARAGRAPHBORDERTYPE_TRIPLE				12
#define RTF_PARAGRAPHBORDERTYPE_WAVY				13
#define RTF_PARAGRAPHBORDERTYPE_DWAVY				14
#define RTF_PARAGRAPHBORDERTYPE_STRIPED			15
#define RTF_PARAGRAPHBORDERTYPE_EMBOSS				16
#define RTF_PARAGRAPHBORDERTYPE_ENGRAVE			17

// Paragraph shading type defs
#define RTF_PARAGRAPHSHADINGTYPE_FILL				0
#define RTF_PARAGRAPHSHADINGTYPE_HORIZ				1
#define RTF_PARAGRAPHSHADINGTYPE_VERT				2
#define RTF_PARAGRAPHSHADINGTYPE_FDIAG				3
#define RTF_PARAGRAPHSHADINGTYPE_BDIAG				4
#define RTF_PARAGRAPHSHADINGTYPE_CROSS				5
#define RTF_PARAGRAPHSHADINGTYPE_CROSSD			6
#define RTF_PARAGRAPHSHADINGTYPE_DHORIZ			7
#define RTF_PARAGRAPHSHADINGTYPE_DVERT				8
#define RTF_PARAGRAPHSHADINGTYPE_DFDIAG			9
#define RTF_PARAGRAPHSHADINGTYPE_DBDIAG			10
#define RTF_PARAGRAPHSHADINGTYPE_DCROSS			11
#define RTF_PARAGRAPHSHADINGTYPE_DCROSSD			12

// Section break defs
#define RTF_SECTIONBREAK_CONTINUOUS					0
#define RTF_SECTIONBREAK_COLUMN						1
#define RTF_SECTIONBREAK_PAGE							2
#define RTF_SECTIONBREAK_EVENPAGE					3
#define RTF_SECTIONBREAK_ODDPAGE						4

// Table row text align defs
#define RTF_ROWTEXTALIGN_LEFT							0
#define RTF_ROWTEXTALIGN_CENTER						1
#define RTF_ROWTEXTALIGN_RIGHT						2

// Table cell text vertical align defs
#define RTF_CELLTEXTALIGN_TOP							0	
#define RTF_CELLTEXTALIGN_CENTER						1
#define RTF_CELLTEXTALIGN_BOTTOM						2

// Table cell text direction defs
#define RTF_CELLTEXTDIRECTION_LRTB					0
#define RTF_CELLTEXTDIRECTION_RLTB					1
#define RTF_CELLTEXTDIRECTION_LRBT					2
#define RTF_CELLTEXTDIRECTION_LRTBV					3
#define RTF_CELLTEXTDIRECTION_RLTBV					4

// Table cell shading type defs
#define RTF_CELLSHADINGTYPE_FILL						0
#define RTF_CELLSHADINGTYPE_HORIZ					1	
#define RTF_CELLSHADINGTYPE_VERT						2
#define RTF_CELLSHADINGTYPE_FDIAG					3
#define RTF_CELLSHADINGTYPE_BDIAG					4
#define RTF_CELLSHADINGTYPE_CROSS					5
#define RTF_CELLSHADINGTYPE_CROSSD					6
#define RTF_CELLSHADINGTYPE_DHORIZ					7
#define RTF_CELLSHADINGTYPE_DVERT					8
#define RTF_CELLSHADINGTYPE_DFDIAG					9
#define RTF_CELLSHADINGTYPE_DBDIAG					10
#define RTF_CELLSHADINGTYPE_DCROSS					11
#define RTF_CELLSHADINGTYPE_DCROSSD					12

// Document view kind defs
#define RTF_DOCUMENTVIEWKIND_NONE					0
#define RTF_DOCUMENTVIEWKIND_PAGE					1	
#define RTF_DOCUMENTVIEWKIND_OUTLINE				2
#define RTF_DOCUMENTVIEWKIND_MASTER					3
#define RTF_DOCUMENTVIEWKIND_NORMAL					4



#endif // _TR_RTF_H_