/*
 * i言語用 Pretty Print
 * Author: SilverRain <silver+iprettyprint@lacmhacarh.gr.jp>
 * Licence: とりあえず修正BSDライセンス互換。
 *          使われるなら後できちんと冒頭に書きます
 *
 *  ｉ言語の文章を、わかりやすく(?)ハイライトさせるJavaScript。
 *  とりあえず以下の文章で動作確認
 *  http://blog.tendice.jp/200803/article_5.html
 *
 * Usage:
 *   1) iprettyprint.js と iprettyprint.css を用意
 *   2) HTML 中で、以下のようによみこむ
 *      <link rel="stylesheet" type="text/css" href="iprettyprint.css" />
 *      <script type="text/javascript" src="iprettyprint.js" ></script>
 *      前者は head の中、公社は head の後に書くこと
 *   3) body の中で以下のようにして初期化させる
 *      <script type="text/javascript" language="javascript">
 *      window.onload = function() {
 *        iLanguagePrettyPrint();
 *      }
 *      </script>
 *
 *  4) ハイライトさせたい場所を、pre 要素で囲み、class を "iLanguage" にする。
 *     例) <pre class="iLanguage">i言語の文章</pre>
 *
 * History:
 *   Version 0.0: 2008/3/12 release.
 *
 */

  // ゲーム全体の制御文字。必ず行頭のみに出現するものとする。
  var GLOBAL_KEYWORDS = ["ＩＣＧ", "ＩＷＧ", "ＩＬＧ"];
  // ゲーム局所の制御文字。「：」と共に利用される
  var LOCAL_KEYWORDS = ["ｆ：", "ｔ：", "ｌ：", "ｒ：", "Ｑ：","Ａ："];
  // 既に定義済みのキーワード
  var DEFINED_KEYWORDS = [];

  // [TODO]
  // 用語は"＝"の左に揃える。ただし冒頭の？：は無視する
  // 二回目以降の用語はハイライトする
  // 実態参照をエスケープ?いらないかも
  
  // ゲーム全体の制御文字をハイライト
  // [TODO]後できちんと {} の中では無効にすること
  function highlightGlobalKeywords(text) {
      for(var i=0; i<GLOBAL_KEYWORDS.length; i++) {
	  var regptn = new RegExp("^([　\s]*" + GLOBAL_KEYWORDS[i] + ")");
	  text = text.replace(regptn, "<span class=\"gkwd\">$1</span>");
      }

      return text;
  }


  // ＝をハイライト
  function highlightEqual(text) {
      return text.replace(/＝/, "<span class=\"ykm\">＝</span>");
  }

  // 局所的な制御文字とキーワードをハイライト
  // [TODO]後できちんとグローバルな処理状態にそわせること
  function highlightLocalKeywords(text) {
      for(var i=0; i<LOCAL_KEYWORDS.length; i++) {
	  var regptn = new RegExp("^([　\s]*" + LOCAL_KEYWORDS[i] + ")");
	  if (text.match(regptn)) {
	      text = text.replace(regptn, "<span class=\"lkwd\">$1</span>");

	      // ＝を色付ける
	      text = highlightEqual(text);
	  }
      }

      return text;
  }

  // その場で定義されるキーワードをハイライト
  // [TODO]後できちんとキーワードが後で出た時にハイライトさせること
  function highlightNewKeywords(text, line) {
      // →などの文中避け
      if (text.match(/^[　\s]*→/)) return text;

      // 新規キーワード
      var regptn = new RegExp("(^|：</span>[　\s]*)([^＝]+)(<|[　\s]*＝)");
      var m = text.match(regptn);
      if (m != null) {
	  // [TODO] アンカーつける
	  text = text.replace(regptn, "$1<span class=\"kwd\">$2</span>$3");
	  DEFINED_KEYWORDS[m[2]] = line;

	  // ＝を色付ける
	  text = highlightEqual(text);
      }
      return text;
  }

  // 残りの約物をハイライト
  // [TODO]後で状態管理すること
  function highlightYakumono(text) {
      var regptn = new RegExp("(｛|｝)");
      text = text.replace(regptn, "<span class=\"ykm\">$1</span>");
      return text;
  }

  // i言語の入ったノードを処理
  function nodePrettyPrint(node, line) {
      // 改行で分割されたテキスト
      var texts = node.innerHTML.replace(/(\r|\r\n)/, "\n").split("\n");
      // 整形後の文字列
      var prettynode = [];

      for (var i=0; i<texts.length; i++) {
	  var mes = texts[i];

	  // ゲーム全体の制御文字を処理
	  mes = highlightGlobalKeywords(mes);
	  // ゲームの局所的な制御文字を処理
	  mes = highlightLocalKeywords(mes);
	  // 新規定義のキーワードをハイライト
	  mes = highlightNewKeywords(mes, i);
	  // 残りの約物をハイライト
	  mes = highlightYakumono(mes);

	  prettynode.push(mes);
      }

      // 定義済みのキーワードをハイライト
//      for (var i=0; i<prettynode.length; i++) {
//	  prettynode[i] = highlightDefinedKeywords(prettynode[i]);
//      }

      // 画面に戻す
      node.innerHTML = prettynode.join("\n");
  }

  // ノードを切り分けて、 pre 要素の iLanguage クラスのみを対象とする
  function iLanguagePrettyPrint() {
      var pretags = document.getElementsByTagName('pre');

      for (var i=0; i<pretags.length; i++) {
	  var node = pretags[i];
	  if(node.className="iLanguage") {
	      nodePrettyPrint(node, i);
	  }
      }

  }

