if(typeof $WowheadPower == 'undefined')
var $WowheadPower = new function()
{
function ce(z, p){var r = document.createElement(z); if(p) cO(r, p); return r }
function ae(z,y){return z.appendChild(y)}
function aE(z,y,x){if(window.attachEvent)z.attachEvent('on'+y,x);else z.addEventListener(y,x,false)}
function cO(d, s)
{
	for(var p in s)
	{
		if(typeof s[p] == 'object')
		{
			if(!d[p]) d[p] = {};
			cO(d[p], s[p]);
		}
		else
			d[p] = s[p];
	}
}
function $E(e)
{
	if(!e) e = event;
	if(!e._button)
	{
		e._button = e.which  ? e.which : e.button;
		e._target = e.target ? e.target : e.srcElement;
	}
	return e;
}
function getWindowSize()
{
	var width = 0, height = 0;

	if(typeof window.innerWidth == 'number') //Non-IE
	{
		width = window.innerWidth;
		height = window.innerHeight;
	}
	else if(document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight))
  	{
		//IE 6+ in 'standards compliant mode'
		width = document.documentElement.clientWidth;
		height = document.documentElement.clientHeight;
	}
 	else if(document.body && (document.body.clientWidth || document.body.clientHeight))
	{
		//IE 4 compatible
		width = document.body.clientWidth;
		height = document.body.clientHeight;
	}

	return {w: width, h: height};
}
function getScroll()
{
	var x = 0, y = 0;
	if(typeof(window.pageYOffset) == 'number')
	{
		//Netscape compliant
		x = window.pageXOffset;
		y = window.pageYOffset;
	}
	else if(document.body && (document.body.scrollLeft || document.body.scrollTop))
	{
		//DOM compliant
		x = document.body.scrollLeft;
		y = document.body.scrollTop;
	}
	else if(document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop))
	{
		//IE6 standards compliant mode
		x = document.documentElement.scrollLeft;
		y = document.documentElement.scrollTop;
	}

	return {x: x, y: y};
}
function getCursorPos(e)
{
	var x, y;
	if(window.innerHeight)
	{
		x = e.pageX;
		y = e.pageY;
	}
	else
	{
		var scroll = getScroll();
		x = e.clientX + scroll.x;
		y = e.clientY + scroll.y;
	}

	return {x: x, y: y};
}
function getLocaleFromDomain(domain)
{
	var _ = getLocaleFromDomain.L;

	return (_[domain] ? _[domain] : 0);
}
getLocaleFromDomain.L = {
//	www: 25,
	fr: 2,
	de: 3,
	es: 6,
	ru: 7,
	wotlk: 0
};
function getIdFromTypeName(typeName)
{
	var _ = getIdFromTypeName.L;

	return (_[typeName] ? _[typeName] : -1);
}
getIdFromTypeName.L = {
	npc: 1,
	object: 2,
	item: 3,
	itemset: 4,
	quest: 5,
	spell: 6,
	zone: 7,
	faction: 8,
	pet: 9,
	achievement: 10
};
function convertRatingToPercent(level, rating, value)
{
	var ratingBases = {
		12:  1.5, // DEFENSE_SKILL_RATING
		13: 12,   // DODGE_RATING
		14: 15,   // PARRY_RATING
		15:  5,   // BLOCK_RATING
		16: 10,   // HIT_MELEE_RATING
		17: 10,   // HIT_RANGED_RATING
		18:  8,   // HIT_SPELL_RATING
		19: 14,   // CRIT_MELEE_RATING
		20: 14,   // CRIT_RANGED_RATING
		21: 14,   // CRIT_SPELL_RATING
		22: 10,   // HIT_TAKEN_MELEE_RATING
		23: 10,   // HIT_TAKEN_RANGED_RATING
		24:  0,   // HIT_TAKEN_SPELL_RATING
		25:  0,   // CRIT_TAKEN_MELEE_RATING
		26:  0,   // CRIT_TAKEN_RANGED_RATING
		27:  0,   // CRIT_TAKEN_SPELL_RATING
		28: 10,   // HASTE_MELEE_RATING
		29: 10,   // HASTE_RANGED_RATING
		30: 10,   // HASTE_SPELL_RATING
		31: 10,   // HIT_RATING
		32: 14,   // CRIT_RATING
		33:  0,   // HIT_TAKEN_RATING
		34:  0,   // CRIT_TAKEN_RATING
		35: 25,   // RESILIENCE_RATING
		36: 10,   // HASTE_RATING
		37:  2.5, // EXPERTISE_RATING
		44:  4.69512176513672 // ARMOR PENETRATION RATING
	};

	if(level < 0)
		level = 1;
	else if(level > 80)
		level = 80;

	// Patch 2.4.3: Parry Rating, Defense Rating, and Block Rating
	if((rating == 14 || rating == 12 || rating == 15) && level < 34)
		level = 34

	if(value < 0)
		value = 0;

	var percent;
	if(ratingBases[rating] == null)
		percent = 0;
	else
	{
		var H;

		if(level > 70)
			H = (82 / 52) * Math.pow((131 / 63), ((level - 70) / 10));
		else if(level > 60)
			H = (82 / (262 - 3 * level));
		else if(level > 10)
			H = ((level - 8) / 52);
		else
			H = 2 / 52;

		percent = value / ratingBases[rating] / H;
	}

	return percent;
}



	var
		opt = { applyto: 3 },

		currentType,
		currentId,
		currentLocale,

		currentDomain,

		currentPcs,
		currentLvl,
		currentBuff,

		cursorX,
		cursorY,

		head = document.getElementsByTagName('head')[0],

		items        = {},
		quests       = {},
		spells       = {},
		achievements = {},

		tooltip,
		tooltipTable,
		tooltipTd,
		tooltipIcon,
		tooltipLogo,

		showIcon = 1,
		showLogo = 0,

		ie  = !!(window.attachEvent && !window.opera),
		ie7 = navigator.userAgent.indexOf('MSIE 7.0') != -1,
		ie6 = navigator.userAgent.indexOf('MSIE 6.0') != -1 && !ie7,

		LANG = {
			loading: 'Loading...',
			noresponse: 'No response from server :('
		},

		STATUS_NONE     = 0,
		STATUS_QUERYING = 1,
		STATUS_ERROR    = 2,
		STATUS_NOTFOUND = 3,
		STATUS_OK       = 4,

		TYPE_ITEM        = 3,
		TYPE_QUEST       = 5,
		TYPE_SPELL       = 6,
		TYPE_ACHIEVEMENT = 10,

		CURSOR_HSPACE = 15,
		CURSOR_VSPACE = 15,

		LOOKUPS = {
			3:  [items,		'item',		'Item'],
			5:  [quests,		'quest',	'Quest'],
			6:  [spells,		'spell',	'Spell'],
			10: [achievements,	'achievement',	'Achievement']
		},

		LOCALES = {
			0: 'enus',
			2: 'frfr',
			3: 'dede',
			6: 'eses',
			7: 'ruru'
		};

	function init()
	{
		ae(head, ce('link', {type: 'text/css', href: 'http://www.wowhead.com/widgets/power/power.css?3', rel: 'stylesheet'}));

		if(ie)
		{
			ae(head, ce('link', {type: 'text/css', href: 'http://www.wowhead.com/widgets/power/power_ie.css?3', rel: 'stylesheet'}));
			if(ie6)
				ae(head, ce('link', {type: 'text/css', href: 'http://www.wowhead.com/widgets/power/power_ie6.css?3', rel: 'stylesheet'}));
		}

		aE(document, 'mouseover', onMouseOver);
	}

	function updateCursorPos(e)
	{
		var pos = getCursorPos(e);
		cursorX = pos.x;
		cursorY = pos.y;
	}

	function scanElement(t, e)
	{
		if(t.nodeName != 'A' && t.nodeName != 'AREA') return -2323;
		if(!t.href.length) return;

		var i0, i1, i2, m, params = {};

		var p = function(m, k, v) { if(k == 'buff') params[k] = true; else if(k == 'rand' || k == 'ench' || k == 'lvl') params[k] = parseInt(v); else if(k == 'gems' || k == 'pcs') params[k] = v.split(':'); };

		if(opt.applyto & 1)
		{
			i0 = 1;
			i1 = 2;
			i2 = 3;
			m = t.href.match(/^http:\/\/(www|dev|fr|es|de|ru|wotlk)?\.?wowhead\.com\/\?(item|quest|spell|achievement)=([0-9]+)/);

			showLogo = 0;
		}

		if(m == null && (opt.applyto & 2) && t.rel)
		{
			i0 = 0;
			i1 = 1;
			i2 = 2;
			m = t.rel.match(/(item|quest|spell|achievement).?([0-9]+)/);

			showLogo = 1;
		}

		t.href.replace(/([a-zA-Z]+).?([0-9:\\-]*)/g, p);
		if(t.rel)
			t.rel.replace(/([a-zA-Z]+).?([0-9:\\-]*)/g, p);

		if(m)
		{
			var
				locale,
				domain = 'www';

			if(i0 && m[i0])
				domain = m[i0];

			locale = getLocaleFromDomain(domain);
			if(domain == 'wotlk')
				domain = 'www';

			currentDomain = domain;

			if(!t.onmousemove)
			{
				t.onmousemove = onMouseMove;
				t.onmouseout  = onMouseOut;
			}

			updateCursorPos(e);

			display(getIdFromTypeName(m[i1]), m[i2], locale, params);
		}
	}

	function onMouseOver(e)
	{
		e = $E(e);
		var t = e._target;

		var i = 0;
		while(t != null && i < 3 && scanElement(t, e) == -2323)
		{
			t = t.parentNode;
			++i;
		}
	}

	function onMouseMove(e)
	{
		e = $E(e);
		updateCursorPos(e);
		moveTooltip();
	}

	function onMouseOut()
	{
		currentType = null;
		currentPcs = [];
		currentLvl = null;
		currentBuff = null;
		hideTooltip();
	}

	function initTooltip()
	{
		if(!tooltip)
		{
			var d = ce('div'), t = ce('table'), tb = ce('tbody'), tr1 = ce('tr'), tr2 = ce('tr'), td = ce('td'), th1 = ce('th'), th2 = ce('th'), th3 = ce('th');

			d.className = 'wowhead-tooltip';

			th1.style.backgroundPosition = 'top right';
			th2.style.backgroundPosition = 'bottom left';
			th3.style.backgroundPosition = 'bottom right';

			ae(tr1, td);
			ae(tr1, th1);
			ae(tb, tr1);
			ae(tr2, th2);
			ae(tr2, th3);
			ae(tb, tr2);
			ae(t, tb);

			//{
				tooltipIcon = ce('p');
				tooltipIcon.style.display = 'none';
				ae(tooltipIcon, ce('div'));
				ae(d, tooltipIcon);
			//}

			ae(d, t);
			ae(document.body, d);

			tooltip = d;
			tooltipTable = t;
			tooltipTd = td;

			var img = ce('div');
			img.className = 'wowhead-tooltip-powered';
			ae(d, img);
			tooltipLogo = img;

			hideTooltip();
		}
	}

	function showTooltip(html, icon, pcs, lvl)
	{
		if(!tooltip)
			initTooltip();

		if(!html)
		{
			html = LOOKUPS[currentType][2] + ' not found :(';
			icon = 'Temp';
		}
		else
		{
			if(pcs && pcs.length)
			{
				var n = 0;
				for(var i = 0, len = pcs.length; i < len; ++i)
				{
					if(html.indexOf('<span><!--si' + pcs[i] + '-->') != -1)
					{
						html = html.replace('<span><!--si' + pcs[i] + '-->', '<span class="q8">');
						++n;
					}
				}

				if(n > 0)
				{
					html = html.replace('(0/', '(' + n + '/');
					html = html.replace(new RegExp('<span>\\(([0-' + n + '])\\) Set:', 'g'), '<span class="q2">($1) Set:');
				}
			}

			if(lvl)
			{
				html = html.replace(
					/\(<!--r([0-9]+):([0-9]+):([0-9]+)-->([0-9.%]+)(.+?)([0-9]+)\)/g,

					function(_, _, r, v, _, str, _)
					{
						var pct = convertRatingToPercent(lvl, r, v);

						pct = (Math.round(pct * 100) / 100);

						if(r != 12 && r != 37) // Neither Defense, nor Expertise
							pct += '%';

						return '(<!--r' + lvl + ':' + r + ':' + v + '-->' + pct + str + lvl + ')';
					}
				);
			}
		}

		if(tooltipLogo)
			tooltipLogo.style.display = (showLogo ? '' : 'none');

		if(showIcon && icon)
		{
			tooltipIcon.style.backgroundImage = 'url(http://static.wowhead.com/images/icons/medium/' + icon.toLowerCase() + '.jpg)';
			tooltipIcon.style.display = '';
		}
		else
		{
			tooltipIcon.style.backgroundImage = 'none';
			tooltipIcon.style.display = 'none';
		}

		tooltip.style.display = '';
		tooltip.style.width = '320px';

		tooltipTd.innerHTML = html;
		fixTooltip();
		moveTooltip();

		tooltip.style.visibility = 'visible';
	}

	function hideTooltip()
	{
		if(!tooltip) return;

		tooltip.style.display = 'none';
		tooltip.style.visibility = 'hidden';
	}

	function fixTooltip()
	{
		var c = tooltipTd.childNodes;

		if(c.length >= 2 && c[0].nodeName == 'TABLE' && c[1].nodeName == 'TABLE')
		{
			c[0].style.whiteSpace = 'nowrap';

			var m;
			if(c[1].offsetWidth > 300)
				m = Math.max(300, c[0].offsetWidth) + 20;
			else
				m = Math.max(c[0].offsetWidth, c[1].offsetWidth) + 20;

			if(m > 20)
			{
				tooltip.style.width = m + 'px';
				c[0].style.width = c[1].style.width = '100%';
			}
		}
		else
			tooltip.style.width = tooltipTable.offsetWidth + 'px';

	}

	function moveTooltip()
	{
		if(!tooltip) return;
		if(cursorX == null) return;

		var
			windowSize = getWindowSize(),
			scroll = getScroll(),
			bcw = windowSize.w,
			bch = windowSize.h,
			bsl = scroll.x,
			bst = scroll.y,
			tow = tooltipTable.offsetWidth,
			toh = tooltipTable.offsetHeight,
			left = cursorX + CURSOR_HSPACE,
			top  = cursorY - toh - CURSOR_VSPACE;

		if(left + CURSOR_HSPACE + tow + 4 >= bsl + bcw)
		{
			var foo = cursorX - tow - CURSOR_HSPACE;
			if(foo >= 0)
				left = foo;
			else
				left = bsl + bcw - tow - CURSOR_HSPACE - 4;
		}

		if(top < bst)
		{
			top = cursorY + CURSOR_VSPACE;

			if(top + toh > bst + bch)
			{
				top = bst + bch - toh;

				if(showIcon)
				{
					if(cursorX >= left - 48 && cursorX <= left && cursorY >= top - 4 && cursorY <= top + 48)
						top -= 48 - (cursorY - top);
				}
			}
		}

		tooltip.style.left = left + 'px';
		tooltip.style.top  = top  + 'px';
	}

	function getTooltipField(locale)
	{
		return (currentBuff ? 'buff_' : 'tooltip_') + LOCALES[locale];
	}

	function initElement(type, id, locale)
	{
		var arr = LOOKUPS[type][0];

		if(arr[id] == null)
			arr[id] = {};

		if(arr[id].status == null)
			arr[id].status = {};

		if(arr[id].status[locale] == null)
			arr[id].status[locale] = STATUS_NONE;
	}

	function display(type, id, locale, params)
	{
		if(!params)
			params = {};

		var fullId = id + (params.rand ? 'r' + params.rand : '') + (params.ench ? 'e' + params.ench : '') + (params.gems ? 'g' + params.gems.join(',') : '');

		currentType   = type;
		currentId     = fullId;
		currentLocale = locale;
		currentPcs    = params.pcs;
		currentLvl    = params.lvl;
		currentBuff   = params.buff;

		initElement(type, fullId, locale);

		var arr = LOOKUPS[type][0];

		if(arr[fullId].status[locale] == STATUS_OK || arr[fullId].status[locale] == STATUS_NOTFOUND)
			showTooltip(arr[fullId][getTooltipField(locale)], arr[fullId].icon, currentPcs, currentLvl);
		else
		{
			if(arr[fullId].status[locale] == STATUS_QUERYING)
				showTooltip(LANG.tooltip_loading);
			else
				request(type, id, locale, null, params);
		}
	}

	function request(type, id, locale, stealth, params)
	{
		var fullId = id + (params.rand ? 'r' + params.rand : '') + (params.ench ? 'e' + params.ench : '') + (params.gems ? 'g' + params.gems.join(',') : '');

		var arr = LOOKUPS[type][0];

		if(arr[fullId].status[locale] != STATUS_NONE && arr[fullId].status[locale] != STATUS_ERROR)
			return;

		arr[fullId].status[locale] = STATUS_QUERYING;

		if(!stealth)
			arr[fullId].timer = setTimeout(function(){showLoading.apply(this, [type, fullId, locale])}, 333);

		var p = '';
		for(var i in params)
		{
			if(i != 'rand' && i != 'ench' && i != 'gems')
				continue;

			if(typeof params[i] == 'object')
				p += '&' + i + '=' + params[i].join(':');
			else
				p += '&' + i + '=' + params[i];
		}

		ajaxIshRequest('http://' + currentDomain + '.wowhead.com/?' + LOOKUPS[type][1] + '=' + id + p + '&power&lol');
	}

	function ajaxIshRequest(url)
	{
		ae(head, ce('script', {type: 'text/javascript', src: url}));
	}

	function showLoading(type, id, locale)
	{
		if(currentType == type && currentId == id && currentLocale == locale)
		{
			showTooltip(LANG.loading);

			var arr = LOOKUPS[type][0];

			arr[id].timer = setTimeout(function(){notFound.apply(this, [type, id, locale])}, 3850);
		}
	}

	function notFound(type, id, locale)
	{
		var arr = LOOKUPS[type][0];

		arr[id].status[locale] = STATUS_ERROR;

		if(currentType == type && currentId == id && currentLocale == locale)
			showTooltip(LANG.tooltip_noresponse);
	}

	this.register = function(type, id, locale, json)
	{
		var arr = LOOKUPS[type][0];

		clearTimeout(arr[id].timer);
		cO(arr[id], json);

		if(arr[id][getTooltipField(locale)])
			arr[id].status[locale] = STATUS_OK;
		else
			arr[id].status[locale] = STATUS_NOTFOUND;

		if(currentType == type && id == currentId && currentLocale == locale)
			showTooltip(arr[id][getTooltipField(locale)], arr[id].icon, currentPcs, currentLvl);
	}

	this.registerItem = function(id, locale, json)
	{
		this.register(TYPE_ITEM, id, locale, json);
	}

	this.registerQuest = function(id, locale, json)
	{
		this.register(TYPE_QUEST, id, locale, json);
	}

	this.registerSpell = function(id, locale, json)
	{
		this.register(TYPE_SPELL, id, locale, json);
	}

	this.registerAchievement = function(id, locale, json)
	{
		this.register(TYPE_ACHIEVEMENT, id, locale, json);
	}

	this.set = function(foo)
	{
		cO(opt, foo);
	}

	this.showTooltip = function(e, tooltip, icon)
	{
		updateCursorPos(e);
		showTooltip(tooltip, icon);
	}

	this.hideTooltip = function()
	{
		hideTooltip();
	}

	this.moveTooltip = function(e)
	{
		onMouseMove(e);
	}



	init();
};
