/* 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
*/

#include "ruby.h"

#include "global.h"

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

extern "C" {

#define RB_BOOL_MEMBER(target, klass, type, member, reader) \
	VALUE rwv2_ ## target ## _ ## reader(VALUE self) { \
		klass * stub; \
		Data_Get_Struct(self, klass, stub); \
		if(stub->wv_ ## target->member == (wvWare::type)1) \
			return Qtrue; \
		else \
			return Qfalse; \
	}

#define RB_CONST_MEMBER(target, klass, type, member, reader) \
	VALUE rwv2_ ## target ## _ ## reader(VALUE self) { \
		klass * stub; \
		Data_Get_Struct(self, klass, stub); \
		wvWare::type val = stub->wv_ ## target->member; \
		return INT2FIX(val); \
	}

#define RB_CONST_FALSE_MEMBER(target, klass, type, member, reader) \
	VALUE rwv2_ ## target ## _ ## reader(VALUE self) { \
		klass * stub; \
		Data_Get_Struct(self, klass, stub); \
		wvWare::type val = stub->wv_ ## target->member; \
		if(val == (wvWare::type)0) \
			return Qfalse; \
		else \
			return INT2FIX(val); \
	}

RB_CONST_FALSE_MEMBER(sep, Rwv2Sep, U8, bkc, break_code)
RB_BOOL_MEMBER(sep, Rwv2Sep, U8, fTitlePage, title_page)
RB_CONST_MEMBER(sep, Rwv2Sep, U8, nfcPgn, page_number_format)
RB_BOOL_MEMBER(sep, Rwv2Sep, U8, fUnlocked, unlocked)
RB_BOOL_MEMBER(sep, Rwv2Sep, U8, fPgnRestart, page_number_restart)
RB_BOOL_MEMBER(sep, Rwv2Sep, U8, fEndNote, endnote)
RB_CONST_MEMBER(sep, Rwv2Sep, S8, lnc, line_numbering_code)
RB_CONST_FALSE_MEMBER(sep, Rwv2Sep, U16, lnc, line_numbering_modulus)

VALUE rwv2_sep_columns(VALUE self) {
	Rwv2Sep * stub;
	Data_Get_Struct(self, Rwv2Sep, stub);
	wvWare::S16 val = stub->wv_sep->ccolM1;
	return INT2FIX(val + 1);
}

void rwv2_sep_free(Rwv2Sep * stub) {
	delete stub->wv_sep;
	free(stub);
}
	
RB_CONST_MEMBER(pap, Rwv2Pap, U8, pap().jc, justify)
RB_BOOL_MEMBER(pap, Rwv2Pap, U8, pap().fKeep, keep)
RB_BOOL_MEMBER(pap, Rwv2Pap, U8, pap().fKeepFollow, keep_follow)
RB_BOOL_MEMBER(pap, Rwv2Pap, U8, pap().fPageBreakBefore, page_break_before)
RB_BOOL_MEMBER(pap, Rwv2Pap, U8, pap().fWidowControl, widow_control)
RB_CONST_MEMBER(pap, Rwv2Pap, S32, pap().dxaRight, indent_right)
RB_CONST_MEMBER(pap, Rwv2Pap, S32, pap().dxaLeft, indent_left)
RB_CONST_MEMBER(pap, Rwv2Pap, S32, pap().dxaLeft1, indent_first_line)

RB_BOOL_MEMBER(chp, Rwv2Chp, U8, fBold, bold)
RB_BOOL_MEMBER(chp, Rwv2Chp, U8, fItalic, italic)
RB_BOOL_MEMBER(chp, Rwv2Chp, U8, fRMark, rev_mark)
RB_BOOL_MEMBER(chp, Rwv2Chp, U8, fRMarkDel, rev_mark_del)
RB_BOOL_MEMBER(chp, Rwv2Chp, U8, fOutline, outline)
RB_BOOL_MEMBER(chp, Rwv2Chp, U8, fSmallCaps, small_caps)
RB_BOOL_MEMBER(chp, Rwv2Chp, U8, fCaps, caps)
RB_BOOL_MEMBER(chp, Rwv2Chp, U8, fSpec, special_char)
RB_BOOL_MEMBER(chp, Rwv2Chp, U8, fStrike, strikethrough)
RB_BOOL_MEMBER(chp, Rwv2Chp, U8, fShadow, shadow)
RB_BOOL_MEMBER(chp, Rwv2Chp, U8, fLowerCase, lowercase)
RB_BOOL_MEMBER(chp, Rwv2Chp, U8, fEmboss, emboss)
RB_BOOL_MEMBER(chp, Rwv2Chp, U8, fImprint, imprint)
RB_BOOL_MEMBER(chp, Rwv2Chp, U8, fDStrike, double_strikethrough)
RB_CONST_FALSE_MEMBER(chp, Rwv2Chp, U8, iss, position)
RB_CONST_FALSE_MEMBER(chp, Rwv2Chp, U8, kul, underline)

void rwv2_chp_free(Rwv2Chp * stub) {
	delete stub->wv_chp;
	free(stub);
}

RB_CONST_MEMBER(tap, Rwv2Tap, S16, jc, justify)
RB_CONST_MEMBER(tap, Rwv2Tap, S32, dxaGapHalf, gap_half)
RB_CONST_MEMBER(tap, Rwv2Tap, S32, dyaRowHeight, row_height)
RB_BOOL_MEMBER(tap, Rwv2Tap, U8, fCantSplit, cant_split)
RB_BOOL_MEMBER(tap, Rwv2Tap, U8, fTableHeader, table_header)
RB_CONST_MEMBER(tap, Rwv2Tap, S32, itcMac, row_cells)
VALUE rwv2_tap_cell_boundaries(VALUE self) {
	Rwv2Tap * stub;
	Data_Get_Struct(self, Rwv2Tap, stub);
	std::vector<wvWare::S16> vect = stub->wv_tap->rgdxaCenter;
	VALUE array = rb_ary_new();
	for(long idx=0; idx <= stub->wv_tap->itcMac; idx++) {
		rb_ary_push(array, INT2FIX(vect[idx]));
	}
	return array;
}
VALUE rwv2_tap_cell_descriptors(VALUE self) {
	Rwv2Tap * stub;
	Data_Get_Struct(self, Rwv2Tap, stub);
	std::vector<wvWare::Word97::TC> vect = stub->wv_tap->rgtc;
	VALUE array = rb_ary_new();
	for(long idx=0; idx < stub->wv_tap->itcMac; idx++) {
		VALUE rb_tc;
		Rwv2Tc * stub;
		rb_tc = Data_Make_Struct(cRwv2Tc, Rwv2Tc, 0, rwv2_tc_free, stub);
		wvWare::Word97::TC * wv_tc = 
			(wvWare::Word97::TC *) malloc(vect[idx].sizeOf);
		*wv_tc = vect[idx];
		stub->wv_tc = wv_tc;
		rb_ary_push(array, rb_tc);
	}
	return array;
}

void rwv2_tap_free(Rwv2Tap * stub) {
	delete stub->wv_tap;
	free(stub);
}

RB_BOOL_MEMBER(tc, Rwv2Tc, U16, fFirstMerged, first_merged)
RB_BOOL_MEMBER(tc, Rwv2Tc, U16, fMerged, merged)
RB_BOOL_MEMBER(tc, Rwv2Tc, U16, fVertical, vertical)
RB_BOOL_MEMBER(tc, Rwv2Tc, U16, fBackward, backward)
RB_BOOL_MEMBER(tc, Rwv2Tc, U16, fRotateFont, rotate_font)
RB_BOOL_MEMBER(tc, Rwv2Tc, U16, fVertMerge, vertical_merged)
RB_BOOL_MEMBER(tc, Rwv2Tc, U16, fVertRestart, vertical_restart)
RB_CONST_MEMBER(tc, Rwv2Tc, U16, vertAlign, vertical_align)

void rwv2_tc_free(Rwv2Tc * stub) {
	free(stub->wv_tc);
	free(stub);
}

} // extern "C"

