package net.sourceforge.rtf.parser;

import java.io.IOException;

/**
 * Default RTF parser which is able to parse RTF Stream (Reader) character by character.
 * It launch events on special RTF keywords :  
 * <ul>
 * 	<li>
 * 		<b>startRow</b> when current RTF keyword parsed <b>\trowd</b> is found. This event
 *      is start of RTF row. 
 * 	</li>
 * 	<li>
 * 		<b>endRow</b> when current RTF keyword parsed <b>\row</b> is found. This event
 *      is end of RTF row. 
 * 	</li>
 *  <li>
 *      <b>inTable</b> when current RTF keyword parsed <b>\intbl</b> is found. This event
 *      is sometimes start of RTF row. 
 *  </li> 
 * 	<li>
 * 		<b>startField</b> when current RTF keyword parsed <b>\field</b> is found. This event
 *      is start of RTF field (like MERGEFIELD, HYPERLINK...). 
 * 	</li>
 * 	<li>
 * 		<b>startBookmark</b> when current RTF keyword parsed <b>\bkmkstart</b> is found. This event
 *      is start of RTF bookmark. 
 * 	</li>
 * 	<li>
 * 		<b>endBookmark</b> when current RTF keyword parsed <b>\bkmkend</b> is found. This event
 *      is end of RTF bookmark. 
 * 	</li>
 * 	<li>
 * 		<b>startPage</b> when current RTF keyword parsed <b>\page</b> is found. This event
 *      is page break. 
 * 	</li>
 * 	<li>
 * 		<b>startUserProperty</b> when current RTF keyword parsed <b>\propname</b> is found. This event
 *      is start of RTF user property. 
 * 	</li>
 * 	<li>
 * 		<b>endUserProperty</b> when current RTF keyword parsed <b>\staticval</b> is found. This event
 *      is end of RTF user property. 
 * 	</li>
 * 	<li>
 * 		<b>handleText</b> for other RTF content.
 * 	</li>
 * </ul> 
 * To use this abstract class, you must implement events 
 * <b>startGroup</b>, <b>endGroup</b>, <b>startRow</b>, <b>startRow</b>, <b>endRow</b>,
 * <b>startField</b>, <b>startBookmark</b>, <b>endBookmark</b>, <b>startPage</b>
 * and <b>handleText</b>.
 * @see AbstractCoreRTFParser
 * @version 1.0.0
 * @author <a href="mailto:angelo.zerr@gmail.com">Angelo ZERR</a>
 */
public abstract class AbstractDefaultRTFParser extends AbstractCoreRTFParser {

	private String starSlash = "";
	
	/**
	 * Manage events RTF keyword (Row, Field, Bookmark, Page and other RTF content). 
	 * @param content RTF keyword.
	 * @throws IOException
	 */
	protected void handleKeyword(String content) throws IOException {
		String keyword = content.trim();
		// ROW (start + end)
		if (keyword.equals("\\trowd")) {
			startRow(content);
			return;
		}
		if (keyword.equals("\\row")) {
			endRow(content);
			return;
		}
        if (keyword.equals("\\intbl")) {
             // sometimes row son't start with 
             // \trowd but with \intbl
             inTable(content);
             return;
        }        
		// FIELD (start)
		if (keyword.equals("\\field")) {
			startField(content);
			return;
		}
		// BOOKMARK (start + end)
		if (keyword.equals("\\*")) {
			starSlash = content;
			return;
		}
		if (keyword.startsWith("\\bkmkstart")) {
			startBookmark(starSlash + content);
			starSlash = "";
			return;
		}
		if (keyword.startsWith("\\bkmkend")) {
			endBookmark(starSlash + content);
			starSlash = "";
			return;
		}
		// PAGE (start)
		if (keyword.equals("\\page")) {
			startPage(content);
			return;
		}
		// USER PROPERTIES (start + end)
		if (keyword.startsWith("\\propname")) {
			startUserProperty(content);
			return;
		}
		if (keyword.startsWith("\\staticval")) {
			endUserProperty(content);
			return;
		}
        // ANNOTATION
        /*if (keyword.startsWith("\\annotation")) {
            startAnnotation(content);
            return;
        }*/
		
		// OTHER RTF CONTENT
		handleText(starSlash + content);
		starSlash = "";
	}
	
	// EVENTS TO IMPLEMENT
	
	//	 ROW
	/**
	 * Event start row. This event is launched when 
	 * RTF keyword <b>\trowd</b> is found.
	 * @param content RTF start row keyword <b>\trowd</b>.
	 * @throws IOException
	 */
	protected abstract void startRow(String content) throws IOException;
	
	/**
	 * Event end row. This event is launched when 
	 * RTF keyword <b>\row</b> is found.
	 * @param content RTF end row keyword <b>\row</b>.
	 * @throws IOException
	 */
	protected abstract void endRow(String content) throws IOException;
	
    /**
     * Event current paragraph is in table. This event helps to locate
     * start of rows, which does not begin with \trowd (it only appears at the end of row)
     * @param content RTF in table keyword <b>\intbl</b>.
     * @throws IOException
     */
    protected abstract void inTable(String content) throws IOException;
    
	// FIELD
	/**
	 * Event start field. This event is launched when 
	 * RTF keyword <b>\field</b> is found.
	 * @param content RTF end row keyword <b>\field</b>.
	 * @throws IOException
	 */
	protected abstract void startField(String content) throws IOException;
	
	// BOOKMARK
	/**
	 * Event start bookmark. This event is launched when 
	 * RTF keyword <b>\bkmkstart</b> is found.
	 * @param content RTF start bookmark keyword <b>\bkmkstart</b>.
	 * @throws IOException
	 */
	protected abstract void startBookmark(String content) throws IOException;
	
	/**
	 * Event end bookmark. This event is launched when 
	 * RTF keyword <b>\bkmkend</b> is found.
	 * @param content RTF end bookmark keyword <b>\bkmkend</b>.
	 * @throws IOException
	 */
	protected abstract void endBookmark(String content) throws IOException;
	
	// PAGE
	/**
	 * Event page break. This event is launched when 
	 * RTF keyword <b>\page</b> is found.
	 * @param content RTF start page keyword <b>\page</b>.
	 * @throws IOException
	 */
	protected abstract void startPage(String content) throws IOException;
	
	// HANDLE TEXT
	/**
	 * Event other RTF content. This event is launched 
	 * when other RTF content is found (not a RTF keyword)
	 * @param content other RTF content.
	 * @throws IOException
	 */
	protected abstract void handleText(String content) throws IOException;

	// USER PROPERTY
	/**
	 * Event start user property. This event is launched when 
	 * RTF keyword <b>\propname</b> is found.
	 * @param content RTF start user property keyword <b>\propname</b>.
	 * @throws IOException
	 */
	protected abstract void startUserProperty(String content) throws IOException;
	
	/**
	 * Event end user property. This event is launched when 
	 * RTF keyword <b>\staticval</b> is found.
	 * @param content RTF end user property keyword <b>\staticval</b>.
	 * @throws IOException
	 */
	protected abstract void endUserProperty(String content) throws IOException;
    
    /**
     * Event annotation. This event is launched when 
     * RTF keyword <b>\annotation</b> is found.
     * @param content RTF annotation keyword <b>\annotation</b>.
     * @throws IOException
     */
    protected abstract void startAnnotation(String content) throws IOException;

    
}
