/* Rwv2 -- Microsoft Word Parser extension
   Copyright (C) 2003 Hannes Wyss, ywesee

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

   ywesee - intellectual capital connected
	 Winterthurerstrasse 52, CH-8006 Zürich, Switzerland
   hwyss@ywesee.com
*/

#ifndef RWV2_HANDLERS_H
#define RWV2_HANDLERS_H


#include "global.h"
#include "handlers.h"
#include "sharedptr.h"
#include "ustring.h"
#include "word97_generated.h"
#include "paragraphproperties.h"


#include "rwv2.h"
#include "rwv2_properties.h"

extern "C" {

#define RB_REPLACE(target, funcname, dflt) \
	if(rb_funcall(target, rb_intern("respond_to?"), 1, rb_str_new2(funcname)) == Qfalse) { \
		return (wvWare::U8) * dflt; \
	} \
	VALUE val = rb_funcall(target, rb_intern(funcname), 0); \
	long len; \
	char * cstr = rb_str2cstr(val, &len); \
	if(len != 1) { \
		rb_raise(rb_eRuntimeError, "InlineReplacementHandler#%s() must return single Character!", funcname); \
	} \
	return (wvWare::U8) * cstr;

class Rwv2InlineReplacementHandler : public wvWare::InlineReplacementHandler {
	private:
	VALUE m_rb_handler;
	public: 
	Rwv2InlineReplacementHandler(VALUE rb_handler) : m_rb_handler(rb_handler) {};
	wvWare::U8 tab() {
		RB_REPLACE(m_rb_handler, "tab", "\t");
	};
	wvWare::U8 hardLineBreak() {
		RB_REPLACE(m_rb_handler, "hard_line_break", "\v");
	};
	wvWare::U8 columnBreak() {
		RB_REPLACE(m_rb_handler, "column_break", "\016");
	};
	wvWare::U8 nonBreakingHyphen() {
		RB_REPLACE(m_rb_handler, "non_breaking_hyphen", "\036");
	};
	wvWare::U8 nonRequiredHyphen() {
		RB_REPLACE(m_rb_handler, "non_required_hyphen", "\037");
	};
	wvWare::U8 nonBreakingSpace() {
		RB_REPLACE(m_rb_handler, "non_breaking_space", "\240");
	};
};

#define RB_DELEGATE(funcname_wv, funcname_rb) \
	void funcname_wv() {\
		rb_funcall(m_rb_handler, rb_intern(funcname_rb), 0); \
	}

class Rwv2SubDocumentHandler : public wvWare::SubDocumentHandler {
	public:
	Rwv2SubDocumentHandler(VALUE rb_handler) : m_rb_handler(rb_handler) {};
	RB_DELEGATE(bodyStart, "body_start")
	RB_DELEGATE(bodyEnd, "body_end")
	RB_DELEGATE(footnoteStart, "footnote_start")
	RB_DELEGATE(footnoteEnd, "footnote_end")
	RB_DELEGATE(headersStart, "headers_start")
	RB_DELEGATE(headersEnd, "headers_end")
	void headerStart(wvWare::HeaderData::Type type) {
		VALUE rb_type = INT2FIX((int)type);
		rb_funcall(m_rb_handler, rb_intern("header_start"), 1, rb_type);
	}
	RB_DELEGATE(headerEnd, "header_end")
	private:
	VALUE m_rb_handler;
};

class Rwv2TableHandler : public wvWare::TableHandler {
	public:
	Rwv2TableHandler(VALUE rb_handler) : m_rb_handler(rb_handler) {};
	void tableRowStart(wvWare::SharedPtr<const wvWare::Word97::TAP> tap);
	RB_DELEGATE(tableRowEnd, "row_end")
	RB_DELEGATE(tableCellStart, "cell_start")
	RB_DELEGATE(tableCellEnd, "cell_end")
	private:
	VALUE m_rb_handler;
};

class Rwv2TextHandler : public wvWare::TextHandler {
	public: 
	Rwv2TextHandler(VALUE rb_handler) : m_rb_handler(rb_handler) {};
	void sectionStart(wvWare::SharedPtr<const wvWare::Word97::SEP> sep);
	RB_DELEGATE(sectionEnd, "section_end")
	RB_DELEGATE(pageBreak, "page_break")
	void paragraphStart(wvWare::SharedPtr<const wvWare::ParagraphProperties> pap);
	RB_DELEGATE(paragraphEnd, "paragraph_end")
	void runOfText(const wvWare::UString & text, 
			wvWare::SharedPtr<const wvWare::Word97::CHP> chp);
	private:
	VALUE m_rb_handler;
	VALUE wrap_chp(wvWare::SharedPtr<const wvWare::Word97::CHP> chp);
};

} // extern "C"
#endif
