/**
 * @author	Sven Kutzner
 * @copyright	2007-2009 deixu.net
 * @license	GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
 */

function ArmoryUtil() {
	this.tooltip;
	this.language = new Array();
	this.items = new Array();
	this.characters = new Array();
	this.ajaxRequest;
	this.currentUuid = "";
	this.requestQueue = new Array();
	this.search = new Array();
	this.searchForm = new Array();
	this.searchInsertType = '';
	this.searchType = 'items';
	
	// mouse cursor position
	this.cursorX = 0;
	this.cursorY = 0;
	
	
	this.getLang = function(type, item, replacements) {
		var value = '';
		item = 'wcf.wow.'+type+'.'+item;
		if(!this.language[type]) return '';
		if(!this.language[type][item]) return '';
		item = this.language[type][item];
		if(replacements != undefined) {
			for(var key in replacements) {
				if(key != undefined) {
					value = replacements[key];
					key = '{$'+key+'}';
					item = item.replace(key, value.toString());
				}
			}
		}
		return item;
	}
	
	// UUID functions
	this.S4 = function () {
		return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
	}

	this.uuid = function() {
		return (this.S4()+this.S4()+"-"+this.S4()+"-"+this.S4()+"-"+this.S4()+"-"+this.S4()+this.S4()+this.S4());
	}

	this.clearItems = function() {
		this.items.clear();
	}
	
	this.clearCharacters = function() {
		this.characters.clear();
	}

	this.addName = function(element, name, quality) {
		var node = document.createElement("div");
		node.className = 'wowItemName wowQuality'+quality;
		node.innerHTML = name;
		element.appendChild(node);		
	}
	
	this.addTextNode = function(element, text, alignment, margin) {
		var node = document.createElement("div");
		if(alignment == 'right') {
			node.className = 'wow'+alignment.capitalize();
		} else if(alignment == 'left') {
			node.className = 'wowText wow'+alignment.capitalize();
		} else {
			node.className = 'wowText';
		}
		if(margin) {
			node.className = node.className + ' wowMargin';
		}
		node.innerHTML = text;
		element.appendChild(node);
	}

	this.addSpellNode = function(element, text) {
		var node = document.createElement("div");
		node.className = 'wowText wowSpell';
		node.innerHTML = text;
		element.appendChild(node);
	}

	this.addSetNode = function(element, text) {
		var node = document.createElement("div");
		node.className = 'wowText wowSet';
		node.innerHTML = text;
		element.appendChild(node);
	}

	this.addSetTextNode = function(element, text) {
		var node = document.createElement("div");
		node.className = 'wowText wowSetMargin';
		node.innerHTML = text;
		element.appendChild(node);
	}

	this.addSetGrayNode = function(element, text) {
		var node = document.createElement("div");
		node.className = 'wowText wowSetMargin wowGray';
		node.innerHTML = text;
		element.appendChild(node);
	}

	this.addGrayNode = function(element, text) {
		var node = document.createElement("div");
		node.className = 'wowText wowGray';
		node.innerHTML = text;
		element.appendChild(node);
	}

	this.addIntValue = function(element, value, type) {
		var text = '';
		if(value > 0) text = '+';
		text = text + value + ' ' + type;
		this.addTextNode(element, text);
	}
	
	this.addSocket = function(element, socket) {
		var node = document.createElement("div");
		node.className = 'wowGray wowSocket'+socket.color;
		if(socket.enchant != '') {
			node.innerHTML = socket.enchant;
		} else {
			node.innerHTML = this.getLang('item', 'socket.'+socket.color.toLowerCase());
		}
		element.appendChild(node);
	}
	
	this.generateTooltipHTML = function(item) {
		var text = '';
		var alignment = '';
		var data = item.data;
		var idata;
		
		item.tooltip = document.createElement("div");
		item.tooltip.className = 'wowTooltip';
		this.addName(item.tooltip, item.data.name, item.data.quality);
		if(data.zoneBound) this.addTextNode(item.tooltip, this.getLang('item', 'zoneBound', {'item.zoneBound':data.zoneBound}))
		if(data.instanceBound) this.addTextNode(item.tooltip, this.getLang('item', 'instanceBound', {'item.instanceBound':data.instanceBound}))
		if(data.bonding) this.addTextNode(item.tooltip, this.getLang('item', 'bonding.'+item.data.bonding));
		if(data.equipment.inventoryType > 0) {
			text = '';
			switch(data.equipment.inventoryType) {
			case "18":
				text = this.getLang('item', 'bag', {'item.equipment.containerSlots':data.equipment.containerSlots,'item.equipment.subclassName':data.equipment.subclassName});
				break;
			default:
				if(data.classId == 6) {
					text = this.getLang('item', 'projectile');
				} else {
					text = this.getLang('item', 'slot.'+data.equipment.inventoryType);
				}
				break;
			}
			if(data.equipment.subclassName != '') alignment = 'left';
			this.addTextNode(item.tooltip, text, alignment);
			if(data.equipment.subclassName != '' && data.equipment.inventoryType != 18)
				this.addTextNode(item.tooltip, data.equipment.subclassName, 'right');
		}
		
		if(data.damage.dps > 0) {
			for(var i=0;i<data.damage.data.length;i++) {
				text = data.damage.data[i].min + '-' + data.damage.data[i].max + ' ' + this.getLang('item', 'damage.'+data.damage.data[i].type);
				if(i > 0) {
					text = '+ ' + text;
					this.addTextNode(item.tooltip, text);
				} else {
					this.addTextNode(item.tooltip, text, 'left');
					text = this.getLang('item', 'damage.speed') + ' ' + Number(data.damage.speed).toFixed(2);
					this.addTextNode(item.tooltip, text, 'right');
				}
			}
			text = '(' + (Math.round(Number(data.damage.dps) * 10) / 10) + ' ' + this.getLang('item', 'damage.dps') + ')';
			this.addTextNode(item.tooltip, text);			
		}
		
		if(data.stats.armor > 0) {
			text = this.getLang('item', 'armor', {'item.stats.armor':data.stats.armor});
			if(data.stats.armorBonus == 0) {
				this.addTextNode(item.tooltip, text);
			} else {
				this.addSpellNode(item.tooltip, text);
			}
		}
		if(data.stats.blockValue > 0) this.addTextNode(item.tooltip, this.getLang('item', 'blockValue', {'item.stats.blockValue':data.stats.blockValue}));
		if(data.enchant != "")        this.addSpellNode(item.tooltip, data.enchant);
		// stats
		if(data.stats.strength != 0)  this.addIntValue(item.tooltip, data.stats.strength, this.getLang('item', 'stat.strength'));
		if(data.stats.agility != 0)   this.addIntValue(item.tooltip, data.stats.agility, this.getLang('item', 'stat.agility'));
		if(data.stats.stamina != 0)   this.addIntValue(item.tooltip, data.stats.stamina, this.getLang('item', 'stat.stamina'));
		if(data.stats.intellect != 0) this.addIntValue(item.tooltip, data.stats.intellect, this.getLang('item', 'stat.intellect'));
		if(data.stats.spirit != 0)    this.addIntValue(item.tooltip, data.stats.spirit, this.getLang('item', 'stat.spirit'));

		if(data.resistances.fire != 0)    this.addIntValue(item.tooltip, data.resistances.fire, this.getLang('item', 'resistance.fire'));
		if(data.resistances.nature != 0)    this.addIntValue(item.tooltip, data.resistances.nature, this.getLang('item', 'resistance.nature'));
		if(data.resistances.frost != 0)    this.addIntValue(item.tooltip, data.resistances.frost, this.getLang('item', 'resistance.frost'));
		if(data.resistances.shadow != 0)    this.addIntValue(item.tooltip, data.resistances.shadow, this.getLang('item', 'resistance.shadow'));
		if(data.resistances.arcane != 0)    this.addIntValue(item.tooltip, data.resistances.arcane, this.getLang('item', 'resistance.arcane'));

		if(data.sockets.data.length > 0) {
			for(var i=0;i<data.sockets.data.length;i++) {
				this.addSocket(item.tooltip, data.sockets.data[i]);
			}
			if(data.sockets.matchEnchant != '')
				this.addTextNode(item.tooltip, this.getLang('item', 'socket.bonus')+': '+data.sockets.matchEnchant);
		}
		
		if(data.gemProperties)        this.addTextNode(item.tooltip, data.gemProperties);
		if(data.durability.max > 0)
			this.addTextNode(item.tooltip, this.getLang('item', 'durability', {'item.durability.current':data.durability.current, 'item.durability.max':data.durability.max }));
		
		if(data.allowableRaces.length > 0) {
			this.addTextNode(item.tooltip, this.getLang('item', 'allowableRaces')+' '+data.allowableRaces.join(', '));
		}
		if(data.allowableClasses.length > 0) {
			this.addTextNode(item.tooltip, this.getLang('item', 'allowableClasses')+' '+data.allowableClasses.join(', '));
		}
		
		if(data.requirements.level > 0) this.addTextNode(item.tooltip, this.getLang('item', 'requiredLevel', {'item.requirements.level':data.requirements.level}));

		this.addTextNode(item.tooltip, this.getLang('item', 'level', {'item.level':data.level}));

		for(var bonus in data.bonus) {
			if(data.bonus[bonus] != 0) {
				this.addSpellNode(item.tooltip, this.getLang('item', 'bonus.'+bonus)+' '+data.bonus[bonus]+'.');
			}
		}

		if(data.spells.length > 0) {
			if(data.classId == 9) {
				this.addSpellNode(item.tooltip, this.getLang('item', 'spell.'+data.spells[0].trigger)+': '+data.spells[0].desc);
				if(data.spells[0].charges > 1) {
					this.addTextNode(item.tooltip, data.spells[0].charges+' '+this.getLang('item', 'charges'));
				}
				if(data.spells[0].reagents.length > 0) {
					this.addTextNode(item.tooltip, this.getLang('item', 'requires')+': '+data.spells[0].reagents.join(', '), '', true);
				}
			} else {
				for(var spell in data.spells) {
					if(data.spells[spell].desc != undefined) {
						this.addSpellNode(item.tooltip, this.getLang('item', 'spell.'+data.spells[spell].trigger)+': '+data.spells[spell].desc);
						if(data.spells[spell].charges > 1) {
							this.addTextNode(item.tooltip, data.spells[spell].charges+' '+this.getLang('item', 'charges'));
						}
						if(data.spells[spell].reagents.length > 0) {
							this.addTextNode(item.tooltip, this.getLang('item', 'requires')+': '+data.spells[spell].reagents.join(', '), '', true);
						}
					}
				}
			}
		}
		
		if(data.set.name != '') {
			var equipped = 0;
			for(var i=0; i<data.set.items.length;i++) {
				equipped = equipped + data.set.items[i].equipped;
			}
			this.addTextNode(item.tooltip, '&nbsp;');
			this.addSetNode(item.tooltip, data.set.name+' ('+equipped+'/'+data.set.items.length+')');
			for(var i=0; i<data.set.items.length;i++) {
				if(data.set.items[i].equipped == 0) {
					this.addSetGrayNode(item.tooltip, data.set.items[i].name)
				} else {
					this.addSetTextNode(item.tooltip, data.set.items[i].name)
				}
			}

			if(data.set.bonus.length > 0) {
				this.addTextNode(item.tooltip, '&nbsp;');
				for(var i=0; i<data.set.bonus.length;i++) {
					if(equipped >= data.set.bonus[i].threshold) {
						this.addSetTextNode(item.tooltip, '('+data.set.bonus[i].threshold+') '+data.set.bonus[i].desc)
					} else {
						this.addSetGrayNode(item.tooltip, '('+data.set.bonus[i].threshold+') '+data.set.bonus[i].desc)
					}
				}
			}
		}
		if(data.desc != '')	{
			this.addSetNode(item.tooltip, '&quot;'+data.desc+'&quot;', '', true);
		}
		if(data.source.type=='creatureDrop') {
			var difficulty = '';
			if(data.source.difficulty == 'h') { difficulty = ' ('+this.getLang('item', 'source.heroic')+')'; }
			this.addTextNode(item.tooltip, this.getLang('item', 'source')+': '+data.source.area+difficulty+', '+data.source.creature.trim(), '' , true);
		}
	}

	this.handleItem = function(response) {
		var item = this.items[response.uuid];
		item.data = response.data;
		if(item.type == 'tooltip') {
			this.generateTooltipHTML(item);
			item.tooltip.className = 'wowTooltip wowTooltipMouseOver';
			this.displayTooltip(item.element);
		}
	}
	
	this.handleLanguage = function(response) {
		this.language[response.category] = response.data;
		if(response.category == 'item')
			this.initElements();
	}

	this.sendRequest = function(uri) {
		new Ajax.Request(uri, {
			onSuccess: function(response) {
				var result = response.responseText.evalJSON();
				if(result.type == 'item') {
					armoryUtil.handleItem(result);
				} else if(result.type == 'language') {
					armoryUtil.handleLanguage(result);
				} else if(result.type == 'search') {
					armoryUtil.handleSearch(result);
				}
			}
		});
	}
	
	this.addItem = function(element) {
		var args = element.title.split(",");
		var itemId = args[0];
		var type = args[1] ? args[1] : "tooltip";
		var uuid = element.id;
		if(this.items[uuid] == null) {
			this.items[uuid] = new Array();
			this.currentUuid = uuid;
			this.items[uuid] = {
				"id": itemId,
				"type": type,
				"element": element,
				"uuid": uuid,
				"data": null,
				"tooltip": ""
			};
			if(type == 'tooltip') {
				element.onmouseover = function(e) { armoryUtil.tooltipMouseOver(e); };
				element.onmouseout = function(e) { armoryUtil.tooltipMouseOut(e); };
			}
			element.title = "";
		}
	}
	
	this.initElements = function() {
		var objs=new Array(),teststr;
		objs=document.getElementsByTagName("a");

		for(i=0;i<objs.length;i++) {
			teststr=","+objs[i].className.split(" ").join(",")+",";
			if(teststr.indexOf(",wowitem,")!=-1) {
				this.addItem(objs[i]);
			}
		}
	}
	
	this.displayTooltip = function(element) {
		var item = this.items[element.id];
		var top, left, width, height;
		var offset = element.cumulativeOffset();
		var ttSize, ttOffset;
		var offset = element.cumulativeOffset();
		var scrollOffset = element.cumulativeScrollOffset();
		var viewportSize = document.viewport.getDimensions();
		
		width = element.getWidth();
		height = element.getHeight();
		top = offset.top + height;
		left = offset.left + width;
		
		this.tooltip.innerHTML = '';
		this.tooltip.appendChild(item.tooltip);
		
		this.tooltip.style.visibility = "hidden";
		this.tooltip.style.width = "310px";
		this.tooltip.style.height = "auto";
		this.tooltip.style.display = "block";
		this.tooltip.style.left = left+"px";
		this.tooltip.style.top = top+"px";
		
		ttSize = this.tooltip.getDimensions();
		ttOffset = this.tooltip.viewportOffset();
		
		if(ttOffset.left+ttSize.width > viewportSize.width) {
			this.tooltip.style.left = (offset.left)+"px";
		}
		if(ttOffset.top+ttSize.height > viewportSize.height) {
			this.tooltip.style.top = (offset.top-ttSize.height)+"px";
		}
		this.tooltip.style.visibility = "visible";
	}
	
	this.tooltipMouseOver = function(event) {
		var top, left, width, height;
		event = event || window.event;
		var target = event.target || event.srcElement;
		var item = this.items[target.id];
		var offset = target.cumulativeOffset();
		var scrollOffset = target.cumulativeScrollOffset();
		var viewportSize = document.viewport.getDimensions();
		if(item.tooltip == "") {
			width = target.getWidth();
			height = target.getHeight();
			top = offset.top + height;
			left = offset.left + width;
			
			this.tooltip.style.visibility = "hidden";
			this.tooltip.style.width = "50px";
			this.tooltip.style.height = "50px";
			this.tooltip.style.display = "block";
			this.tooltip.style.left = left+"px";
			this.tooltip.style.top = top+"px";
			this.tooltip.innerHTML = '<img class="wowTooltip wowTooltipMouseOver" src="'+RELATIVE_WCF_DIR+'icon/wowLoad.gif" />';
			this.tooltip.style.visibility = "visible";
			this.sendRequest("index.php?page=ArmoryItem&id="+item.id+"&uuid="+item.uuid);
		} else {
			this.displayTooltip(target);
		}	
	}

	this.tooltipMouseOut = function(event) {
		this.tooltip.innerHTML = '';
		this.tooltip.style.display = "none";
		this.tooltip.style.visibility = "hidden";
	}

	this.init = function() {
		this.tooltip = document.createElement("div");
		this.tooltip.style.display = "none"
		this.tooltip.className = "wowPopup";
		document.body.appendChild(this.tooltip);
		this.sendRequest("index.php?page=ArmoryLanguage&category=item");		
	}
	
	this.initSearch = function() {
		this.sendRequest("index.php?page=ArmoryLanguage&category=search");
		
		this.searchForm["name"] = document.getElementById('wowSearchNameValue');
		this.searchForm["name"].onkeydown = function(e) { return armoryUtil.searchCheckEnter(e); }
		this.searchForm["realm"] = document.getElementById('wowSearchRealmValue');
		this.searchForm["realm"].onkeydown = function(e) { return armoryUtil.searchCheckEnter(e); }
		this.searchForm["language"] = document.getElementById('wowSearchLanguageValue');
		this.searchForm["insertType"] = document.getElementById('wowSearchInsertTypeValue');

		this.searchForm["results"] = document.getElementById('wowSearchResults');
		this.searchForm["resultList"] = document.getElementById('wowSearchResultList');
		this.searchForm["resultDesc"] = document.getElementById('wowSearchResultDesc');
		this.searchForm["submit"] = document.getElementById('wowSearchSubmitButton');
		this.searchForm["submit"].onclick = function(e) { return armoryUtil.searchExec(); }
	}
	
	this.searchCheckEnter = function(e) {
		var characterCode;
		if(e && e.which){
			e = e;
			characterCode = e.which;
		} else {
			e = event;
			characterCode = e.keyCode;
		}
		if(characterCode == 13){
			armoryUtil.searchExec();
			return false
		} else {
			return true
		}
	}
	
	this.searchSetType = function(type) {
		this.searchType = type;
		if(this.searchType == 'items') {
			this.search.realm.style.display = "none";
		} else if(this.searchType == 'characters' || this.searchType == 'guilds') {
			this.search.realm.style.display = "block";
		}

	}
	
	this.searchExec = function() {
		var uri = 'index.php?page=ArmorySearch&name='+this.searchForm.name.value;
		if(this.searchType == 'characters' || this.searchType == 'guilds') { uri = uri +'&realm='+this.searchForm.realm.value; }
		this.searchForm.results.style.display = 'none';
		this.sendRequest(uri);
	}
	
	this.searchTableAddRow = function(element, className) {
		var row = document.createElement('tr');
		row.className = className;
		element.appendChild(row);
		return row;
	}

	this.searchTableAddHeadColumn = function(element, className, content) {
		var column = document.createElement('th');
		column.className = className;
		column.innerHTML = content;
		element.appendChild(column);
		return column;
	}

	this.searchTableAddColumn = function(element, className, content) {
		var column = document.createElement('td');
		column.className = className;
		column.innerHTML = content;
		element.appendChild(column);
		return column;
	}

	this.searchInitResultList = function(element) {
		var row, column;
		var table = document.createElement('table');
		var thead = document.createElement('thead');
		var tbody = document.createElement('tbody');
		table.className = 'tableList wowSearchList border';
		table.appendChild(thead);
		table.appendChild(tbody);
		if(this.search.searchType == 'items') {
			row = this.searchTableAddRow(thead, 'tableHead');
			column = this.searchTableAddHeadColumn(row, 'wowSearchID', this.getLang('search','id'));
			column = this.searchTableAddHeadColumn(row, 'wowSearchName', this.getLang('search','name'));
			column = this.searchTableAddHeadColumn(row, 'wowSearchRelevance', this.getLang('search','relevance'));
		} else {
		}
		element.appendChild(table);
		return tbody;
	}
	
	this.searchInsertItem = function(id) {
		var params = '';
		if(this.searchForm.insertType.value != '') params = '='+this.searchForm.insertType.value;
		WysiwygInsert('text','[wowitem'+params+']'+id+'[/wowitem]');
	}
	
	this.searchAddRelevanceBar = function(element, percent) {
		var relevance = document.createElement('div');
		var relevanceInner = document.createElement('div');
		var relevanceText = document.createElement('div');
		relevance.appendChild(relevanceInner);
		relevance.appendChild(relevanceText);
		relevance.className = "wowRelevanceOuter";
		relevanceInner.className = "wowRelevanceInner";
		relevanceText.className = "wowRelevanceText";
		relevanceInner.style.width = percent+'px';
		relevanceText.style.marginLeft = '-'+percent+'px'
		relevanceText.innerHTML = percent+'%';
		element.appendChild(relevance);
	}

	this.searchAddResult = function(element, resultItem) {
		uuid = this.uuid();
		if(resultItem.name == this.search.name) {
			rowClass = 'wowSearchHighlight';
		} else {
			rowClass = '';
		}
		row = this.searchTableAddRow(element, rowClass);
		column = this.searchTableAddColumn(row, 'wowSearchID', resultItem.id);
		column.id = 'wowSID-'+uuid;
		column.ondblclick = function(e) { armoryUtil.searchInsertItem(resultItem.id); }
		
		column = this.searchTableAddColumn(row, 'wowSearchName wowQuality'+resultItem.quality, resultItem.name);
		column.id = 'wowSN-'+uuid;
		column.ondblclick = function(e) { armoryUtil.searchInsertItem(resultItem.id); }
		column.style.backgroundImage = "url('index.php?page=ArmoryIcon&name="+resultItem.icon+"&size=21')";
		
		column = this.searchTableAddColumn(row, 'wowSearchRelevance', '');
		column.id = 'wowSR-'+uuid;
		column.ondblclick = function(e) { armoryUtil.searchInsertItem(resultItem.id); }
		this.searchAddRelevanceBar(column, resultItem.relevance);		
	}
	
	this.handleSearch = function(response) {
		var tbody, column;
		var rowClass = '';
		var uuid = '';
		var resultItem;
		
		
		this.search = response;
		this.searchForm.resultList.innerHTML = '';
		if(this.search.resultCount > 0) {
			tbody = this.searchInitResultList(this.searchForm.resultList);
			for(var i = 0; i < this.search.resultCount; i++) {
				this.searchAddResult(tbody, this.search.results[i])
			}
		} else {
			this.searchForm.resultList.innerHTML = this.getLang('search','notFound').replace('{$name}', this.search.name);
		}
		this.searchForm.results.style.display = '';
	}

}

var armoryUtil = new ArmoryUtil();
onloadEvents.push(function() { armoryUtil.init(); });
