1 /******************************************************************************
2  *
3  *  versekey.h -	code for class 'VerseKey'- a standard Biblical verse
4  *			key
5  *
6  * $Id: versekey.h 3541 2017-12-03 18:40:33Z scribe $
7  *
8  * Copyright 1997-2013 CrossWire Bible Society (http://www.crosswire.org)
9  *	CrossWire Bible Society
10  *	P. O. Box 2528
11  *	Tempe, AZ	85280-2528
12  *
13  * This program is free software; you can redistribute it and/or modify it
14  * under the terms of the GNU General Public License as published by the
15  * Free Software Foundation version 2.
16  *
17  * This program is distributed in the hope that it will be useful, but
18  * WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the GNU
20  * General Public License for more details.
21  *
22  */
23 
24 
25 #ifndef VERSEKEY_H
26 #define VERSEKEY_H
27 
28 #include <swkey.h>
29 #include <swmacs.h>
30 #include <listkey.h>
31 #include <versificationmgr.h>
32 
33 #include <defs.h>
34 
35 SWORD_NAMESPACE_START
36 
37 #define POS_MAXVERSE ((char)3)
38 #define POS_MAXCHAPTER ((char)4)
39 #define POS_MAXBOOK ((char)5)
40 
41 #define MAXVERSE SW_POSITION(POS_MAXVERSE)
42 #define MAXCHAPTER SW_POSITION(POS_MAXCHAPTER)
43 #define MAXBOOK SW_POSITION(POS_MAXBOOK)
44 
45 
46 
47 /**
48  * Class VerseKey
49  * The SWKey implementation used for verse based modules like Bibles or commentaries.
50  */
51 class SWDLLEXPORT VerseKey : public SWKey {
52 
53 	static SWClass classdef;
54 
55 	/** number of instantiated VerseKey objects or derivitives
56 	*/
57 	static int instance;
58 	ListKey internalListKey;
59 
60 	const VersificationMgr::System *refSys;
61 
62 	/** flag for auto normalization
63 	*/
64 	char autonorm;
65 
66 	/** flag for intros on/off
67 	*/
68 	char intros;
69 
70 	/** initializes this VerseKey()
71 	*/
72 	void init(const char *v11n = "KJV");
73 
74 	// bounds caching is mutable, thus const
75 	void initBounds() const;
76 
77 	// private with no bounds check
78 	void setFromOther(const VerseKey &vk);
79 
80 	void checkBounds();
81 
82 	// internal upper/lower bounds optimizations
83 	mutable long lowerBound, upperBound;	// if autonorms is on
84 	mutable VerseKey *tmpClone;
85 
86 	typedef struct { int test; int book; int chap; int verse; char suffix; } VerseComponents;
87 
88 	mutable VerseComponents lowerBoundComponents, upperBoundComponents;	// if autonorms is off, we can't optimize with index
89 
90 protected:
91 
92 	/** The Testament: 0 - Module Heading; 1 - Old; 2 - New
93 	*/
94 	signed char testament;
95 	signed char book;
96 	signed int chapter;
97 	signed int verse;
98 	signed char suffix;
99 
100 	/************************************************************************
101 	 * VerseKey::getBookFromAbbrev - Attempts to find a book no from a name or
102 	 *                           abbreviation
103 	 *
104 	 * ENT:	@param abbr - key for which to search;
105 	 * RET:	@return book number or < 0 = not valid
106 	 */
107 	virtual int getBookFromAbbrev(const char *abbr) const;
108 
109 	/** Refresh keytext based on testament|book|chapter|verse
110 	* default auto normalization to true
111 	* default display headings option is false
112 	*/
113 	void freshtext() const;
114 	/**	Parse a character array into testament|book|chapter|verse
115 	*
116 	*/
117 	virtual char parse(bool checkNormalize = true);
118 public:
119 #if 0
120 	static long otbks[];
121 	static long otcps[];
122 	static long ntbks[];
123 	static long ntcps[];
124 #endif
125 	int BMAX[2];
126 
127 	/**
128 	* VerseKey Constructor - initializes Instance of VerseKey
129 	*
130 	* @param ikey text key (will take various forms of 'BOOK CH:VS'.
131 	* See parse() for more detailed information)
132 	*/
133 	VerseKey(const char *ikey = 0);
134 
135 	/**
136 	* VerseKey Constructor - initializes instance of VerseKey
137 	*
138 	* @param ikey base key (will take various forms of 'BOOK CH:VS'.
139 	*	See parse() for more detailed information)
140 	*/
141 	VerseKey(const SWKey *ikey);
142 
143 	/** VerseKey Constructor - initializes instance of VerseKey
144 	* with boundariess - see also LowerBound()
145 	* and UpperBound()
146 	* @param min the lower boundary of the new	VerseKey
147 	* @param max the upper boundary of the new	VerseKey
148 	*/
149 	VerseKey(const char *min, const char *max, const char *v11n = "KJV");
150 
151 	/**	VerseKey Copy Constructor - will create a new VerseKey
152 	* based on an existing SWKey
153 	*
154 	* @param k the	VerseKey to copy from
155 	*/
156 	VerseKey(const SWKey &k);
157 
158 	/**	VerseKey Copy Constructor - will create a new VerseKey
159 	* based on an existing one
160 	*
161 	* @param k the	VerseKey to copy from
162 	*/
163 	VerseKey(const VerseKey &k);
164 
165 	/**	VerseKey Destructor
166 	* Cleans up an instance of VerseKey
167 	*/
168 	virtual ~VerseKey();
169 
170 	/** sets the lower boundary for this VerseKey
171 	*
172 	* @param lb the new lower boundary for this VerseKey
173 	*/
174 	void setLowerBound(const VerseKey &lb);
LowerBound(const VerseKey & lb)175 	SWDEPRECATED VerseKey &LowerBound(const VerseKey &lb) { setLowerBound(lb); return getLowerBound(); }
176 
177 	/** sets the upper boundary for this VerseKey
178 	* @param ub the new upper boundary for this VerseKey
179 	*/
180 	void setUpperBound(const VerseKey &ub);
UpperBound(const VerseKey & ub)181 	SWDEPRECATED VerseKey &UpperBound(const VerseKey &ub) { setUpperBound(ub); return getUpperBound(); }
182 
183 	/** gets the lower boundary of this VerseKey
184 	* @return the lower boundary of this VerseKey
185 	*/
186 	VerseKey &getLowerBound() const;
LowerBound()187 	SWDEPRECATED VerseKey &LowerBound() const { return getLowerBound(); }
188 
189 	/** gets the upper boundary of this VerseKey
190 	* @return the upper boundary of this VerseKey
191 	*/
192 	VerseKey &getUpperBound() const;
UpperBound()193 	SWDEPRECATED VerseKey &UpperBound() const { return getUpperBound(); }
194 
195 	/** clears the boundaries of this VerseKey
196 	*/
197 	void clearBounds();
ClearBounds()198 	SWDEPRECATED void ClearBounds() { clearBounds(); }
199 
200 	/** Creates a new SWKey based on the current VerseKey
201 	* see also the Copy Constructor
202 	*/
203 	virtual SWKey *clone() const;
204 
205 	/** refreshes keytext before returning if cast to
206 	* a (char *) is requested
207 	*/
208 	virtual const char *getText() const;
209 	virtual const char *getShortText() const;
setText(const char * ikey,bool checkNormalize)210 	virtual void setText(const char *ikey, bool checkNormalize) { SWKey::setText(ikey); parse(checkNormalize); }
setText(const char * ikey)211 	virtual void setText(const char *ikey) { SWKey::setText(ikey); parse(); }
212 	virtual void copyFrom(const SWKey &ikey);
213 
214 	/** Equates this VerseKey to another VerseKey
215 	*/
216 	virtual void copyFrom(const VerseKey &ikey);
217 
218 	/** Only repositions this VerseKey to another VerseKey
219 	*/
220 	virtual void positionFrom(const SWKey &ikey);
221 
222 	/** Positions this key
223 	*
224 	* @param newpos Position to set to.
225 	*/
226 	virtual void setPosition(SW_POSITION newpos);
227 
228 	/** Decrements key a number of verses
229 	*
230 	* @param steps Number of verses to jump backward
231 	*/
232 	virtual void decrement(int steps = 1);
233 
234 	/** Increments key a number of verses
235 	*
236 	* @param steps Number of verses to jump forward
237 	*/
238 	virtual void increment(int steps = 1);
isTraversable()239 	virtual bool isTraversable() const { return true; }
240 
241 	/** Get/Set position of this key by Book Name
242 	 */
243 	virtual const char *getBookName() const;
244 	virtual void setBookName(const char *bname);
245 
246 	virtual const char *getBookAbbrev() const;
247 	/** Gets testament
248 	*
249 	* @return value of testament
250 	*/
251 	virtual char getTestament() const;
252 	/**
253 	* @deprecated Use getTestament() instead.
254 	*/
Testament()255 	SWDEPRECATED char Testament() const { return getTestament(); }	// deprecated
getTestamentMax()256 	virtual int getTestamentMax() const { return 2; }
257 
258 	/** Gets book
259 	*
260 	* @return value of book
261 	*/
262 	virtual char getBook() const;
263 	/**
264 	* @deprecated Use getBook() instead.
265 	*/
Book()266 	SWDEPRECATED char Book() const { return getBook(); }	// deprecated
getBookMax()267 	virtual int getBookMax() const { return BMAX[testament-1]; }
268 
269 	/** Gets chapter
270 	*
271 	* @return value of chapter
272 	*/
273 	virtual int getChapter() const;
274 	/**
275 	* @deprecated Use getChapter() instead.
276 	*/
Chapter()277 	SWDEPRECATED int Chapter() const { return getChapter(); }	// deprecated
278 	virtual int getChapterMax() const;
279 
280 	/** Gets verse
281 	*
282 	* @return value of verse
283 	*/
284 	virtual int getVerse() const;
285 	/**
286 	* @deprecated Use getVerse() instead.
287 	*/
Verse()288 	SWDEPRECATED int Verse() const { return getVerse(); }		// deprecated
289 	virtual int getVerseMax() const;
290 
291 	/** Gets verse suffix
292 	*
293 	* @return value of verse suffix
294 	*/
295 	virtual char getSuffix() const;
296 
297 	/** Sets testament
298 	*
299 	* @param itestament value which to set testament
300 	*/
301 	virtual void setTestament(char itestament);
302 	/**
303 	* @deprecated Use setTestament() instead.
304 	*/
Testament(char itestament)305 	SWDEPRECATED char Testament(char itestament) { char retVal = getTestament(); setTestament(itestament); return retVal; } // deprecated
306 
307 	/** Sets book
308 	*
309 	* @param ibook value which to set book
310 	*/
311 	virtual void setBook(char ibook);
312 	/**
313 	* @deprecated Use setBook() instead.
314 	*/
Book(char ibook)315 	SWDEPRECATED char Book(char ibook) { char retVal = getBook(); setBook(ibook); return retVal; } // deprecated
316 
317 	/** Sets chapter
318 	*
319 	* @param ichapter value which to set chapter
320 	*/
321 	virtual void setChapter(int ichapter);
322 	/**
323 	* @deprecated Use setChapter() instead.
324 	*/
Chapter(int ichapter)325 	SWDEPRECATED int Chapter(int ichapter) { char retVal = getChapter(); setChapter(ichapter); return retVal; } // deprecated
326 
327 	/** Sets verse
328 	*
329 	* @param iverse value which to set verse
330 	*/
331 	virtual void setVerse(int iverse);
332 	/**
333 	* @deprecated Use setVerse() instead.
334 	*/
Verse(int iverse)335 	SWDEPRECATED int Verse(int iverse) { char retVal = getVerse(); setVerse(iverse); return retVal; } // deprecated;
336 
337 	/** Sets/gets verse suffix
338 	*
339 	* @param isuffix value which to set verse suffix
340 	*/
341 	virtual void setSuffix(char isuffix);
342 
343 	/** checks limits and normalizes if necessary (e.g.
344 	* Matthew 29:47 = Mark 2:2).	If last verse is
345 	* exceeded, key is set to last Book CH:VS
346 	*
347 	*/
348 	virtual void normalize(bool autocheck = false);
349 	SWDEPRECATED void Normalize(char autocheck = 0) { normalize(autocheck!=0); }
350 
351 	/** Sets flag that tells VerseKey to
352 	* automatically normalize itself when modified
353 	*
354 	* @param iautonorm value which to set autonorm
355 	*/
356 	virtual void setAutoNormalize(bool iautonorm);
357 	virtual bool isAutoNormalize() const;
358 
359 	/**
360 	* @deprecated Use setAutoNormalize() instead.
361 	*/
AutoNormalize(char iautonorm)362 	SWDEPRECATED char AutoNormalize(char iautonorm) { char retVal = isAutoNormalize()?1:0; setAutoNormalize(iautonorm!=0); return retVal; }	// deprecated
363 	/**
364 	* @deprecated Use isAutoNormalize() instead.
365 	*/
AutoNormalize()366 	SWDEPRECATED char AutoNormalize() const { return isAutoNormalize()?1:0; }	// deprecated
367 
368 
369 	/** Sets/gets flag that tells VerseKey to include
370 	* chapter/book/testament/module intros
371 	*
372 	* @deprecated Use setIntros() and isIntros() instead.
373 	* @param iheadings value which to set intros
374 	* [MAXPOS(char)] - only get
375 	* @return if unchanged -> value of intros,
376 	* if changed -> previous value of intros
377 	*/
378 	SWDEPRECATED char Headings(char iheadings = MAXPOS(char)) { char retVal = isIntros(); if (iheadings != MAXPOS(char)) setIntros(iheadings!=0); return retVal; }
379 
380 	/** The Intros property determine whether or not to include
381 	* chapter/book/testament/module intros
382 	*/
383 	virtual void setIntros(bool val);
384 	virtual bool isIntros() const;
385 
386 
387 	/** Gets index based upon current verse
388 	*
389 	* @return offset
390 	*/
391 	virtual long getIndex() const;
392 
393 
394 	/** Sets index based upon current verse
395 	*
396 	* @param iindex value to set index to
397 	*/
398 	virtual void setIndex(long iindex);
399 
400 
401 	/** Gets index into current testament based upon current verse
402 	*
403 	* @return offset
404 	*/
405 	virtual long getTestamentIndex() const;
406 
407 	/**
408 	* @deprecated Use getTestamentIndex()
409 	*/
TestamentIndex()410 	SWDEPRECATED long TestamentIndex() const { return getTestamentIndex(); }	// deprecated, use getTestamentIndex()
411 
412 	virtual const char *getOSISRef() const;
413 	virtual const char *getOSISBookName() const;
414 
415 	/** Tries to parse a string and convert it into an OSIS reference
416 	 * @param inRef reference string to try to parse
417 	 * @param defaultKey for details @see ParseVerseList(..., defaultKey, ...)
418 	 */
419 	static const char *convertToOSIS(const char *inRef, const SWKey *defaultKey);
420 
421 	/******************************************************************************
422 	 * VerseKey::parseVerseList - Attempts to parse a buffer into separate
423 	 *				verse entries returned in a ListKey
424 	 *
425 	 * ENT:	buf		- buffer to parse;
426 	 *	defaultKey	- if verse, chap, book, or testament is left off,
427 	 *				pull info from this key (ie. Gen 2:3; 4:5;
428 	 *				Gen would be used when parsing the 4:5 section)
429 	 *	expandRange	- whether or not to expand eg. John 1:10-12 or just
430 	 *				save John 1:10
431 	 *
432 	 * RET:	ListKey reference filled with verse entries contained in buf
433 	 *
434 	 * COMMENT: This code works but wreaks.  Rewrite to make more maintainable.
435 	 */
436 	virtual ListKey parseVerseList(const char *buf, const char *defaultKey = 0, bool expandRange = false, bool useChapterAsVerse = false);
437 	SWDEPRECATED ListKey ParseVerseList(const char *buf, const char *defaultKey = 0, bool expandRange = false, bool useChapterAsVerse = false) { return parseVerseList(buf, defaultKey, expandRange, useChapterAsVerse); }
438 	virtual const char *getRangeText() const;
439 	virtual const char *getOSISRefRangeText() const;
440 	/** Compares another	SWKey object
441 	*
442 	* @param ikey key to compare with this one
443 	* @return >0 if this	VerseKey is greater than compare	SWKey,
444 	* <0 if this	VerseKey is smaller than compare	SWKey,
445 	* 0 if the keys are the same
446 	*/
447 	virtual int compare(const SWKey &ikey);
448 
449 	/** Compares another	VerseKey object
450 	*
451 	* @param ikey key to compare with this one
452 	* @return >0 if this	VerseKey is greater than compare	VerseKey,
453 	* <0 if this	VerseKey is smaller than compare	VerseKey,
454 	* 0 if the keys are the same
455 	*/
456 	virtual int _compare(const VerseKey &ikey);
457 
458 	virtual void setVersificationSystem(const char *name);
459 	virtual const char *getVersificationSystem() const;
460 
461 	// DEBUG
462 	void validateCurrentLocale() const;
463 
464 
465 	// OPERATORS --------------------------------------------------------------------
466 
467 
468 	SWKEY_OPERATORS
469 
470 	virtual SWKey &operator =(const VerseKey &ikey) { positionFrom(ikey); return *this; }
471 };
472 
473 SWORD_NAMESPACE_END
474 
475 #endif //VERSEKEY_H
476