//create global GameManager

processMochiTAL = function (dom, data) {
	if (dom.nodeType != 1) {
		return;
	}
	
	var attr;
	
	// handle repeat tags
	attr = getAttribute(dom, "mochi:repeat");
	if (attr) {
		dom.removeAttribute("mochi:repeat");
		var parent = dom.parentNode;
		attr = attr.split(" ");
		log("Repeat", attr[1]);
		var name = attr[0];
		var lst = valueForKeyPath(data, attr[1]);
		if (!lst) {	
			return;
		}
		
		for (var i=0; i<lst.length; ++i) {
			data[name] = lst[i];
			var newDOM = dom.cloneNode(true);
			processMochiTAL(newDOM, data);
			parent.insertBefore(newDOM, dom);
		}
		
		parent.removeChild(dom);
		return;
	}
	
	// handle content tags
	attr = getAttribute(dom, "mochi:content");
	if (attr) {
		log("content", attr);
		dom.removeAttribute("mochi:content");
		replaceChildNodes(dom, valueForKeyPath(data, attr));
		return;
	}
	
	attr = getAttribute(dom, "mochi:formattedContent");
	if (attr) {
		log("form-content", attr);
		dom.removeAttribute("mochi:formattedContent");
		var format = getAttribute(dom, "mochi:format");
		if (format) {
			replaceChildNodes(dom, 	numberFormatter(format)(valueForKeyPath(data, attr)));
		} else {
			replaceChildNodes(dom, 	numberFormatter("#%")(valueForKeyPath(data, attr)));
		}		
		return;
	}
	
	// handle custom link...
	attr = getAttribute(dom, "mochi:customLink");
	if (attr) {
		dom.removeAttribute("mochi:customLink");

		attr = attr.split(" ");

		var href = attr[0];
		var ref1 = attr[1];
		var ref2 = attr[2];
		
		//dom.href = href + "?" + ref1 + "=" + valueForKeyPath(data, "item.home") + "&" + ref2 + "=" + valueForKeyPath(data, "item.away");
		dom.href = href + "?" + ref1 + "=" + valueForKeyPath(data, "item.homeID") + "&" + ref2 + "=" + valueForKeyPath(data, "item.awayID");
	}
	
	// make a shallow copy of the child nodes - in case it changes due to repeat attr
	var nodes = list(dom.childNodes);
	
	// now iterate through them and continue the processing
	for (var i=0; i<nodes.length; ++i) {
		processMochiTAL(nodes[i], data);
	}	
};

ignoreEvent = function(ev) {
	if (ev && ev.preventDefault) {
		ev.preventDefault();
		ev.stopPropagation();
	} else if (typeof(event) != 'undefined') {
		event.cancelBubble = false;
		event.returnValue = false;
	}
};

var hiddenLinksGBL = null;
var subMenuHome = null;

toggleDivTypeVisibility = function (ev) {
	ignoreEvent(ev);
	log ("toggle div vis");
	var myListID = getAttribute(this, "mochi:listID");
	
	for (var i=0; i<hiddenLinksGBL.length; ++i) {
		if(getAttribute(hiddenLinksGBL[i], "mochi:parentID") == myListID) {
			// now toggle the attribute...
			var vis = hiddenLinksGBL[i].style;

			if(vis.display==''&&elem.offsetWidth!=undefined&&elem.offsetHeight!=undefined)
				vis.display = (elem.offsetWidth!=0&&elem.offsetHeight!=0)?'block':'none';
			vis.display = (vis.display==''||vis.display=='block')?'none':'block';			
		} else {
			setStyle(hiddenLinksGBL[i], {"display": "none"});
		}

	}
};

loadFromDivisionAnchor = function(ev) {
	ignoreEvent(ev);
	var divisionID = this.getAttribute("mochi:division");
	gameManager.loadFromURL(gameManager.scriptName, {divID: divisionID});
	
	log("SelectedDivision", this.firstChild.innerHTML);
	
	// change the text for the divison label
	var tempDivisionLabel = this.firstChild.innerHTML;
	swapDOM("divisionLabel", SPAN({id: "divisionLabel"}, tempDivisionLabel));
	
	//clear the other division anchors
	clearAnchorStyles("mochi:division");
	
	//and set this one
	//this.setAttribute("style", "color:#000000;background-color:#f1f30a;");
	setStyle(this, {'color': '#000000', 'background-color': '#f1f30a'});
};

clearAnchorStyles = function(key) {
	var anchors = getElementsByTagAndClassName("a", null);

	for (var i=0; i<anchors.length; ++i) {
		var node = anchors[i];

		var division = getAttribute(node, key);

		if (division) {
			//node.setAttribute("style", "");
			//setNodeAttribute(node, "style", "");
			//node.style = null;
			setStyle(node, {'color': null, 'background-color': null});
		}

	}

};

getAttribute = function (dom, key) {
	try {
		return dom.getAttribute(key);
	} catch (e) {
		return null;
	}
};

valueForKeyPath = function (data, keyPath) {
	var chunks = keyPath.split(".");
	while (chunks.length && data) {
		data = data[chunks.shift()];
	}
	return data;
};

SortTransforms = {
	"str": operator.identity,
	"isoDate": isoDate
};


GameManager = function() {
	this.defaultDivId = 0;
	this.templates = [];
	this.deferred = null;
	this.data = null;
	this.loadingData = null;
	this.scriptName = "/cgi-bin/new_site/GetTeamRankingsIntl.pl";
	this.sortState = {};
	
	bindMethods(this);
};

GameManager.prototype = {
	"initialize": function() {
		log("initializing");
		
		// grab the template divs, and then remove their temp class
		var templates = getElementsByTagAndClassName(null, "mochi-template");
		
		for (var i=0; i<templates.length; ++i) {
			var template = templates[i];
			var proto = template.cloneNode(true);
			removeElementClass(proto, "mochi-template");
			this.templates.push({"template": proto, "node": template});
		}
				
		// go through and get the team links
		log("Grab links");
		
		hiddenLinksGBL = new Array();		
		
		var links = document.getElementsByTagName("a");
		
		for (var i=0; i<links.length; ++i) {
			// lets merge in the vislist...

			if (links[i].className == "mochi-visList_top") {
				var listID = getAttribute(links[i], "mochi:listID");

				if (listID) {
					links[i].onclick = toggleDivTypeVisibility;
				}	
			} else if (links[i].className == "mochi-visList_bottom") {
				hiddenLinksGBL[hiddenLinksGBL.length] = links[i];

				var parentID = getAttribute(links[i], "mochi:parentID");

				if (parentID) {
					var division = getAttribute(links[i], "mochi:division");

					if (division) {
						links[i].onclick = loadFromDivisionAnchor;
					}
				}				
			}
		}
		
		// catch the table header, and set for sorting
		
		var thead = getElement("tabletop");
		var tempThead = thead.cloneNode(true);
		
		var headers = tempThead.getElementsByTagName("div");
		for (var i=0; i<headers.length; ++i) {
			var header = headers[i];
			var attr = getAttribute(header, "mochi:sortcolumn");
			if (attr) {
				var sortinfo = attr.split(" ");
				var sortkey = sortinfo[0];
				header.onclick = this.onSortClick(sortkey);
			}		
		}
		swapDOM(thead, tempThead);
			
		
		this.sortkey = "overall";
		this.sortStyle = "str";
		this.loadFromURL(this.scriptName, {divID: this.defaultDivId});
	},
	
	"loadFromURL": function(url, vars) {
		log("loadFromURL", url, vars.divID);
		var d;
		if (this.deferred) {
			this.deferred.cancel();
		}
		
		this.displayLoading();
		
		d = loadJSONDoc(url, vars);
		
		this.deferred = d;
		var self = this;
		
		d.addBoth(function (res) {
			self.deferred = null;
			log('loadFromURL success');
			return res;
		});
		
		d.addCallback(this.initWithData);
		
		d.addErrback(function(err) {
			if (err instanceof CancelledError) {
				return;
			}
			
			logError(err);
		});
		return d;
	},
	
	"initWithData": function(data) {
		log("initWithData", data);
		// store data for later
		// go thru the data, and replace the atk def ovr with normalised versions
		var normAtk = 0;
		var normDef = 0;
		var normOvr = 0;
		
		log ("MAX", data.bounds.maxAtk, data.bounds.minDef, data.bounds.maxOvr);
		for (var i=0; i<data.rankings.length; ++i) {
			normAtk = 100 * (data.rankings[i].atk / data.bounds.maxAtk);
			normDef = 100 * (data.bounds.minDef / data.rankings[i].def);
			normOvr = 100 * (data.rankings[i].overall / data.bounds.maxOvr);
			
			data.rankings[i].atk = normAtk;
			data.rankings[i].def = normDef;
			data.rankings[i].overall = normOvr;
			
			log (data.rankings[i].name, normAtk, normDef, normOvr);
		}
		
		this.data = data;
		
		// sort
		var order = this.sortState[this.sortkey];
		if (typeof(order) == 'undefined') {
			order = false;
		}
		
		
		// display the rows
		this.displaySortedRows(this.sortkey, order, false);
	},
	
	"onSortClick": function(name) {
		var self = this;
		
		return function () {
			log('onSortClick', name);
			var order = self.sortState[name];
			if (typeof(order) == 'undefined') {
				order = true;
			} else if (self.sortkey == name) {
				order = !((typeof(order) == 'undefined')? false : order);
			}
			self.displaySortedRows(name, order, true);
		}
	},
		
	"displayRows": function () {
		log("displayRows");
		for (var i=0; i<this.templates.length; ++i) {
			var template = this.templates[i];
			log('template', i, template);
			var dom = template.template.cloneNode(true);
			processMochiTAL(dom, this.data);
			template.node = swapDOM(template.node, dom);
		}
	},
	
	"displaySortedRows": function (key, forward, clicked) {
		log("displaySortedRows", key, forward, clicked);
		
		this.sortState[key] = forward;
		this.sortkey = key;
		var sortstyle;
		
		// sort out the sort columns
		
		// apply sort transform to imaginary column
		// then do the sort
		if(!sortstyle) {
			sortstyle = "str";
		}
		
		var sortfunc = SortTransforms[sortstyle];
		if (!sortfunc) {
			throw new TypeError("unsupported sort style" + repr(sortstyle));
		}
		
		var games = this.data.rankings;
		for (var i=0; i<games.length; ++i) {
			var game = games[i];
			game.__sort__ = sortfunc(game[key]);
		}
		
		// now do the sort
		var cmp = (forward? keyComparator: reverseKeyComparator);
		games.sort(cmp("__sort__"));
		
		for (var i=0; i<this.templates.length; ++i) {
			var template = this.templates[i];
			log('template', i, template);
			var dom = template.template.cloneNode(true);
			processMochiTAL(dom, this.data);
			template.node = swapDOM(template.node, dom);
		}
	},
	
	"displayLoading": function() {
		log("Display loading text");
		
		for (var i=0; i<this.templates.length; ++i) {
			var template = this.templates[i];
			log('template', i, template);
			var dom = template.template.cloneNode(true);
			processMochiTAL(dom, this.loadingData);
			template.node = swapDOM(template.node, dom);
		}		
	}

};

gameManager = new GameManager();
addLoadEvent(gameManager.initialize);

