var Calculator = {
	start: function() {
		Tooltips.start();
		
		var json   = eval(featclass);
		var trees = new Array();
		var points = { 'total': 0, 'maxTier': 0, 'trees': {}};
		
		$each(json.Trees, function(tree, id) {
			this[id] = new Tree(id);
			points.trees[id] = 0;
		}, trees);
		
		$('closead').addEvent('click', function() {
			$('advert').setStyle('display', 'none');
		});

		$('class-select').addEvent('change', function(e) {
			var char_class = $(this).value;
			window.location.href = baseurl + char_class;
		});
			
		$('build-tab').addEvent('click', function(e) {
			$('summary').setStyle('display', 'none');
			$('builds').setStyle('display', 'block');
			$('summary-tab').removeClass('selected');
			$('build-tab').addClass('selected');
		});
		
		$('summary-tab').addEvent('click', function(e) {
			$('builds').setStyle('display', 'none');
			$('summary').setStyle('display', 'block');
			$('build-tab').removeClass('selected');
			$('summary-tab').addClass('selected');
		});
		
		$('submit-build-link').addEvent('click', function() {
			points.total = 0;
			$each(trees, function(tree, treeId) {
				if(typeof tree != 'undefined') {
					var treePoints = tree.info();
					points.trees[treeId] = treePoints;
					points.total += treePoints;
				}
			});
			
			if(points.total > 70) {
				if(logged_in == true) {
					$('submit-build').setStyle('display', 'block');
					window.scroll(0,300);
				} else {
					alert('You must log in before you can save a build!');
				}
			} else {
				alert('You must spend more than 70 points to submit a build!');
			}
		});
		
		$('submit-build-form').addEvent('submit', function(e) {
			new Event(e).stop();
			this.send();
			
			$('submit-build').empty().set('text', 'Your build has been submitted');
		});
		
		$('link').addEvent('click', function(e) {
			Calculator.featbuild(trees);
		});
		
		$each($$('span.reset'), function(reset) {
			var treeId = reset.getParent().getProperty('id');
			var tree = trees[treeId];
			
			reset.addEvent('click', function(e) {
				tree.reset();
				
				points.total = 0;
				points.maxTier = 0;
				$each(trees, function(tree, treeId) {
					if(typeof tree != 'undefined') {
						if(tree.maxTier > points.maxTier) {
							points.maxTier = tree.maxTier
						}
						var treePoints = tree.info();
						points.trees[treeId] = treePoints;
						points.total += treePoints;
					}
				});
				
				tree.update();
				Calculator.update(points, Calculator.featbuild(trees));
			});
		}, trees);
		
		$('resetall').addEvent('click', function(e) {
			points.total = 0;
			points.maxTier = 0;
			$each(trees, function(tree, treeId) {
				if(typeof tree != 'undefined') {
					tree.reset();
					var treePoints = tree.info();
					points.trees[treeId] = treePoints;
					points.total += treePoints;
					tree.update();
				}
			});
			
			Calculator.update(points, Calculator.featbuild(trees));
		});
		
		$each($$('option.build-link'), function(build) {
			var string = build.getProperty('value');
			
			build.addEvent('click', function(e) {
				Calculator.loadBuild(string, trees, builds);				
			});
		});
		
		Effects.start(json.Effects);
		
//		$each($$('div.feat', 'div.icon', 'div.border', 'div.border-active', 'div.ranks'), function(el) {
//			el.addEvents({
//			    'mousedown': function(){
//			        return false;
//			    },
//			    'click': function(){
//					return false;
//			    }
//			});
//		});
		
		$each(json.Feats, function(feat, id) {
			var trees = this;
			var tree = trees[feat.tree];
			tree.register(feat);
			
			$(id).addEvent('click', function(e) {
				e.preventDefault();
				e.stopPropagation();
				
				return false;
			});
			
			$(id).addEvent('mousedown', function(e) {
				e.preventDefault();
				e.stopPropagation();

				this.oncontextmenu = function(e) {
					return false;
				}
				
				points.total = 0;
				$each(trees, function(tree, treeId) {
					if(typeof tree != 'undefined') {
						var treePoints = tree.info();
						points.trees[treeId] = treePoints;
						points.total += treePoints;
					}
				});

				Click.handle(e, feat, tree, points);

				$each(trees, function(tree) {
					if(typeof tree != 'undefined') {
						tree.update();
					}
				});
								
				points.total = 0;
				points.maxTier = 0;
				$each(trees, function(tree, treeId) {
					if(typeof tree != 'undefined') {
						if(tree.maxTier > points.maxTier) {
							points.maxTier = tree.maxTier
						}
						var treePoints = tree.info();
						points.trees[treeId] = treePoints;
						points.total += treePoints;
					}
				});
				
				if(points.total >= 79) {
					$each(trees, function(tree) {
						if(typeof tree != 'undefined') {
							tree.stasis();
						}
					});
				}
				
				Calculator.update(points, Calculator.featbuild(trees));
				return false;
			});
			
		}, trees);
		
		if(window.location.href.indexOf("#") > -1 ) {
			var build = window.location.href.substr((window.location.href.indexOf("#") + 1));
			var split = build.split(':');

			if(split.length == 4) {			
				build = split[3];
				Calculator.loadBuild(build, trees, builds);
			} else {
				Calculator.loadBuild(build, trees, builds);
			}
		} else {
			$each(trees, function(tree) {
				if(typeof tree != 'undefined') {
					tree.update();
				}
			});
		}
	},
	
	update: function(points, featbuild) {
		var levelTier = new Array(10, 15, 20, 25, 30, 40, 50, 60, 70);
		var levelPts  = new Array('-');
		
		var i = 10;
		var end = 80;
		while(i <= end) {
			levelPts.push(i);

			if(i % 10 == 0 && i != 10) {
				levelPts.push(i);
			}
			if(i == 75) {
				levelPts.push(i);
			}		
			i++;
		}

		var levelreq  = levelTier[points.maxTier];
		document.location.hash = featbuild;
		
		$('build-build').setProperty('value', featbuild);
		
		$('points-spent').set('text', '[ ' + points.total + ' ]');
		$('points-left').set('text', '[ ' + (79 - points.total) + ' ]');
		
		if((levelPts[points.total]) >= levelreq || points.total == 0) {
			levelreq = (levelPts[points.total]);
		}
		
		$('level-req').set('text', '[ ' + levelreq + ' ]');
		
		var ptDist = '';
		$each(points.trees, function(tP, treeId) {
			ptDist += treeId + ':' + tP + '/';
			$(treeId).getElement('.tree-points').set('text', '[ ' + tP + ' ]');
		});
		
		$('build-dist').setProperty('value', ptDist);
	},
	
	featbuild: function(trees, buildId) {
		var featbuild = '';
		
		$each(trees, function(tree) {
			if(typeof tree != 'undefined') {
				featbuild = featbuild + tree.featbuild() + ':';
			}
		});
		
		if(buildId) {
			featbuild = featbuild + buildId;
		} else {
			featbuild = featbuild.substring(0, (featbuild.length -1));
		}
				
		return featbuild;
	},
	
	loadBuild: function(build, trees, builds) {
		if(isNaN(build)) {
			var string = build;
		} else {
			var loaded = true;
			var string = builds[build].build;
		}
		
		if(string.indexOf(":") > -1) {
			var iterative = false;
			
			var treeStrings = string.split(':');
		} else {
			var oldBuild = new Element('div', { 'class': 'loginc error'});
			oldBuild.set('html', '<b>WARNING!</b> You are viewing an old feat build that may be incorrect. You can view it in the old ' +
								 'feat calculator <a href="http://f.goonheim.com/' + featclass + '#' + string + '">HERE</a>');
			oldBuild.inject('advert', 'before');
			
			var iterative = true;
			
			string = string.replace('t0', '');
			string = string.replace('t1', ':');
			string = string.replace('t2', ':');
			
			var tS = string.split(':');
			var foo = new Array();
			var treeStrings = new Array();

			var ordered = array_combine(treeOrder, tS);
			$each(ordered, function(s, id) {
				foo[id] = s;
			});
			
			for(var i=0; i<foo.length; i++) {
				if(foo[i]) {
					treeStrings.push(foo[i]);
				}
			}
		}
		
		var iter = 0;
	
		$each(trees, function(tree) {
			if(typeof tree != 'undefined') {
				tree.reset();
				tree.featMap(iterative);
				
				var string = treeStrings[iter];
				if(string) {
					var split = new Array();			
					
					for(var i=0; i<string.length; i++) {
						split[i] = string.substring(i, (i + 1));
					}
					
					for(var i=0; i<split.length; i++) {
						if(!isNaN(split[i])) {
							continue;
						}
		
						var featId = tree.map[get_letter_number(split[i])];
						var feat   = tree.featInfo(featId);
						
						if(feat) {
							if(!isNaN(split[(i + 1)])) {
								var rank = split[(i + 1)];
							} else {
								var rank = feat.maxRank;
							}
			
							for(var j=1; j<=rank; j++) {
								if(j == rank) {
									tree.train(featId, false, true);
								} else {
									tree.train(featId, true, true);
								}
							}
						}
					}
				}
				
				iter++;
			}
		});
		
		var points = { 'total': 0, 'maxTier': 0, trees: {}};

		$each(trees, function(tree, treeId) {
			if(typeof tree != 'undefined') {
				var treePoints = tree.info();
				points.trees[treeId] = treePoints;
				points.total += treePoints;
				tree.update();
				
				if(tree.maxTier > points.maxTier) {
					points.maxTier = tree.maxTier
				}
			}
		});
		
		if(points.total >= 79) {
			$each(trees, function(tree) {
				if(typeof tree != 'undefined') {
					tree.stasis();
				}
			});
		}
		
		if(loaded) {
			$('build-type').set('text', builds[build].type);
//			$('build-rating').set('text', builds[build].rating);
			$('build-desc').set('text', builds[build].description);
			$('build-submitter').set('text', builds[build].user);
			$('build-submittedon').set('text', builds[build].date);
			Calculator.update(points, Calculator.featbuild(trees, build));
		} else {
			Calculator.update(points, Calculator.featbuild(trees));
		}
		
	}
}

var Click = {
	handle: function(e, feat, tree, points) {
		switch(e.rightClick) {
			case false:
				if(e.control == true || e.shift == true) {
					if(e.shift == true && e.control == false) {
						for(var i = 0; i < feat.maxRank; i++) {
							if(points.total < 79) {
								tree.interact('train', feat.id);
								points.total++;
							}
						}
					} else {
						if(e.shift == true) {
							for(var i = 0; i < feat.maxRank; i++) {
								tree.interact('untrain', feat.id);
							}
						}
						
						tree.interact('untrain', feat.id);
					}
				} else {
					if(points.total < 79) {
						tree.interact('train', feat.id);
					}
				}
				break;
			case true:
				if(e.shift == true) {
					for(var i = feat.rank; i > 0; i--) {
						tree.interact('untrain', feat.id);
					}
				} else {
					tree.interact('untrain', feat.id);
				}

				break;
		}
	}
}

var Feat = {
	activate: function(id) {
		id = String(id);
		
		var iter  = $(id).getProperty('var');
		var xpos  = Number(iter * -36);
		var ypos  = 0;
		var bgpos = String(xpos + 'px ' + ypos + 'px');

		var icon = $(id).getElement('.icon');
		icon.setStyle('background-position', bgpos);
	},
	
	hilite: function(id) {
		id = String(id);
		
		var tile = $(id).getElement('.border-active');
		tile.setStyle('background-position', '-46px 0px');
	},
	
	unhilite: function(id) {
		id = String(id);
		
		var tile = $(id).getElement('.border-active');
		tile.setStyle('background-position', '0px 0px');
	},
	
	deactivate: function(id) {
		id = String(id);
		
		var iter  = $(id).getProperty('var');
		var xpos  = Number(iter * -36);
		var ypos  = -36;
		var bgpos = String(xpos + 'px ' + ypos + 'px');

		var icon = $(id).getElement('.icon');
		icon.setStyle('background-position', bgpos);	
	},

	rank: function(id, rank, maxRank) {
		id = String(id);
		
		var xpos  = Number((maxRank - 1) * -60);
		var ypos  = Number((125 - (rank * 25)) * -1);
		var bgpos = String(xpos + 'px ' + ypos + 'px');

		var ranks = $(id).getElement('.ranks');
		ranks.setStyle('background-position', bgpos);
	},
	
	summary: function(feat) {
		var summary = $('summary-' + feat.id);
		if(summary.getElement('.summary-rank')) {
			if(feat.rank == 0) {
				summary.empty();
			} else {
				var summaryrank = summary.getElement('.summary-rank');
				summaryrank.set('text', feat.rank + '/' + feat.maxRank);
			}
		} else {
			var summaryfeat = new Element('span', {'class': 'summary-feat'});
			var summaryrank = new Element('span', {'class': 'summary-rank'});
			
			summaryfeat.set('text', feat.name);
			summaryrank.set('text', feat.rank + '/' + feat.maxRank);
			
			summaryfeat.inject(summary);
			summaryrank.inject(summary);
		}
	}
}

var Tooltips = {
	start: function() {
		new Tips('.feat-container', {className: 'tooltip'});
		new Tips('.summary-row', {className: 'tooltip'});
	},
	
	update: function(featId, title, effects, text, rank, postpone) {
		featId = String(featId);

		$(featId).store('tip:title', title);
		$(featId).store('tip:effects', effects);
		$(featId).store('tip:text', text);
		
		if(rank == 0) {
			$(featId).store('tip:subtext', 'Click to train. Shift-click to max.');
		} else {
			$(featId).store('tip:subtext', 'Right-click to untrain. Shift-right-click to untrain to 0.');			
		}

		if($('summary-' + featId)) {
			$('summary-' + featId).store('tip:title', title);
			$('summary-' + featId).store('tip:effects', effects);
			$('summary-' + featId).store('tip:text', text);
		}
	}
}

var Effects = {
	effects: new Hash(),
	
	start: function(effects) {
		Effects.effects = effects;
	},
	
	generate: function(featId, rank) {
		var text = '';
		$each(Effects.effects[featId].efs, function(effect) {
			switch(effect.type) {
				case 1:
				case 2:
					text = text + '<div class="tip-effects-mod">Power Increase</div>';
					switch(effect.amountType) {
						case 0:
							text = text + '<div class="tip-effects-val">' + effect.description + '</div>';
							break;
						case 1:
							text = text + '<div class="tip-effects-val">' + 
										  	effect.description.replace(/%1/g, '<span class="mod-val">+' + effect.amounts[rank] + '</span>') + 
										  '</div>';
							break;
						case 2:
							text = text + '<div class="tip-effects-val">' + 
										  	effect.description.replace(/%1/g, '<span class="mod-val">+' + effect.amounts[rank] + '%</span>') + 
										  '</div>';
										  
							break;
					}
					
					text = text.replace(/\+-/g, '-');
					
					if(effect.affected) {
						text = text + '<div class="tip-effects-mod">Affected</div>';
						text = text + '<div class="tip-effects-val">' + effect.affected + '</div>';
					}
					
					break;
				case 3:
					text = text + '<div class="tip-effects-mod">Chance on Hit</div>';
					
					switch(effect.amountType) {
						case 0:
							text = text + '<div class="tip-effects-val">' + effect.description + '</div>';
							break;
						case 1:
							text = text + '<div class="tip-effects-val">' + 
										  	effect.description.replace(/%1/g, '<span class="mod-val">+' + effect.amounts[rank] + '</span>') + 
										  '</div>';
							break;
						case 2:
							text = text + '<div class="tip-effects-val">' + 
										  	effect.description.replace(/%1/g, '<span class="mod-val">+' + effect.amounts[rank] + '%</span>') + 
										  '</div>';
							break;
					}
					
					text = text.replace(/\+-/g, '-');
					
					if(effect.affected) {
						text = text + '<div class="tip-effects-mod">Affected</div>';
						text = text + '<div class="tip-effects-val">' + effect.affected + '</div>';
					}
					
					break;
				case 4:
					text = text + '<div class="tip-effects-mod">Upgrade Combo</div>';
				
					switch(effect.amountType) {
						case 0:
							text = text + '<div class="tip-effects-val">' + effect.description + '</div>';
							break;
						case 1:
							text = text + '<div class="tip-effects-val">' + 
										  	effect.description.replace(/%1/g, '<span class="mod-val">+' + effect.amounts[rank] + '</span>') + 
										  '</div>';
							break;
						case 2:
							text = text + '<div class="tip-effects-val">' + 
										  	effect.description.replace(/%1/g, '<span class="mod-val">+' + effect.amounts[rank] + '%</span>') + 
										  '</div>';
							break;
					}
					
					text = text.replace(/\+-/g, '-');
					
					if(effect.affected) {
						text = text + '<div class="tip-effects-mod">Affected</div>';
						text = text + '<div class="tip-effects-val">' + effect.affected + '</div>';
					}
				
					break;
				case 5:
					text = text + '<div class="tip-effects-mod">Change</div>';
					switch(effect.amountType) {
						case 0:
							text = text + '<div class="tip-effects-val">' + effect.description + '</div>';
							break;
						case 1:
							text = text + '<div class="tip-effects-val">' + 
										  	effect.description.replace(/%1/g, '<span class="mod-val">+' + effect.amounts[rank] + '</span>') + 
										  '</div>';
							break;
						case 2:
							text = text + '<div class="tip-effects-val">' + 
										  	effect.description.replace(/%1/g, '<span class="mod-val">+' + effect.amounts[rank] + '%</span>') + 
										  '</div>';
							break;
					}
					
					text = text.replace(/\+-/g, '-');
					
					if(effect.affected) {
						text = text + '<div class="tip-effects-mod">Affected</div>';
						text = text + '<div class="tip-effects-val">' + effect.affected + '</div>';
					}
					
					break;
				case 6:
					text = text + '<div class="tip-effects-mod">Chance on Combo</div>';
					
					switch(effect.amountType) {
						case 0:
							text = text + '<div class="tip-effects-val">' + effect.description + '</div>';
							break;
						case 1:
							text = text + '<div class="tip-effects-val">' + 
										  	effect.description.replace(/%1/g, '<span class="mod-val">+' + effect.amounts[rank] + '</span>') + 
										  '</div>';
							break;
						case 2:
							text = text + '<div class="tip-effects-val">' + 
										  	effect.description.replace(/%1/g, '<span class="mod-val">+' + effect.amounts[rank] + '%</span>') + 
										  '</div>';
							break;
					}
					
					text = text.replace(/\+-/g, '-');
					
					if(effect.affected) {
						text = text + '<div class="tip-effects-mod">Affected</div>';
						text = text + '<div class="tip-effects-val">' + effect.affected + '</div>';
					}
				
					break;
				case 7:
					text = text + '<div class="tip-effects-mod">Grants Spell</div>';
					text = text + '<div class="tip-effects-val">' + effect.description + '</div>';
					break;
			}
		});
		return text;
	}
}

var Tree = new Class({
	initialize: function(id) {
		this.id      = id;
		this.points  = new Array(0, 0, 0, 0, 0, 0, 0, 0, 0);
		this.feats   = new Array();
		this.map     = new Array();
		this.maxTier = 0;
	},
	
	register: function(feat) {
		this.feats[feat.id] = feat;
		this.feats[feat.id].rank = 0;
		this.feats[feat.id].active = false;
		
		Tooltips.update(feat.id, feat.name, this.genEfs(feat.id), feat.description, this.feats[feat.id].rank, true);
	},
	
	interact: function(action, featId) {
		if(this.check(action, featId)) {
			eval('this.' + action + '(' + featId + ')');
		}
	},
	
	reset: function() {
		this.points = new Array(0, 0, 0, 0, 0, 0, 0, 0, 0);
		this.maxTier = 0;
		
		$each(this.feats, function(feat) {
			if(typeof feat != 'undefined') {
				feat.rank = 0;
				this.feats[feat.id].active = false;
				
				Feat.rank(feat.id, feat.rank, feat.maxRank);
				Feat.unhilite(feat.id);
				Feat.deactivate(feat.id);
							
				Tooltips.update(this.feats[feat.id].id, 
								this.feats[feat.id].name, 
								this.genEfs(this.feats[feat.id].id), 
								this.feats[feat.id].description, 
								this.feats[feat.id].rank, true);
				
				if($('summary-' + feat.id)) {
					$('summary-' + feat.id).empty();
				}
			}
		}, this);
	},
	 
	update: function() {
		$each(this.feats, function(feat) {
			if(typeof feat != 'undefined') {
				if((this.feats[feat.id].rank == 0 && this.feats[feat.id].active == true)) {
					if(!this.check('train', feat.id)) {
						Feat.deactivate(feat.id);	
						this.feats[feat.id].active = false;
					}
				} else {
					if((this.feats[feat.id].rank > 0 && this.feats[feat.id].active == false) || this.check('train', feat.id)) {
						Feat.activate(feat.id);
						this.feats[feat.id].active = true;
					}
				}
			}
		}, this);
	},
	
	check: function(action, featId) {
		switch(action) {
			case 'train':
				var points = 0;
				
				$each(this.points, function(t) {
					points = points + t;
				});
				
				if(points < (this.feats[featId].row * 5)) {
					return false;
				}
				
				if(this.feats[featId].rank >= this.feats[featId].maxRank) {
					return false;					
				}
				
				if(this.feats[featId].req) {
					var req =  this.feats[featId].req;
					if(this.feats[req].rank < this.feats[req].maxRank) {
						return false;
					} else {
						this.feats[req].dep = featId;
					}
				}
				
				return true;
				break;
			case 'untrain':
				if(this.feats[featId].rank <= 0) {
					return false;
				}

				var maxTier = 0;
				$each(this.points, function(t, i) {
					if(i > maxTier && t > 0) {
						maxTier = i;				
					}
				});
				
				if(this.feats[featId].row < maxTier) {
					var total = 0;
					for(var i = (this.feats[featId].row); i >= 0; i--) {
						total += this.points[i];
					}
					
					if(((this.feats[featId].row + 1) * 5) >= total) {
						return false;
					} else {
						var total = 0;
						
						for(var i = (maxTier - 1); i >= 0; i--) {
							total += this.points[i];
						}
		
						if((maxTier * 5) >= total) {
							return false;
						}
					}
				}
				
				if(this.feats[featId].dep) {
					var dep =  this.feats[featId].dep;
					if(this.feats[dep].rank > 0) {
						return false;
					} 
				}
				
				return true;
				break;
		}
	},
	
	train: function(featId, postpone, tip_postpone) {
		if(this.feats[featId].rank == this.feats[featId].maxRank) {
			return;
		}
		
		this.feats[featId].rank++;
		this.points[this.feats[featId].row]++;
		
		if(this.feats[featId].rank == this.feats[featId].maxRank && postpone == true) {
			Feat.rank(featId, this.feats[featId].rank, this.feats[featId].maxRank);
			Feat.hilite(featId);
			Feat.summary(this.featInfo(featId));
			
			Tooltips.update(this.feats[featId].id, this.feats[featId].name, this.genEfs(this.feats[featId].id), this.feats[featId].description, this.feats[featId].rank, tip_postpone);
		}
		
		if(this.feats[featId].row > this.maxTier) {		
			this.maxTier = this.feats[featId].row;
		}
		
		if(typeof(postpone) == 'undefined' || !postpone || postpone == false) { 
			Feat.rank(featId, this.feats[featId].rank, this.feats[featId].maxRank);
			Feat.hilite(featId);
			Feat.summary(this.featInfo(featId));
			
			Tooltips.update(this.feats[featId].id, this.feats[featId].name, this.genEfs(this.feats[featId].id), this.feats[featId].description, this.feats[featId].rank, tip_postpone);
		} 
	},
	
	untrain: function(featId) {
		this.feats[featId].rank--;
		this.points[this.feats[featId].row]--;
		
		var maxTier = 0;
		
		$each(this.points, function(t, i) {
			if(i > maxTier && t > 0) {
				maxTier = i;				
			}
		});
		
		this.maxTier = maxTier;
		
		Feat.rank(featId, this.feats[featId].rank, this.feats[featId].maxRank);
		Feat.summary(this.featInfo(featId));
		
		if(this.feats[featId].rank <= 0) {
			Feat.unhilite(featId);
		}
		
		Tooltips.update(this.feats[featId].id, this.feats[featId].name, this.genEfs(this.feats[featId].id), this.feats[featId].description, this.feats[featId].rank);
	},
	
	genEfs: function(featId) {
		if(!Effects.effects[featId]) {
			return;
		} 

		if(this.feats[featId].rank == 0) {
			var text = '<div class="tip-effects-ranks">';
			var text = text + '<span class="tip-effects-rank">Rank ' + this.feats[featId].rank + '/' + this.feats[featId].maxRank + '</span>';
			var text = text + Effects.generate(featId, this.feats[featId].rank);
			var text = text + '</div>';
		} else if(this.feats[featId].rank == this.feats[featId].maxRank) {
			var text = '<div class="tip-effects-ranks">';
			var text = text + '<span class="tip-effects-rank">Rank ' + this.feats[featId].rank + '/' + this.feats[featId].maxRank + '</span>';
			var text = text + Effects.generate(featId, (this.feats[featId].rank - 1));
			var text = text + '</div>';
		} else {
			var text = '<div class="tip-effects-ranks">';
			var text = text + '<span class="tip-effects-rank">Rank ' + this.feats[featId].rank + '/' + this.feats[featId].maxRank + '</span>';
			var text = text + Effects.generate(featId, (this.feats[featId].rank - 1));
			var text = text + '</div>';
			var text = text + '<div class="tip-effects-ranks">';
			var text = text +'<span class="tip-effects-rank">Next Rank ' + (this.feats[featId].rank + 1) + '/' + this.feats[featId].maxRank + '</span>';
			var text = text + Effects.generate(featId, this.feats[featId].rank);
			var text = text + '</div>';
		}
		
		return text;
	},
	
	featbuild: function() {
		var build = '';
		var iter  = 0;
		
		$each(this.feats, function(feat) {
			if(typeof feat != 'undefined') {
				if(feat.rank > 0) {
					var part = get_number_letter(iter);
					
					if(feat.rank != feat.maxRank) {
						part = part + feat.rank;
					}
					
					build = build + part;
				}
				
				iter++;
			}
		});
		
		return build;
	},
	
	stasis: function() {
		$each(this.feats, function(feat) {
			if(typeof feat != 'undefined') {
				if(feat.rank < 1) {
					Feat.deactivate(feat.id);
					feat.active = false;
				}
			}
		});
	},
	
	info: function() {
		var points = 0;
				
		$each(this.points, function(t) {
			points = points + t;
		});
		
		return points;
	},
	
	featMap: function(iterative) {
		if(typeof(iterative) == 'undefined' || !iterative || iterative == false) {
			$each(this.feats, function(feat) {
				if(typeof feat != 'undefined') {
					this.map.push(feat.id);
				}
			}, this);
		} else {
			var sort = new Array();
			$each(this.feats, function(feat) {
				if(typeof feat != 'undefined') {
					if(!sort[feat.row]) {
						sort[feat.row] = new Array();
					}
	
					if(feat.column == '2.5' || feat.column == '3.5') {
						sort[feat.row][3] = feat.id;
					} else {
						sort[feat.row][feat.column] = feat.id;
					}
				}
			});
			
			for(var i=0; i<sort.length; i++) {
				for(var j=0; j<sort[i].length; j++) {
					if(sort[i][j]) {
						this.map.push(sort[i][j]);
					}
				}
			}
		}
	},
	
	featInfo: function(featId) {
		if(this.feats[featId]) {
			var featInfo = new Hash({rank: this.feats[featId].rank, maxRank: this.feats[featId].maxRank, tree: this.feats[featId].tree,
								     tier: this.feats[featId].row, name: this.feats[featId].name, id: featId });
			
			return featInfo;
		} 
	}
});

function get_number_letter(number) {
	letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRTSUVWXYZ";
	return (letters.charAt(number));
}

function get_letter_number(letter) {
	letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRTSUVWXYZ";
	return (letters.indexOf(letter));	
}

function array_combine(keys, values) {
    var new_array = {}, keycount=keys.length, i;
 
    if( !keys || !values || keys.constructor !== Array || values.constructor !== Array ){
        return false;
    }
 
    if(keycount != values.length){
        return false;
    }
 
    for ( i=0; i < keycount; i++ ){
        new_array[keys[i]] = values[i];
    }
 
    return new_array;
}

window.addEvent('domready', Calculator.start);
