/**
 * Moxkiriya standalone Wiki.
 * Base class of Blocklevel element parser, processor.
 * 
 * @author Ryuhei Terada
 * See the '<a href="{@docRoot}/copyright.html">Copyright</a>'
 */
package com.wiki.standalone.moxkiriya.parser.blockparser;

import com.wiki.standalone.moxkiriya.WikiEngine;
import com.wiki.standalone.moxkiriya.parser.inlineparser.WikiInlineParser;
import com.wiki.standalone.moxkiriya.parser.inlineparser.WikiInlineParserCreator;

public abstract class WikiBlockParserBase implements WikiBlockParser {
	/** Wiki engine */
	WikiEngine wikiEngine_;
	
	/**	ブロック終了状態 */
	protected boolean isBlockEnd_ = false;

	/** 処理終了後の残り文字列 */
	protected String  remain_ = "";

	/** 処理した文字数 */
	protected int     count_  = 0;

	/** parse状態 */
	protected Status status_;

	/** インスタンス生成時のparse状態 */
	protected Status initialStatus_;

	/** ネスト元要素parser */
	protected WikiBlockParser motherParser_;

	/** ネスト要素parser */
	protected WikiBlockParser daughterParser_;
	
	/**
	 * Constructor.
	 * @param wikiRepository
	 */
	public WikiBlockParserBase(WikiEngine wikiEngine) {
		isBlockEnd_     = false;
		wikiEngine_ = wikiEngine;
	}
	
	@Override
	public String parse(String line, StringBuffer buf) throws Exception {
		buf.append(inlineParse(line));
		return "";
	}

	@Override
	public String daughterElementCloseHelper(String tagPart) {
		return tagPart;
	}

	@Override
	public boolean isBlockEnd() {
		return isBlockEnd_;
	}

	/**
	 * インライン要素を解析する。
	 * @param line
	 * @return インライン要素の解析結果
	 */
	public String inlineParse(String line) {
		return inlineParse(line, new WikiInlineParserCreator(wikiEngine_));
	}

	/**
	 * インライン要素を解析する。
	 * @param line
	 * @param creatorList
	 * @return インライン要素の解析結果
	 */
	public String inlineParse(String line, WikiInlineParserCreator creator) {
		StringBuffer buf        = new StringBuffer();
		String       inlineHtml = line;

		WikiInlineParserCreator inlineParserCreator = creator;
		WikiInlineParser        inlineParser        = inlineParserCreator.create(line);

		inlineHtml = inlineParser.parse(line);
		buf.append(inlineHtml);

		return buf.toString();
	}

	@Override
	public int getCount() {
		return count_;
	}

	/**
	 * ネストparser開始処理
	 * @param creator
	 * @param line
	 */
	protected void startDaughterParse(WikiBlockParserCreator creator, String line) {
		if(status_ == Status.INIT) {
			/*
			 * インスタンス生成後初parse&初matchの場合
			 */
			isBlockEnd_ = false;
			status_     = Status.OPEN;
		}
		else {
			status_        = Status.NESTING;
			daughterParser_ = creator.create(line);
		}
	}

	/**
	 * ネストparser開始処理
	 * @param creator
	 */
	protected void startDaughterParse(WikiBlockParserCreator.Creator creator) {
		if(status_ == Status.INIT) {
			/*
			 * インスタンス生成後初parse&初matchの場合
			 */
			isBlockEnd_ = false;
			status_     = Status.OPEN;
		}
		else {
			status_         = Status.NESTING;
			daughterParser_ = creator.create(wikiEngine_);
		}
	}

	/**
	 * lineの行頭からのtokenの数をカウントする。
	 * @param line
	 * @parma token
	 * @return 行頭からのtokenの数
	 */
	public int countToken(String line, char token) {
		int count = 0;
		for(count = 0; count < line.length(); count++) {
			if(token != line.charAt(count)) {
				break;
			}
		}
		
		return count;
	}
}
