function splited_text(txt) {
	var ret = [];
	var start = 0;
	for (var i=0; i<txt.length; i++) {
		var j = txt.charCodeAt(i);
		if (j == 10 || j == 13) {
			if (start != i)
				ret.push(txt.substr(start, i-start));
			start = i+1;
		}
	}
	return ret;
}
function from_plain_text(txt) {
	var ary = splited_text(txt);
	if (ary.length == 0)
		return "";
	return "<div>"+ary.join("<br/>")+"</div>";
}
function constructor_text(txt) {
	var tmp = splited_text(txt);
	var header = "<pre>"+tmp[0]+"</pre>";
	tmp.shift();
	return "<div>"+header+"<div>"+tmp.join("<br/>")+"</div></div>";
}

function get_sub_field(ary, offset) {
	var ret = [];
	for (var i=offset; i<ary.length; i++) {
		if (ary[i] == "---") {
			break;
		}
		ret.push(analysis_field_line(ary[i]));
	}
	return ret;
}

function analysis_field_line(txt) {
	var i1 = txt.indexOf(":");
	if (i1 < 0) {
		if (txt.substr(-1) == ",")
			return txt.substr(0, txt.length -1);
		return txt;
	}
	var i2 = txt.indexOf(";", i1);
	if (i2 < 0)
		return txt;
	var i3 = txt.indexOf("//", i2);
	return {
		name: txt.substr(0, i1),
		type: txt.substring(i1+(txt.substr(i1+1, 1) == " " ? 2 : 1), i2),
		desc: i3 >= 0 ? txt.substr(i3+2) : ""
	}
}

function get_field_info(txt) {
	var tmp = splited_text(txt);
	var ret = []
	for (var i=0; i<tmp.length; i++) {
		if (tmp[i] == "---")
			continue;
		var obj = analysis_field_line(tmp[i]);
		if (obj.type.indexOf("Trigger") == 0) {
			obj.sub_fields = get_sub_field(tmp, i+1);
			if (obj.sub_fields.length == 0) {
				ret.push(obj);
				continue;
			}
			i += obj.sub_fields.length + 1;
		}
		ret.push(obj);
	}
	return ret;
}

var white_list = [
	"number",
	"string",
	"Object",
	"any",
	"bool",
	"HTMLElement",
	"HTMLCanvasElement",
	"HTMLImageElement",
	"Function",
	"CanvasRenderingContext2D",
	"ImageData"
]
function auto_link(txt) {
	if (!txt)
		return txt;
	txt = txt.trim();
	if (txt.indexOf("{") != -1)
		return txt;
	for (var i=0; i<white_list.length; i++) {
		if (txt.indexOf(white_list[i]) === 0)
			return txt;
	}
	var ary_index = txt.indexOf("[");
	var targetClass = ary_index == -1 ? txt : txt.substr(0, ary_index);
	switch (targetClass) {
		case "CommonSize":
		case "CommonOffset":
		case "TriggerHandler":
		case "CharacterMovedEventArgs":
		case "CharacterMoveInfo":
		case "ActionEventArgs":
		case "ActionTickEventArgs":
		case "ArcPoint":
		case "BezierPoint":
		case "QuadraticPoint":
			return '<a href="interfaces.html">'+txt+'</a>';
		case "CharacterAngle":
		case "InputEventType":
		case "Keytype":
		case "ShapeStyle":
		case "ShapeType":
		case "RenderTransferMode":
			return '<a href="enums.html">'+txt+'</a>';
	}
	return '<a href="'+targetClass+'.html">'+txt+'</a>';
}

function event_text(txt) {
	if (txt == "---")
		return "";
	var ret = [];
	var fields = get_field_info(txt);
	for (var i=0; i<fields.length; i++) {
		if (fields[i].type != "Trigger")
			continue;

		var row = $("<div/>");
		row.append($("<h3/>").text(fields[i].name));
		if (fields[i].desc != "") {
			row.append($("<div/>").html(fields[i].desc));
		}
		var arg_index = 0;
		if (fields[i].sub_fields) {
			for (var j=0; j<fields[i].sub_fields.length; j++) {
				var s = fields[i].sub_fields[j];
				if (typeof s == "string") {
					row.append($("<p/>").html(s));
				} else {
					arg_index++;
					row.append(
						"<h4>パラメータ型: "+auto_link(s.type)+"</h4>"
					);
					if (s.desc != "") {
						row.append(
							$("<div class='indent'/>").html(s.desc)
						);
					}
				}
			}
		}
		ret.push(row.html());
	}
	return ret.join("");
}

function analysis_interface_line(txt) {
	var i1 = txt.indexOf("interface ");
	var i2 = txt.indexOf("{");
	var ret = {}
	ret.name = txt.substring(i1+10, i2);
	return ret;
}

function analysis_enum_line(txt) {
	var i1 = txt.indexOf("enum ");
	var i2 = txt.indexOf("{");
	var ret = {}
	ret.name = txt.substring(i1+5, i2);
	return ret;
}

function analysis_method_line(txt) {
	var i1 = txt.indexOf("(");
	var i2 = txt.indexOf(")", i1);
	var ret = {}
	var fields = txt.substring(i1+1, i2).split(/,/g);
	ret.name = txt.substr(0, i1);
	ret.pre = txt.substr(0, txt.length-1);
	ret.fields = [];
	for (var i=0; i<fields.length; i++) {
		var f = fields[i].trim();
		if (f == "")
			continue;
		var i3 = f.indexOf(":");
		if (i3 == -1) {
			ret.fields.push({
				name: f,
				type: "any"
			})
		} else {
			ret.fields.push({
				name: f.substr(0, i3),
				type: f.substr(i3+1)
			})
		}
	}
	return ret;
}

function interface_text(txt) {
	var tmp = splited_text(txt);
	var ret = []
	for (var i=0; i<tmp.length; i++) {
		var _interface = analysis_interface_line(tmp[i]);
		_interface.fields = get_sub_field(tmp, i+1);
		i += _interface.fields.length + 1;

		var row = $("<div/>");
		row.append($("<h3/>").text(_interface.name));
		for (var j=0; j<_interface.fields.length; j++) {
			if (typeof _interface.fields[j] == "string")
				continue;
			row.append(
				"<h4>"+_interface.fields[j].name+" : "+auto_link(_interface.fields[j].type)+"</h4>"
			);
			if (_interface.fields[j].desc != "") {
				row.append(
					$("<div class='indent'/>").html(_interface.fields[j].desc)
				);
			}
		}
		for (var k=0; k<_interface.fields.length; k++) {
			if (typeof _interface.fields[k] == "string") {
				row.append($("<p/>").html(_interface.fields[k]));
			}
		}
		ret.push(row.html())
	}
	return ret.join("");
}

function enum_text(txt) {
	var tmp = splited_text(txt);
	var ret = []
	for (var i=0; i<tmp.length; i++) {
		var _interface = analysis_enum_line(tmp[i]);
		_interface.fields = get_sub_field(tmp, i+1);
		i += _interface.fields.length + 1;

		var row = $("<div/>");
		row.append($("<h3/>").text(_interface.name));
		for (var j=0; j<_interface.fields.length; j++) {
			if (typeof _interface.fields[j] == "string")
				continue;
			row.append(
				"<h4>"+_interface.fields[j].name+"</h4>"
			);
			if (_interface.fields[j].desc != "") {
				row.append(
					$("<div class='indent'/>").html(_interface.fields[j].desc)
				);
			}
		}
		for (var k=0; k<_interface.fields.length; k++) {
			if (typeof _interface.fields[k] == "string") {
				row.append($("<p/>").html(_interface.fields[k]));
			}
		}
		ret.push(row.html())
	}
	return ret.join("");
}
function method_text(txt) {
	var tmp = splited_text(txt);
	var ret = []
	for (var i=0; i<tmp.length; i++) {
		var method = analysis_method_line(tmp[i]);
		var sub = get_sub_field(tmp, i+1);
		i += sub.length + 1;
		for (var j=0; j<method.fields.length; j++) {
			for (var k=0; k<sub.length; k++) {
				if (typeof sub[k] == "string")
					continue;
				if (method.fields[j].name == sub[k].name) {
					method.fields[j].desc = sub[k].desc;
					break;
				}
			}
		}

		var row = $("<div/>");
		row.append($("<h3/>").text(method.name));
		row.append(
			$("<pre/>").text(method.pre)
		);
		for (var j=0; j<method.fields.length; j++) {
			row.append(
				"<h4>"+method.fields[j].name+" : "+auto_link(method.fields[j].type)+"</h4>"
			);
			if (method.fields[j].desc != "") {
				row.append(
					$("<div class='indent'/>").html(method.fields[j].desc)
				);
			}
		}
		for (var k=0; k<sub.length; k++) {
			if (typeof sub[k] == "string") {
				row.append($("<p/>").html(sub[k]));
			}
		}
		ret.push(row.html())
	}
	return ret.join("");
}

function field_text(txt) {
	var ret = [];
	var fields = get_field_info(txt);
	for (var i=0; i<fields.length; i++) {
		if (fields[i].type == "Trigger")
			continue;

		var row = $("<div/>");
		row.append($("<h3/>").text(fields[i].name));
		row.append($("<div/>").html("型: "+auto_link(fields[i].type)));
		if (fields[i].desc != "") {
			row.append($("<div/>").html(fields[i].desc));
		}
		ret.push(row.html());
	}
	return ret.join("");
}
$(function() {
	$("#texts").remove();
	var text = ($("h1").text() ? $("h1").text() + " - " : "") + "jgame.js API Reference";
	$("title").text(text);
	if ($("h1").text() ) {
		var tmp = $("h1").text();
		$("h1").text("").append($("<a/>").text("jgame.js").attr("href", "index.html"))
		.append($("<span/>").text(" > " + tmp));
	} else {
		$("h1").text("jgame.js API Reference");
	}
	var menus = [
		{caption: "はじめに", href: "index.html"},
		"Action",
		"Area",
		"BufferedRenderer",
		"Character",
		"CharacterFactory",
		"E",
		"Easing",
		"FrameGame",
		"Game",
		"GameRenderer",
		"GameTimer",
		"InputEvent",
		"InputKeyboardEvent",
		"InputPointEvent",
		"JGUtil",
		"Label",
		"Layer",
		"Line",
		"LoadingScene",
		"ParallelAction",
		"Rectangle",
		"Renderer",
		"Resource",
		"Scene",
		"Shape",
		"Sprite",
		"Tile",
		"Timeline",
		"Trigger",
		"Tween",
		{caption: "Enum型", href: "enums.html"},
		{caption: "TypeScript向けの型", href: "interfaces.html"},
		{caption: "単独関数群", href: "functions.html"},
		{caption: "モジュールについて", href: "modules.html"},
		{caption: "その他", href: "others.html"},
	];

	var menu_text = [];
	var paths = location.href.split("/");
	var current_file = paths.pop();
	if (current_file.indexOf("#") >= 0) {
		current_file = current_file.substr(0, current_file.indexOf("#"));
	}
	if (current_file.indexOf("?") >= 0) {
		current_file = current_file.substr(0, current_file.indexOf("?"));
	}
	for (var i=0; i<menus.length; i++) {
		var caption;
		var href;
		if (typeof menus[i] == "string") {
			caption = menus[i];
			href = menus[i]+".html";
		} else {
			caption = menus[i].caption;
			href = menus[i].href;
		}
		if (current_file == href) {
			menu_text.push('<strong>'+caption+"</strong>");
		} else {
			menu_text.push('<a href="'+href+'">'+caption+"</a>");
		}
	}
	$("#menu").html(
		"<ul>"+
		"<li>"+menu_text.join("</li><li>")+"</li>"+
		"</ul>"
	);

	if (window.summary) {
		var t = from_plain_text(summary);
		if (t) {
			var c = $("<div/>");
			c.append($("<h2/>").text("概要"));
			c.append($("<div/>").append(t));
			$("#body").append(c);
		}
	}

	if (window.constructors) {
		var t = constructor_text(constructors);
		if (t) {
			var c = $("<div/>");
			c.append($("<h2/>").text("コンストラクタ"));
			c.append($("<div/>").append(t));
			$("#body").append(c);
		}
	}

	if (window.fields) {
		var t = event_text(fields);
		if (t) {
			var c = $("<div/>");
			c.append($("<h2/>").text("イベント"));
			c.append($("<div/>").append(t));
			$("#body").append(c);
		}
	}

	if (window.methods) {
		var t = method_text(methods);
		if (t) {
			var c = $("<div/>");
			c.append($("<h2/>").text("メソッド"));
			c.append($("<div/>").append(t));
			$("#body").append(c);
		}
	}

	if (window.fields) {
		var t = field_text(fields);
		if (t) {
			var c = $("<div/>");
			c.append($("<h2/>").text("フィールド"));
			c.append($("<div/>").append(t));
			$("#body").append(c);
		}
	}

	if (window.interfaces) {
		var c = $("<div/>");
		c.append($("<h2/>").text("インターフェース"));
		c.append($("<div/>").append(interface_text(interfaces)));
		$("#body").append(c);
	}
	if (window.enums) {
		var c = $("<div/>");
		c.append($("<h2/>").text("列挙型"));
		c.append($("<div/>").append(enum_text(enums)));
		$("#body").append(c);
	}

	if (window.notes && notes.length > 0) {
		var t = from_plain_text(notes);
		if (t) {
			var c = $("<div/>");
			c.append($("<h2/>").text("備考"));
			c.append($("<div/>").append(t));
			$("#body").append(c);
		}
	}

});