/*@cc_on _d=document;eval('var document=_d')@*/

var ua = navigator.userAgent.toLowerCase();
var isFF = ua.indexOf("gecko") != -1;
var isOpera = ua.indexOf("opera") != -1;
var isIE = ua.indexOf("msie") != -1;

var levelMax = 70;
var levelMin = 10;
var tierNum = 11;
var tierRequestPoint = 5;
var levelOfEveryPoint = 1;

var Points = (levelMax - levelMin) / levelOfEveryPoint + 1;
var PointsMax = Points;
var RequiredLevel = levelMin - levelOfEveryPoint;

var treeName = new Array();
var treeLength = [0, 0, 0];
var treeTalentPoint = [0, 0, 0];
var treeDeepTier = [0, 0, 0];
var talent = new Array();
var talentRank = new Array();
var talentImagePath = new Array();
var talentBeRequired = new Array();
var talentSpell = new Array();
var talentSpellCacheText = new Array();
var tierTalentPoint = [new Array(), new Array(), new Array()];

var pointTalent = new Array();
var lastShowTalentTooltip = 0; // for Opera
var talent_path = './';
var talent_swap = false;

function talent_init() {
	Points = (levelMax - levelMin) / levelOfEveryPoint + 1;
	PointsMax = Points;
	RequiredLevel = levelMin - levelOfEveryPoint;

	for (var z=0; z<3; z++)
		for (var x=0; x<tierNum; x++)
			tierTalentPoint[z][x] = 0;

	for (var x=0; x<talent.length; x++) {
		treeLength[talent[x][0]]++;
		pointTalent[x] = 0;
		talentBeRequired[x] = new Array();
	}

	for (var x=0; x<talent.length; x++)
		if (talent[x][5])
			talentBeRequired[ talent[x][5][0] ].push(x);

	refreshInformationBar();
}

function talent_create() {
	var talent_tree = new Array(
		document.getElementById('talent_tree1'),
		document.getElementById('talent_tree2'),
		document.getElementById('talent_tree3')
	);
	for (var z=0; z<3; z++) {
		var talent_text = document.getElementById('talent_tree' + (z+1) + '_text');
		talent_text.innerHTML = treeName[z] + ': ' + treeTalentPoint[z];

		for (var x=1; x<=tierNum; x++) {
			for (var y=1; y<=4; y++) {
				var cell = talent_newCell();
				cell.setAttribute('id', 'talent_' + z + '_' + x + '_' + y);

				talent_tree[z].appendChild(cell);
			}
		}
	}

	for (var x=0; x<talent.length; x++) {
		var cell = document.getElementById('talent_' + talent[x][0] +  '_' + talent[x][4] + '_' + talent[x][3]);
		cell.setAttribute('id', 'talent_' + x);
		if (talent[x][0]<2 && talent[x][4] <= tierNum - 3)
			talent_injectTooltip(x, 'talent_tooltip tooltip_general');
		else if (talent[x][0]<2)
			talent_injectTooltip(x, 'talent_tooltip tooltip_bottom');
		else if (talent[x][4] <= tierNum - 3)
			talent_injectTooltip(x, 'talent_tooltip tooltip_right');
		else
			talent_injectTooltip(x, 'talent_tooltip tooltip_right_bottom');
	}
	for (var x=0; x<talent.length; x++)
		if (talent[x][5])
			talent_injectArrow(talent[x][5][0], x);
	for (var x=0; x<talentImagePath.length; x++) {
		var cell = document.getElementById('talent_' + x);
		talent_injectImg(x);

		var img = cell.getElementsByTagName('img')[0];
		img.src = talent_path + talentImagePath[x][0];

		img = cell.getElementsByTagName('img')[1];
		img.src = talent_path + talentImagePath[x][1];
	}
}

function contextmenu(event) {
	event = event || window.event;
	var target = event.srcElement || event.target;
	var tagName = target.tagName.toLowerCase();
	var flag = tagName == 'input' || tagName == 'textarea' || tagName == 'a' || tagName == 'select';
	if (!flag && event.preventDefault) event.preventDefault();
	return false;
}

function talent_set() {
	var talent_container = document.getElementById('talent_container');
	if (talent_container.addEventListener) {
		talent_container.addEventListener('contextmenu', contextmenu, false);
	} else if (talent_container.attachEvent) {
		talent_container.attachEvent('oncontextmenu', contextmenu);
	} else {
		talent_container.oncontextmenu = contextmenu;
	}

	for (var x=0; x<talent.length; x++) {
		var obj = document.getElementById('talent_' + x);
		var textObj = obj.getElementsByTagName('div')[1];

		obj.setAttribute('style', 'visibility: visible;');
		obj.style.visibility = 'visible';
		textObj.innerHTML = pointTalent[x] + '/' + talent[x][2];
		if (talent[x][4] == 1 && !talent[x][5]) talent_available(obj);

		if (obj.addEventListener) {
			obj.addEventListener('click', talent_click, false);
			obj.addEventListener('contextmenu', talent_rightClick, false);
			obj.addEventListener('mouseover', talent_mouseover, false);
			obj.addEventListener('mouseout', talent_mouseout, false);
		} else if (obj.attachEvent) {
			obj.attachEvent('onclick', talent_click);
			obj.attachEvent('oncontextmenu', talent_rightClick);
			obj.attachEvent('onmouseover', talent_mouseover);
			obj.attachEvent('onmouseout', talent_mouseout);
		} else {
			obj.onclick = talent_click;
			obj.oncontextmenu = talent_rightClick;
			obj.onmouseover = talent_mouseover;
			obj.onmouseout = talent_mouseout;
		}
	}
}

function talent_newCell() {
	var cell = document.createElement('div');
	cell.setAttribute('class', 'talent_cell talent_disable');
	cell.setAttribute('className', 'talent_cell talent_disable');

	var box = document.createElement('div');
	box.setAttribute('class', 'talent_box');
	box.setAttribute('className', 'talent_box');
	cell.appendChild(box);

	var text = document.createElement('div');
	text.setAttribute('class', 'talent_text');
	text.setAttribute('className', 'talent_text');
	cell.appendChild(text);

	return cell;
}

function talent_injectImg(id) {
	var obj = document.getElementById('talent_' + id);

	var img = document.createElement('img');

	img.setAttribute('alt', '');
	img.setAttribute('class', 'talent_img img_ava');
	img.setAttribute('className', 'talent_img img_ava');
	obj.appendChild(img);

	var disable_img = document.createElement('img');
	disable_img.setAttribute('alt', '');
	disable_img.setAttribute('class', 'talent_img img_dis');
	disable_img.setAttribute('className', 'talent_img img_dis');
	obj.appendChild(disable_img);
}

function talent_injectTooltip(id, style) {
	var ieVersion = getIEVersion();
	var obj = ieVersion && ieVersion < 8 ? document.getElementById('talent_container') : document.getElementById('talent_' + id);
	var tooltip = document.createElement('div');
	
	tooltip.setAttribute('id', 'talentTooltip_' + id);
	tooltip.setAttribute('class', style);
	tooltip.setAttribute('className', style);
	if (ieVersion && ieVersion < 8) {
		var wrapObj = document.createElement('div');
		wrapObj.style.position = 'absolute';
		wrapObj.style.zIndex = 6;
		wrapObj.style.left = talent_getElementPosX('talent_' + id) + (talent[id][0]<2 ? 0 : 65) + 'px';
		wrapObj.style.top = talent_getElementPosY('talent_' + id) + (talent[id][4] <= tierNum - 3 ? 0 : 65) + 'px';
		wrapObj.appendChild(tooltip);
		obj.appendChild(wrapObj);
	} else
		obj.appendChild(tooltip);
	refreshTalentTooltip(id);
}

function talent_injectArrow(fromId, destId) {
	var ieVersion = getIEVersion();
	var fromObj = ieVersion && ieVersion < 8 ? document.getElementById('talent_container') : document.getElementById('talent_' + fromId);
	var box = document.createElement('div');
	var obj = document.createElement('div');

	box.setAttribute('id', 'talent_arrow_' + fromId + '_' + destId);
	box.setAttribute('class', 'talent_arrow arrow_grey');
	box.setAttribute('className', 'talent_arrow arrow_grey');
	if (ieVersion && ieVersion < 8) {
		box.style.left = talent_getElementPosX('talent_' + fromId);
		box.style.top = talent_getElementPosY('talent_' + fromId);
	}

	if (talent[fromId][3] == talent[destId][3]) {
		obj.setAttribute('class', 'arrow_down_' + (talent[destId][4] - talent[fromId][4]));
		obj.setAttribute('className', 'arrow_down_' + (talent[destId][4] - talent[fromId][4]));
		box.appendChild(obj);
		fromObj.appendChild(box);
	} else if(talent[fromId][4] == talent[destId][4]) {
		var className = 'arrow_' + (talent[fromId][3] > talent[destId][3]?'left':'right') + '_' + Math.abs(talent[destId][3] - talent[fromId][3]);
		obj.setAttribute('class', className);
		obj.setAttribute('className', className);
		box.appendChild(obj);
		fromObj.appendChild(box);
	} else {
		var className = 'arrow_down_' + (talent[fromId][3] > talent[destId][3]?'left':'right') + '_' + (talent[destId][4] - talent[fromId][4]);
		obj.setAttribute('class', className);
		obj.setAttribute('className', className);
		box.appendChild(obj);
		fromObj.appendChild(box);
	}
}

function getTalentID(x) {
	for(var y=0; talent[y]; y++)
		if(talent[y][1]==x) return y;
	return x;
}

function talent_available(obj) {
	obj.setAttribute('class', 'talent_cell talent_available');
	obj.setAttribute('className', 'talent_cell talent_available');
}

function talent_disable(obj) {
	obj.setAttribute('class', 'talent_cell talent_disable');
	obj.setAttribute('className', 'talent_cell talent_disable');
}

function talent_full(obj) {
	obj.setAttribute('class', 'talent_cell talent_full');
	obj.setAttribute('className', 'talent_cell talent_full');
}

function talent_click(event) {
	event = event || window.event;
	var target = event.srcElement || event.target;
	if (!target.id) target = target.parentNode;
	var id = get_objTalentId(target);
	if (id < 0) return;

	if (event.shiftKey)// || event.button==2)
		sub_point(id);
	else// if (event.button==0 || isIE && event.button==1)
		add_point(id);
}

function talent_rightClick(event) {
	event = event || window.event;
	var target = event.srcElement || event.target;
	if (!target.id) target = target.parentNode;
	var id = get_objTalentId(target);
	if (id < 0) return;

	sub_point(id);
}

function talent_mouseover(event) {
	event = event || window.event;
	var target = event.srcElement || event.target;
	if (!target.id) target = target.parentNode;
	var id = get_objTalentId(target);
	if(id < 0) return;

	talent_showTooltip(id);
}

function talent_mouseout(event) {
	event = event || window.event;
	var target = event.srcElement || event.target;
	if (!target.id) target = target.parentNode;
	var id = get_objTalentId(target);
	if(id < 0) return;

	talent_hideTooltip(id);
}

function get_objTalentId(obj) {
	var result = parseInt(obj.id.substr(7));
	if (isNaN(result))
		return -1;
	return result;
}

function add_point(id) {
	var obj = document.getElementById('talent_' + id);
	var textObj = obj.getElementsByTagName('div')[1];

	if (pointTalent[id] >= talent[id][2] ||
		(talent[id][4] - 1) * tierRequestPoint > treeTalentPoint[talent[id][0]] ||
		Points<=0 ||
		talent[id][5] && pointTalent[ talent[id][5][0] ] < talent[id][5][1]) return;

	Points--;
	RequiredLevel += levelOfEveryPoint;
	pointTalent[id]++;
	treeTalentPoint[ talent[id][0] ]++;
	treeDeepTier[ talent[id][0] ] = Math.max(treeDeepTier[ talent[id][0] ], talent[id][4]);
	for (var x=talent[id][4]-1; x<tierNum; x++)
		tierTalentPoint[ talent[id][0] ][x]++;

	textObj.innerHTML = pointTalent[id] + '/' + talent[id][2];
	refreshTalentButton(id);
	var talent_text = document.getElementById('talent_tree' + (talent[id][0]+1) + '_text');
	talent_text.innerHTML = treeName[talent[id][0]] + ': ' + treeTalentPoint[talent[id][0]];

	if (Points <= 0) {
		for (var x=0; x<talent.length; x++) {
			if (pointTalent[x] <= 0 && talent[x][4] <= Math.floor(treeTalentPoint[ talent[x][0] ]/tierRequestPoint) + 1) {
				obj = document.getElementById('talent_' + x);
				talent_disable(obj);
				refreshTalentArrow(x);
			}
		}
	}

	refreshInformationBar();
}

function sub_point(id) {
	if (pointTalent[id] <= 0) return;

	var obj = document.getElementById('talent_' + id);
	var textObj = obj.getElementsByTagName('div')[1];
	var tempTierTalentPoint = [tierTalentPoint[0].slice(),
		tierTalentPoint[1].slice(),
		tierTalentPoint[2].slice()];

	for (var x=0; x<talentBeRequired[id].length; x++)
		if (pointTalent[ talentBeRequired[id] ] > 0) return;
	for(var x=tierNum-1; x>=talent[id][4]-1; x--) {
		tempTierTalentPoint[ talent[id][0] ][x]--;
		if (x < treeDeepTier[ talent[id][0] ]-1 &&
			tempTierTalentPoint[ talent[id][0] ][x] < (x+1)*tierRequestPoint) return;
	}

	Points++;
	RequiredLevel -= levelOfEveryPoint;
	pointTalent[id]--;
	treeTalentPoint[ talent[id][0] ]--;
	tierTalentPoint = tempTierTalentPoint;
	if (talent[id][4] == treeDeepTier[ talent[id][0] ]) {
		var subDeepTier = true;
		for (var x=0; x<talent.length; x++) {
			if (talent[x][4] == talent[id][4] && talent[x][0] == talent[id][0] && pointTalent[x] > 0) {
				subDeepTier = false;
				break;
			}
		}
		if (subDeepTier) treeDeepTier[ talent[id][0] ]--;
	}

	textObj.innerHTML = pointTalent[id] + '/' + talent[id][2];
	refreshTalentButton(id);
	var talent_text = document.getElementById('talent_tree' + (talent[id][0]+1) + '_text');
	talent_text.innerHTML = treeName[talent[id][0]] + ': ' + treeTalentPoint[talent[id][0]];

	if (Points == 1) {
		for (var x=0; x<talent.length; x++) {
			if (pointTalent[x] <= 0 && talent[x][4] <= Math.floor(treeTalentPoint[ talent[x][0] ]/tierRequestPoint) + 1 &&
				(!talent[x][5] || pointTalent[ talent[x][5][0] ] >= talent[x][5][1])) {
				obj = document.getElementById('talent_' + x);
				talent_available(obj);
				refreshTalentArrow(x);
			}
		}
	}

	refreshInformationBar();
}

function refreshTalentButton(id) {
	var obj = document.getElementById('talent_' + id);

	if (pointTalent[id] >= talent[id][2]) talent_full(obj);
	else if (pointTalent[id] == talent[id][2] - 1) talent_available(obj);

	refreshTalentTooltip(id);
	refreshTalentArrow(id);

	if (treeTalentPoint[talent[id][0]] % tierRequestPoint == 0) {
		for (var x=0; x<talent.length; x++) {
			var flag1 = talent[x][0] == talent[id][0] &&
				(talent[x][4] - 1) * tierRequestPoint == treeTalentPoint[talent[id][0]];
			var flag2 = !talent[x][5] || pointTalent[ talent[x][5][0] ] >= talent[x][5][1];
			if (flag1 && flag2) {
				obj = document.getElementById('talent_' + x);
				talent_available(obj);
			}
			if (flag1 || flag2) {
				refreshTalentTooltip(x);
				refreshTalentArrow(x);
			}
		}
	} else if (treeTalentPoint[talent[id][0]] % tierRequestPoint == tierRequestPoint-1) {
		for (var x=0; x<talent.length; x++) {
			if (talent[x][0] == talent[id][0] &&
				(talent[x][4] - 1) * tierRequestPoint == treeTalentPoint[talent[id][0]] + 1) {
				obj = document.getElementById('talent_' + x);
				talent_disable(obj);
				refreshTalentTooltip(x);
				refreshTalentArrow(x);
			}
		}
	}

	for (var x=0; x<talentBeRequired[id].length; x++) {
		if ((talent[ talentBeRequired[id][x] ][4] - 1) * tierRequestPoint <= treeTalentPoint[talent[id][0]]) {
			if (pointTalent[ id ] >= talent[ talentBeRequired[id][x] ][5][1]) {
				obj = document.getElementById('talent_' + talentBeRequired[id][x]);
				talent_available(obj);
				refreshTalentTooltip(talentBeRequired[id][x]);
				refreshTalentArrow(talentBeRequired[id][x]);
			} else if (pointTalent[ id ] < talent[ talentBeRequired[id][x] ][5][1]) {
				obj = document.getElementById('talent_' + talentBeRequired[id][x]);
				talent_disable(obj);
				refreshTalentTooltip(talentBeRequired[id][x]);
				refreshTalentArrow(talentBeRequired[id][x]);
			}
		} else if (pointTalent[id] >= talent[id][2] - 1)
			refreshTalentTooltip(talentBeRequired[id][x]);
	}
}

function refreshTalentTooltip(id) {
	var obj = document.getElementById('talentTooltip_' + id);
	clearHtml(obj);
	insertHtml('BeforeEnd', obj, get_tooltip(id));
}

function get_tooltip(id) {
	var html = ['<b>' + talent[id][1] + '</b><br>' +
		'等級: ' + pointTalent[id] + '/' + talent[id][2] + '<br>'];
	if (talent[id][5]) {
		html.push('<span style="color:#' + (pointTalent[ talent[id][5][0] ] < talent[id][5][1] ? 'f00':'0f0') + ';">需要 ' + talent[id][5][1] + ' 點 ' + talent[ talent[id][5][0] ][1] + '</span><br>');
	}
	if (talent[id][4]>1) {
		html.push('<span style="color:#' + (treeTalentPoint[talent[id][0]] < (talent[id][4]-1)*tierRequestPoint ? 'f00':'0f0') + ';">需要 ' + (talent[id][4]-1)*tierRequestPoint + ' 點 ' + treeName[ talent[id][0] ] + ' 天賦</span><br>');
	}

	html.push('<br>');
	if (talentSpellCacheText[id]) {
		html.push(talentSpellCacheText[id]);
	} else if (talentSpell[id]) {
		var cache = new Array();
		if (talentSpell[id][1] > 0) {
			cache.push('<span style="float:left;">' + talentSpell[id][1]);
			switch(talentSpell[id][0]) {
				case 0:
					cache.push('法力'); break;
				case 1:
					cache.push('% 基本法力'); break;
				case 4:
					cache.push('怒氣'); break;
				case 5:
					cache.push('能量'); break;
				case 6:
					cache.push('生命'); break;
				case 7:
					cache.push('符文能量'); break;
				case 8:
					cache.push('集中值'); break;
			}
			cache.push('</span>');
		}
		if (talentSpell[id][2][0]>0 || talentSpell[id][2][1]>0 || talentSpell[id][2][2]>0) {
			cache.push('<span style="float:left;clear:left;">');
			if (talentSpell[id][2][0]>0) cache.push(talentSpell[id][2][0] + '鮮血 ');
			if (talentSpell[id][2][1]>0) cache.push(talentSpell[id][2][1] + '不潔 ');
			if (talentSpell[id][2][2]>0) cache.push(talentSpell[id][2][2] + '冰霜 ');
			cache.push('</span>');
		}
		if (talentSpell[id][6][1]) {
			if (talentSpell[id][1] > 0 || talentSpell[id][2][0]>0 || talentSpell[id][2][1]>0 || talentSpell[id][2][2]>0)
				cache.push('<div style="float:right;clear:right;">');
			else
				cache.push('<div style="clear:both;">');
			if (isArray(talentSpell[id][6][1])) {
				cache.push('敵人: ' + talent_tooltipRangeText(talentSpell[id][6][0]) + '<br>');
				cache.push('同盟: ' + talent_tooltipRangeText(talentSpell[id][6][1]));
				cache.push('</div>');
			} else if(talentSpell[id][6][1] > 0) {
				cache.push(talent_tooltipRangeText(talentSpell[id][6]));
				cache.push('</div>');
			}
		}
		cache.push('<span style="float:left;clear:left;">');
		switch (talentSpell[id][3]) {
			case 0:
				cache.push(talentSpell[id][4] == 0 ? '瞬發' : format_time(talentSpell[id][4]) + '施法時間');
				break;
			case 1: cache.push('引導法術'); break;
			case 2: cache.push('下一次近戰'); break;
		}
		cache.push('</span>');
		if (talentSpell[id][5] > 0)
			cache.push('<span style="float:right;clear:right;">' + format_time(talentSpell[id][5]) + '冷卻時間</span>');
		if (talentSpell[id][9] != '')
			cache.push('<span style="clear:left;float:left;">工具: ' + talentSpell[id][9] + '</span>');
		if (talentSpell[id][8] != '')
			cache.push('<span style="clear:left;float:left;">施法材料: ' + talentSpell[id][8] + '</span>');
		if (talentSpell[id][7] != '')
			cache.push('<span style="clear:left;float:left;">需要' + talentSpell[id][7] + '</span>');
		cache.push('<div style="clear:both;"></div>');
		talentSpellCacheText[id] = cache.join('');
		html.push(talentSpellCacheText[id]);
	}
	if (pointTalent[id] > 0)
		html.push(talentRank[id][ pointTalent[id]-1 ] + '<br>');
	if (pointTalent[id] > 0 && pointTalent[id] < talent[id][2])
		html.push('<br>下一等級:<br>');
	if (pointTalent[id] < talent[id][2])
		html.push(talentRank[id][ pointTalent[id] ] + '<br>');
	html.push('<br><span style="float:left;color:#0f0;">按左鍵學習</span>');
	if(isOpera)
		html.push('<span style="float:right;color:#f00;">按Shift+左鍵忘記</span>');
	else
		html.push('<span style="float:right;color:#f00;">按右鍵忘記</span>');
	return html.join('');
}

function talent_tooltipRangeText(data) {
	var result = new Array();
	if (typeof(data[1]) == 'boolean') {
		result.push('近戰範圍');
	} else if (data[1] > 0) {
		if (data[0] > 0) result.push(data[0] + ' - ');
		result.push(data[1] + '碼距離');
	}
	return result.join('');
}

function format_time(i) {
	var minute = i / 60;
	var seconds = i % 60;
	var result = new Array();

	if (minute >= 1) result.push(minute + '分');
	else result.push(seconds + '秒');
	return result.join('');
}

function refreshTalentArrow(id) {
	if (!talent[id][5]) return;
	var obj = document.getElementById('talent_arrow_' + talent[id][5][0] + '_' + id);
	var flag = pointTalent[ talent[id][5][0] ] >= talent[id][5][1] &&
		(talent[id][4] - 1) * tierRequestPoint <= treeTalentPoint[talent[id][0]];

	if (flag && pointTalent[id] > 0) {
		obj.setAttribute('class', 'talent_arrow arrow_yellow');
		obj.setAttribute('className', 'talent_arrow arrow_yellow');
	} else if (!flag || Points <= 0) {
		obj.setAttribute('class', 'talent_arrow arrow_grey');
		obj.setAttribute('className', 'talent_arrow arrow_grey');
	} else {
		obj.setAttribute('class', 'talent_arrow arrow_green');
		obj.setAttribute('className', 'talent_arrow arrow_green');
	}
}

function refreshInformationBar() {
	var unused_point = document.getElementById('unused_point');
	var used_point = document.getElementById('used_point');
	var character_level = document.getElementById('character_level');

	RequiredLevel = levelMin + (PointsMax - Points - 1) * levelOfEveryPoint;

	unused_point.innerHTML = Points;
	used_point.innerHTML = PointsMax - Points;
	character_level.innerHTML = RequiredLevel;
}

function talent_showTooltip(id) {
	var obj = document.getElementById('talentTooltip_' + id);
	obj.setAttribute('style', 'visibility: visible;');
	obj.style.visibility = 'visible';

	if (isOpera && lastShowTalentTooltip != id) {
		talent_hideTooltip(lastShowTalentTooltip);
		lastShowTalentTooltip = id;
	}
}

function talent_hideTooltip(id) {
	var obj = document.getElementById('talentTooltip_' + id);
	obj.setAttribute('style', 'visibility: hidden;');
	obj.style.visibility = 'hidden';
}

function insertHtml(where, el, html) {
	where = where.toLowerCase();
	if(el.insertAdjacentHTML) {
		switch(where) {
			case "beforebegin":
				el.insertAdjacentHTML('BeforeBegin', html);
				return el.previousSibling;
			case "afterbegin":
				el.insertAdjacentHTML('AfterBegin', html);
				return el.firstChild;
			case "beforeend":
				el.insertAdjacentHTML('BeforeEnd', html);
				return el.lastChild;
			case "afterend":
				el.insertAdjacentHTML('AfterEnd', html);
				return el.nextSibling;
		}
		throw 'Illegal insertion point -> "' + where + '"';
	}
	var range = el.ownerDocument.createRange();
	var frag;
	switch(where) {
		case "beforebegin":
			range.setStartBefore(el);
			frag = range.createContextualFragment(html);
			el.parentNode.insertBefore(frag, el);
			return el.previousSibling;
		case "afterbegin":
			if(el.firstChild) {
				range.setStartBefore(el.firstChild);
				frag = range.createContextualFragment(html);
				el.insertBefore(frag, el.firstChild);
				return el.firstChild;
			} else {
				el.innerHTML = html;
				return el.firstChild;
			}
		case "beforeend":
			if(el.lastChild) {
				range.setStartAfter(el.lastChild);
				frag = range.createContextualFragment(html);
				el.appendChild(frag);
				return el.lastChild;
			} else {
				el.innerHTML = html;
				return el.lastChild;
			}
		case "afterend":
				range.setStartAfter(el);
				frag = range.createContextualFragment(html);
				el.parentNode.insertBefore(frag, el.nextSibling);
				return el.nextSibling;
	}
	throw 'Illegal insertion point -> "' + where + '"';
}

function clearHtml(obj) {
	while (obj.childNodes.length > 0)
		obj.removeChild(obj.childNodes[0]);
}

function resetTalent(tree) {
	if (tree < 0) {
		treeTalentPoint = [0, 0, 0];
		treeDeepTier = [0, 0, 0];
		for (var z=0; z<3; z++)
			for (var x=1; x<=tierNum; x++) tierTalentPoint[z][x-1] = 0;
	} else {
		treeTalentPoint[tree] = 0;
		treeDeepTier[tree] = 0;
		for (var x=1; x<=tierNum; x++) tierTalentPoint[tree][x-1] = 0;
	}

	for (var z=0; z<3; z++) {
		if (tree < 0  || z == tree) {
			var talent_text = document.getElementById('talent_tree' + (z+1) + '_text');
			talent_text.innerHTML = treeName[z] + ': ' + treeTalentPoint[z];
		}
	}

	var flag = !Points;
	for (var x=0; x<talent.length; x++) {
		if (tree < 0  || talent[x][0] == tree) {
			var obj = document.getElementById('talent_' + x);
			var textObj = obj.getElementsByTagName('div')[1];

			Points += pointTalent[x];
			RequiredLevel -= pointTalent[x];
			pointTalent[x] = 0;
			if (talent[x][4] == 1)
				talent_available(obj);
			else
				talent_disable(obj);

			textObj.innerHTML = pointTalent[x] + '/' + talent[x][2];
			refreshTalentTooltip(x);
			refreshTalentArrow(x);
		} else if(flag) {
			var obj = document.getElementById('talent_' + x);
			if (pointTalent[x] <= 0 && talent[x][4] <= Math.floor(treeTalentPoint[ talent[x][0] ] / tierRequestPoint) + 1) {
				talent_available(obj);
				refreshTalentArrow(x);
			}
		}
	}

	refreshInformationBar();
}

function talent_ieFix() {
	if(!isIE) return;
	var ieVersion = getIEVersion();
	if (!ieVersion || ieVersion > 7) return;
	if (ieVersion <= 6)
		window.onload = talent_ieFix2;
	else
		talent_ieFix2();
}

function talent_ieFix2() {
	var all_moveId = new Array();
	var talent_container = document.getElementById('talent_container');
	var obj = document.getElementById('talent_container').getElementsByTagName('div');

	for (var x=0; x<obj.length; x++)
		if(obj[x].id.substring(0, 14) == 'talentTooltip_' || obj[x].id.substring(0, 13) == 'talent_arrow_')
			all_moveId.push(obj[x].id);
	for (var x=0; x<all_moveId.length; x++) {
		obj = document.getElementById(all_moveId[x]);

		var originalLeft; var originalTop; var tree_obj; var lastDisplay;
		if (talent_swap) {
			tree_obj = getTalentElement(obj);
			lastDisplay = tree_obj.style.display;
			tree_obj.style.display = 'block';

			var pos = talent_getPosAtTalentObj(obj);
			originalLeft = pos[0];
			originalTop = pos[1];
		} else {
			originalLeft = talent_getElementPosX(all_moveId[x]);
			originalTop = talent_getElementPosY(all_moveId[x]);
		}

		obj.style.bottom = 'auto';
		obj.style.right = 'auto';
		obj.style.left = originalLeft + 'px';
		obj.style.top = originalTop + 'px';

		if (talent_swap) {
			tree_obj.insertBefore(obj);
			tree_obj.style.display = lastDisplay;
		} else {
			talent_container.insertBefore(obj);
		}
	}
}

function getTalentElement(obj) {
	while(obj && (obj.id.substr(0, 11) != 'talent_tree' || obj.id.length < 16)) {
		obj = obj.parentNode;
	} return obj;
}

function getIEVersion() {
	if(!isIE) return false;

	var s = 'msie';
	var i = ua.indexOf(s);
	return parseFloat(ua.substr(i + s.length));
}

function talent_getPosAtTalentObj(offsetTrail) {
	var offsetLeft = 0;
	var offsetTop = 0;

	while(offsetTrail && (offsetTrail.id.substr(0, 11) != 'talent_tree' || offsetTrail.id.length < 16)) {
		offsetLeft += offsetTrail.offsetLeft;
		offsetTop += offsetTrail.offsetTop;
		offsetTrail = offsetTrail.offsetParent;
	}
	
	return [offsetLeft, offsetTop];
}

function talent_getElementPosX(id) {
	var offsetTrail = document.getElementById(id);
	var offsetLeft = 0;

	while(offsetTrail && offsetTrail.id != 'talent_container') {
		offsetLeft += offsetTrail.offsetLeft;
		offsetTrail = offsetTrail.offsetParent;
	}
	return offsetLeft;
}

function talent_getElementPosY(id) {
	var offsetTrail = document.getElementById(id);
	var offsetTop = 0;

	while(offsetTrail && offsetTrail.id != 'talent_container') {
		offsetTop += offsetTrail.offsetTop;
		offsetTrail = offsetTrail.offsetParent;
	}
	return offsetTop;
}

function create_html() {
	var i = 0;

	var html = new Array();
	for(var x=0; x<talent.length; x++) {
		if (talent[x][1] != '') {
			if (!html[ talent[x][0] ]) html[ talent[x][0] ] = new Array();
			if (!html[ talent[x][0] ][ talent[x][4] ]) html[ talent[x][0] ][ talent[x][4] ] = new Array();

			var tooltip_class;
			var image_on = talent_path + talentImagePath[x][0];
			var image_off = talent_path + talentImagePath[x][1];

			if (talent[x][0]<2 && talent[x][4] <= tierNum - 3)
				tooltip_class = 'talent_tooltip tooltip_general';
			else if (talent[x][0]<2)
				tooltip_class = 'talent_tooltip tooltip_bottom';
			else if (talent[x][4] <= tierNum - 3)
				tooltip_class = 'talent_tooltip tooltip_right';
			else
				tooltip_class = 'talent_tooltip tooltip_right_bottom';

			var arrow_html = new Array();
			if (talentBeRequired[x]) {
				for (var y=0; y<talentBeRequired[x].length; y++) {
					var fromId = x;
					var destId = talentBeRequired[x][y];
					var arrow_class;
					if (talent[fromId][3] == talent[destId][3])
						arrow_class = 'arrow_down_' + (talent[destId][4] - talent[fromId][4]);
					else if(talent[fromId][4] == talent[destId][4])
						arrow_class = 'arrow_' + (talent[fromId][3] > talent[destId][3]?'left':'right') + '_' + Math.abs(talent[destId][3] - talent[fromId][3]);
					else
						arrow_class = 'arrow_down_' + (talent[fromId][3] > talent[destId][3]?'left':'right') + '_' + (talent[destId][4] - talent[fromId][4]);
					arrow_html.push('<div id="talent_arrow_'+x+'_'+destId+'" class="talent_arrow arrow_grey"><div class="'+arrow_class+'"></div></div>');
				}
			}
			
			html[ talent[x][0] ][ talent[x][4] ][ talent[x][3] ] = '<div id="talent_'+x+'" class="talent_cell talent_disable"><div class="talent_box"></div><div class="talent_text"></div><div id="talentTooltip_'+x+'" class="' + tooltip_class + '">' + get_tooltip(x) + '</div>' + arrow_html.join('') + '<img src="' + image_on + '" class="talent_img img_ava"><img src="' + image_off + '" class="talent_img img_dis"></div>';
		}
	}


	var result = new Array();
	for (var z=0; z<3; z++) {
		if (!html[z]) html[z] = new Array();
		result.push('<div id="talent_tree'+(z+1)+'_box"><div id="talent_tree'+(z+1)+'_bar"><span id="talent_tree'+(z+1)+'_text" style="float:left">'+treeName[z]+': 0</span><span style="float:right"><a href="javascript:resetTalent('+z+');">重置</a></span><div style="clear:both;"></div></div><div id="talent_tree'+(z+1)+'_bg"><div id="talent_tree'+(z+1)+'">');
		for (var x=1; x<=tierNum; x++) {
			if (!html[z][x]) html[z][x] = new Array();
			for (var y=1; y<=4; y++) {
				result.push(html[z][x][y] ? html[z][x][y] : '<div class="talent_cell"></div>');
			}
		}
		result.push('</div></div></div>');
	}
	document.write(result.join(''));
}

function isArray(obj) {
	return obj.constructor == Array;
}