package com.wiki.standalone.moxkiriya.parser.inlineparser;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.wiki.standalone.moxkiriya.WikiEngine;

public abstract class WikiInlineParserBase implements WikiInlineParser {
	/** Wiki Engine */
	protected WikiEngine wikiEngine_;

	/**
	 * Constructor.
	 * @param wikiRepository
	 */
	public WikiInlineParserBase(WikiEngine wikiEngine) {
		wikiEngine_ = wikiEngine;
	}
	
	@Override
	public String parse(String line) {
		String  htmlString = line;
		
		if (line.isEmpty() != true
		 && line.equals("{{#TOC}}") != true) {
			WikiInlineParserCreator creator = new WikiInlineParserCreator(wikiEngine_);
			WikiInlineParser        parser;

			/*
			 * 外側のWikiトークンをHTMLに変換する。
			 */
			StringBuffer buf   = new StringBuffer("");
			String[]     split = devideLine(line);
			buf.append(split[0]);

			/* 
			 * 処理したトークンより内側のトークンをHTMLに変換する(もしあれば)。
			 */
			String textNode = deleteWikiToken(split[1]);
			parser          = creator.create(textNode);
			textNode        = parser.parse(textNode);

			StringBuffer mainBuf    = new StringBuffer();
			startElementProcess(mainBuf);
			textNodeProcess(mainBuf, textNode);
			endElementProcess(mainBuf);

			buf.append(mainBuf.toString());
			htmlString = buf.append(split[2]).toString();

			/*
			 * 処理したWikiトークンより外側のトークンを処理する。
			 */
			parser = creator.create(htmlString);

			StringBuffer buf2 = new StringBuffer("");

			buf2.append(parser.parse(htmlString));
			htmlString = buf2.toString();
		}

		return htmlString;
	}

	/**
	 * Wikiトークンを削除する。
	 * @param line
	 * @return　削除後の文字列
	 */
	abstract public String deleteWikiToken(String line);

	/**
	 * 要素開始を処理する。
	 * @param buf
	 */
	abstract public void startElementProcess(StringBuffer buf);

	/**
	 * テキストノードを処理する。
	 * @param buf
	 * @param textNode
	 */
	public void textNodeProcess(StringBuffer buf, String textNode) {
		buf.append(textNode);
	}
	
	/**
	 * 要素終了を処理する。
	 * @param buf
	 */
	abstract public void endElementProcess(StringBuffer buf);

	/**
	 * Wiki記法の開始パターンを取得する
	 * @return Wiki記法の開始パターン
	 */
	abstract public String getStartPattern();

	/**
	 * Wiki記法の終了パターンを取得する
	 * @return Wiki記法の終了パターン
	 */
	abstract public String getEndPattern();
	
	@Override
	public String[] devideLine(String line) {
		String   matchString  = null;
		String[] result       = null;

		Matcher  startMatcher = Pattern.compile(getStartPattern()).matcher(line);

		if(startMatcher.find() == true) {
			String   startSub   = line.substring(startMatcher.start());
			Matcher  endMatcher = Pattern.compile(getEndPattern()).matcher(startSub);

			if(endMatcher.find() == true) {
				matchString = startSub.substring(0, endMatcher.end());
			}
			else {
				matchString = startSub;
			}
		}

		if(matchString != null) {
			String[] split = line.split(Pattern.quote(matchString), 2);
			result = new String[] {split[0], matchString, split[1]};
		}

		return result;
	}	
}
