/*********************************************
* KAI Touch Project!
* 
* 縦書き変換実行
* @author Shunsuke Hirota
* @update 2009/03/31
*********************************************/
var verticalText = 
{
	_tr          : null,
	_source      : null,
	_linkArr     : [],	//href属性値のリスト
	_windowArr   : [],	//target属性値のリスト
	_startAnchor : [],
	_endAnchor   : [],
	_tdList      : [],
	_linkPointer : 0,
	_isA         : 0,	//0:リンクなし, 1:リンク中, 2:リンク終わり
	_index       : 0,
	_line        : 0,	//1行の文字数
	_fontSize    : 14,
	_tempStr     : " ",
	
	/**
	* 開始
	*/
	start : function($class, count, $fontSize)
	{
		var vert = this.getElementByClassName($class)[count].childNodes;
		var strings = "";
		var sectionList;
		
		this.initialize();
		this._source = $class;
		if($fontSize) this._fontSize = $fontSize;
		
		strings = this.getPureString(vert);
		sectionList = this.createSection(strings);
		strings = this.checkLinkPoint(this.escapeSection(strings));
		sectionList = this.checkLine(sectionList);
		
		this.createTable(count);
		
		for(var i = 0; i < sectionList.length; ++i)
			this.createVertical(sectionList[i]);
		
		this.appendTD();
		this.finalize();
	},
	
	/**
	* 初期化
	*/
	initialize : function()
	{
		this._tr = null;
		this._source = null;
		this._index = 0;
		this._linkArr = [];
		this._windowArr = [];
		this._startAnchor = [];
		this._endAnchor = [];
		this._tdList = [];
		this._linkPointer = 0;
		this._isA = 0;
		this._fontSize = 14;
		this._tempStr = " ";
	},
	
	/**
	* メモリ開放
	*/
	finalize : function()
	{
		this._tr = null;
		this._source = null;
		this._linkArr = null;
		this._windowArr = null;
		this._startAnchor = null;
		this._endAnchor = null;
		this._tdList = null;
	},
	
	/**
	* アンカーをプレーンテキストに変換
	*/
	getPureString : function(vert)
	{
		var result = "";
		for(var i = 0; i < vert.length; ++i)
		{
			if(vert.item(i).nodeName == "A")
			{
				this.createAnchorInfo(vert, i);
				result += "__a" + vert.item(i).childNodes[0].nodeValue + "a__";
			}
			
			if(vert.item(i).nodeName == "#text")
				result += vert.item(i).nodeValue;
		}
		return result;
	},
	
	/**
	* 各行を作成
	*/
	createSection : function(str)
	{
		var result = [];
		var arr = str.split(String.fromCharCode("8629"));
		for(var i = 0; i < arr.length; ++i)
		{
			if(arr[i] != '') result.push(arr[i]);
		}
		
		return result;
	},
	
	/**
	* 改行文字情報を削除
	*/
	escapeSection : function(str)
	{
		var reg = new RegExp(String.fromCharCode("8629"), "g");
		return str.replace(reg, "");
	},
	
	/**
	* リンク情報を作成
	*/
	createAnchorInfo : function(vert, index)
	{
		this._linkArr.push(vert.item(index).href);
		if(vert.item(index).target == "")
			this._windowArr.unshift("_self")
		else
			this._windowArr.push(vert.item(index).target);
	},
	
	/**
	* リンクポイントオブジェクトの作成
	*/
	checkLinkPoint : function(str)
	{
		this._tmpString = str;
		for(var i = 0; i < str.length; ++i)
		{
			if(this.isAnchor(i))
				this._startAnchor.push(i);
			if(this.isCloseA(i))
				this._endAnchor.push(i);
		}
		return this._tmpString;
	},
	
	/**
	* 文字数チェック
	* @param list セクションリスト
	*/
	checkLine : function(list)
	{
		if(this._line == 0) return list;
		
		var result = [];
		var stringLen;
		var $tempString;
		
		for(var i = 0; i < list.length; ++i)
		{
			stringLen = list[i].length;
			$tempString = list[i];
			
			if(list[i].search("__a") != -1)
			{
				stringLen = stringLen - 3;
				$tempString = $tempString.replace('__a', '');
			}
				
			if(list[i].search("a__") != -1)
			{
				stringLen = stringLen - 3;
				$tempString = $tempString.replace('a__', '');
			}
			
			if(stringLen > this._line)
				result = result.concat(this.carriageReturn($tempString, stringLen))
			else
				result.push($tempString);
		}
		return result;
	},
	
	carriageReturn : function($string, $len)
	{
		var result = [];
		var reast;
		if($len > this._line)
		{
			result.push($string.substr(0, this._line));
			reast = $string.substr(this._line);
			
			//再起
			result = result.concat(this.carriageReturn(reast, reast.length));
		}
		else
			result.push($string);
		
		return result;
	},
	
	/**
	* テーブル作成
	*/
	createTable : function(count)
	{
		var table = document.createElement("table");
		var tbody = document.createElement("tbody");
		var tr = document.createElement("tr");
		var _class = this.getElementByClassName(this._source)[count];
		
		table.id = "VTable_" + this._source + count;
		tr.id = "VTR_" + this._source;
		
		_class.innerHTML = "";
		_class.appendChild(table);
		document.getElementById(table.id).appendChild(tbody);
		document.getElementById(table.id).style.fontSize = this._fontSize + "px";
		this._tr = tbody.appendChild(tr);//document.getElementById(table.id)
	},
	
	/**
	* 縦書き化実行
	*/
	createVertical : function(str)
	{
		var td = document.createElement("td");
		var anc;
		var inner;
		var len = str.length
		this._tmpString = str;
		
		td.className = "VTD_" + this._source;
		td.style.fontFamily = '"ＭＳ ゴシック",Osaka,"ヒラギノ角ゴ Pro W3"';
		
		for(var i = 0; i < len; ++i)
		{
			if(this._tmpString.charAt(i) == "") break;
			this.checkAnchor();
			
			if(this._isA == 1)
			{
				anc = document.createElement("a");
				anc.href = this._linkArr[this._linkPointer];
				anc.target = this._windowArr[this._linkPointer];
				if(!this.isCloseA(i)) td.appendChild(anc);
			}
			if(this._isA == 2)
			{
				inner = '</a>';
				
				++this._linkPointer;
				td.innerHTML += inner;
				this._isA = 0;
			}
			
			inner = this.checkString(this._tmpString.charAt(i), i);
			if(inner)
			{
				if(this._isA == 1)
					anc.innerHTML += inner;
				else
					td.innerHTML += inner;
			}
			++this._index;
		}
		//最後にtempStrが残っていたら追加する
		if(this._tempStr != " ")
		{
			this._isA == 1 ? anc.innerHTML += this._tempStr : td.innerHTML += this._tempStr;
			this._tmpStr = ' ';
		}
		
		this._tdList.push(td);
	},
	
	/**
	* TDの追加
	*/
	appendTD : function()
	{
		var len = this._tdList.length;
		this._tdList.reverse();
		
		for(var i = 0; i < len; ++i)
			this._tr.appendChild(this._tdList[i]);
	},
	
	/**
	* アンカー開始の真偽
	*/
	isAnchor : function(index)
	{
		if(this._tmpString.charAt(index) != "_") return false;
		if(this._tmpString.charAt(index + 1) != "_") return false;
		if(this._tmpString.charAt(index + 2) != "a") return false;
		this._tmpString = this._tmpString.replace('__a', '');
		return true;
	},
	
	/**
	* アンカー終了の審議
	*/
	isCloseA : function(index)
	{
		if(this._tmpString.charAt(index) != "a") return false;
		if(this._tmpString.charAt(index + 1) != "_") return false;
		if(this._tmpString.charAt(index + 2) != "_") return false;
		this._tmpString = this._tmpString.replace('a__', '');
		return true;
	},
	
	checkAnchor : function()
	{
		var len = this._startAnchor.length;
		
		for(var i = 0; i < len; ++i)
		{
			if(this._index == this._startAnchor[i])
			{
				this._isA = 1;
				return;
			}
		}
		
		for(i = 0; i < len; ++i)
		{
			if(this._index == this._endAnchor[i])
			{
				this._isA = 2;
				return
			}
		}
	},
	
	/**
	* 任意の文字を変換
	*/
	checkString : function(str, i)
	{
		var img;
		var result = '';
		//console.log(str.charAt(0) + " / " + str.charCodeAt(0))
		switch(str.charCodeAt(0))
		{
			case 12289:
				result = this.checkTemp(i);
				return result + this.createTouten();
				break;
			case 12290:
				result = this.checkTemp(i);
				return result + this.createKuten();
				break;
			case 12540:
				result = this.checkTemp(i);
				return result + this.createOnbiki();
				break;
			case 12300:
				result = this.checkTemp(i);
				return result + this.createKakkoBef();
				break;
			case 12301:
				result = this.checkTemp(i);
				return result + this.createKakkoAft();
				break;
			case 12302:
				result = this.checkTemp(i);
				return result + this.createKagiKakkoBef();
				break;
			case 12303:
				result = this.checkTemp(i);
				return result + this.createKagiKakkoAft();
				break;
			case 8230:
				result = this.checkTemp(i);
				return result + this.createTen();
				break;
			case 91://[
				result = this.checkTemp(i);
				return result + this.createBraketBef();
				break;
			case 93://]
				result = this.checkTemp(i);
				return result + this.createBraketAft();
				break;
			case 12304://【sumiParen
				result = this.checkTemp(i);
				return result + this.createSumiParenBef();
				break;
			case 12305://】
				result = this.checkTemp(i);
				return result + this.createSumiParenAft();
				break;
			case 65339:
				result = this.checkTemp(i);
				return result + this.createBraketBef();
				break;
			case 65341:
				result = this.checkTemp(i);
				return result + this.createBraketAft();
				break;
			case 40://(
				result = this.checkTemp(i);
				return result + this.createParenBef();
				break;
			case 65288://(
				result = this.checkTemp(i);
				return result + this.createParenBef();
				break;
			case 41://)
				this._tempStr = " ";
				return this.createParenAft();
				break;
			case 65289://)
				result = this.checkTemp(i);
				return result + this.createParenAft();
				break;
			case 61:
				result = this.checkTemp(i);
				return result + this.createEqual();
				break;
			case 65309:
				result = this.checkTemp(i);
				return result + this.createEqual();
				break;
			case 58:
				result = this.checkTemp(i);
				return result + this.createCollon();
				break;
			case 65306:
				result = this.checkTemp(i);
				return result + this.createCollon();
				break;
			case 65374:
				result = this.checkTemp(i);
				return result + this.createTilde();
				break;
			case 33://!
				return this.caseEX(str, i);
				break;
			case 65281://！
				return this.caseEX(str, i);
				break;
			case 63://?
				return this.caseQues(str, i);
				break;
			case 65311://？
				return this.caseQues(str, i);
				break;
			default:
				if(this._tempStr != " ")
				{
					result = this.checkTemp(i);
					return result + str + "<br />";
				}
				return str + "<br />";
				break;
		}
	},
	
	//！時
	caseEX : function(str, i)
	{
		if(this._tempStr == "？")
		{
			this._tempStr = " ";
			return this.createExQues(i);
		}
		else if(this._tempStr == "！")
		{
			this._tempStr = " ";
			return this.createDoubleEx(i);
		}
		else
		{
			this._tempStr = "！";
		}
	},
	
	//？時
	caseQues : function(str, i)
	{
		if(this._tempStr == "！")
		{
			this._tempStr = " ";
			return this.createExQues(i);
		}
		else if(this._tempStr == "？")
		{
			this._tempStr = " ";
			return this.createDoubleQues(i);
		}
		else
		{
			this._tempStr = "？";
		}
	},
	
	/**
	* tempStrがあれば、今回の文字列の前に付け足して出力
	* 2009/03/31 行頭ならば足さない
	*/
	checkTemp : function($index)
	{
		if($index == 0)
		{
			this._tempStr = " ";
			return '';
		}
		if(this._tempStr != " ")
		{
			var result = this._tempStr + "<br />";
			this._tempStr = " ";
			return result;
		}
		else
			return '';
	},
	
	/**
	* 。句点作成
	*/
	createKuten : function()
	{
		return this.createItem('kuten');
		//return '<img src="common/image/kuten.gif" width="14" height="14" style="border-style:none" />';
	},
	
	/**
	* 、読点作成
	*/
	createTouten : function()
	{
		return this.createItem('touten');
		//return '<img src="common/image/touten.gif" width="14" height="14" />';
	},
	
	/**
	* ー音引き作成
	*/
	createOnbiki : function()
	{
		return this.createItem('onbiki');
		//return '<img src="common/image/onbiki.gif" width="14" height="14" />';
	},
	
	/**
	* 「括弧前
	*/
	createKakkoBef : function()
	{
		return this.createItem('kakko_bef');
	},
	
	/**
	* 」括弧前
	*/
	createKakkoAft : function()
	{
		return this.createItem('kakko_aft');
	},
	
	/**
	* 『鍵括弧前
	*/
	createKagiKakkoBef : function()
	{
		return this.createItem('kagi_kakko_bef');
	},
	
	/**
	* 』鍵括弧後ろ
	*/
	createKagiKakkoAft : function()
	{
		return this.createItem('kagi_kakko_aft');
	},
	
	/**
	* …点
	*/
	createTen : function()
	{
		return this.createItem('ten');
	},
	
	/**
	* [ブラケット前
	*/
	createBraketBef : function()
	{
		return this.createItem('bracket_bef');
	},
	
	/**
	* ]ブラケット後ろ
	*/
	createBraketAft : function()
	{
		return this.createItem('bracket_aft');
	},
	
	/**
	* 【墨付きパーレン前
	*/
	createSumiParenBef : function()
	{
		return this.createItem('sumi_paren_bef');
	},
	
	/**
	* 】墨付きパーレン後
	*/
	createSumiParenAft : function()
	{
		return this.createItem('sumi_paren_aft');
	},
	
	/**
	* (パーレン前
	*/
	createParenBef : function()
	{
		return this.createItem('paren_bef');
	},
	
	/**
	* (パーレン後ろ
	*/
	createParenAft : function()
	{
		return this.createItem('paren_aft');
	},
	
	/**
	* ～チルダ
	*/
	createTilde : function()
	{
		return this.createItem('tilde');
	},
	
	/**
	* =equal
	*/
	createEqual : function()
	{
		return this.createItem('equal');
	},
	
	/**
	* :コロン
	*/
	createCollon : function()
	{
		return this.createItem('collon');
	},
	
	/**
	* !!感嘆符1つ
	*/
	createEx : function()
	{
		
	},
	
	/**
	* !!疑問符1つ
	*/
	createQues : function()
	{
		
	},
	
	/**
	* !!感嘆符二つ
	*/
	createDoubleEx : function(i)
	{
		return this.createItem('double_ex');
	},
	
	/**
	* !!疑問符二つ
	*/
	createDoubleQues : function(i)
	{
		return this.createItem('double_ques');
	},
	
	/**
	* !? 感嘆符付き疑問符
	*/
	createExQues : function(i)
	{
		return this.createItem('ex_ques');
	},
	
	/**
	* 特殊文字用のタグを追加
	*/
	createItem : function($className)
	{
		return '<span class="' + $className + this._fontSize + '" style="width:' + this._fontSize + 'px; height:' + this._fontSize + 'px; font-size:1px; display:block;">&nbsp;</span>'
	},
	
	getElementByClassName : function(name)
	{
		var elements=[];
		var tdElements = document.getElementsByTagName('td');
		var pElements = document.getElementsByTagName('p');
		var divElements = document.getElementsByTagName('div');
		
		for(var i=0,len=divElements.length; i<len; ++i)
		{
			if(divElements[i].className == name)
				elements.push(divElements[i]);
		}
		
		for(i=0,len=pElements.length; i<len; ++i)
		{
			if(pElements[i].className == name)
				elements.push(pElements[i]);
		}
		
		for(i=0,len=tdElements.length; i<len; ++i)
		{
			if(tdElements[i].className == name)
				elements.push(tdElements[i]);
		}
		
		return elements;
	}
};

/**
* 縦書き処理を実行
* @param $class : 対象クラス
* @param line : 1行の最大文字数
* @param $fontSize : 文字のサイズ
*/
function startVertical($class, line, $fontSize)
{
	var len = verticalText.getElementByClassName($class).length;
	if(line) verticalText._line = line;
	for(var i=0; i < len; ++i)
		verticalText.start($class, i, $fontSize);
}