//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(" ");
		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];
			
			if (valueForKeyPath(data, "item.round") == gameManager.selectedStage) {
				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) {
		dom.removeAttribute("mochi:content");
		replaceChildNodes(dom, valueForKeyPath(data, attr));
		return;
	}
	
	attr = getAttribute(dom, "mochi:formattedContent");
	if (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")
			 + "&" + "hty" + "=" + 0
			  + "&" + "aty" + "=" + 0
			  + "&" + "neu" + "=" + valueForKeyPath(data, "item.neutral");
	}
	
	// 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;
	}
};

loadFromStageAnchor = function(ev) {
	ignoreEvent(ev);
	var stageID = this.getAttribute("mochi:stage");
	gameManager.selectedStage = stageID;
	
	gameManager.displayRows();
	// 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:stage");
	
	
	//and set this one
	//this.setAttribute("style", "color:#000000;background-color:#f1f30a;");
	setElementClass(this, "chosenListItem");
};

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});
			removeElementClass(node, "chosenListItem");
		}
	}
};

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;
};

convertEnglishAndAmerican = function(engDate) {
	log ("conv", engDate);
	var amDate = '';
	// format is DD/MM/YYYY
	// we want MM/DD/YYYY
	if (engDate == "POSTPONED")
		engDate=("01/01/1999");
		
	// first change the '-' to '/'
	tempArr = engDate.split("-");
	engDate = "";
	
	for (var i=0; i<tempArr.length - 1; ++i)
		engDate = engDate + tempArr[i] + "/";
	
	engDate = engDate + tempArr[tempArr.length - 1];
	
	// now split and americanify
		
	tempArr = engDate.split("/");
	amDate = tempArr[1] + "/" + tempArr[0] + "/" + tempArr[2];
	return amDate;
};

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

GameManager = function() {
	this.defaultDivId = 0;
	this.templates = [];
	this.deferred = null;
	this.data = null;
	this.loadingData = null;
	this.scriptName = "/cgi-bin/facup/GetKnockout_facup.pl";
	this.sortState = {};
	this.selectedStage = "R3";
	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});
		}
				
		// catch the links to select the type of match
		var anchors = getElementsByTagAndClassName("a",null);
		
		for (var i=0; i<anchors.length; ++i) {
			var node = anchors[i];
			
			var stage = getAttribute(node, "mochi:stage");
			
			if (stage) {
				node.onclick = loadFromStageAnchor;
			}
			
		}
		
		// 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];
				var mySortStyle = sortinfo[1];
				header.onclick = this.onSortClick(sortkey,mySortStyle);
			}		
		}
		swapDOM(thead, tempThead);
		
		this.sortkey = "number";
		this.sortStyle = "num";
		this.sortState["number"] = true;
		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
		this.data = data;
		
		// sort loading data
		var order = this.sortState[this.sortkey];
		if (typeof(order) == 'undefined') {
			order = true;
		}
		
		// display the rows
		this.displaySortedRows(this.sortkey, order, false);
	},
	
	"onSortClick": function(name, style) {
		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);
			}
			gameManager.sortStyle = style;
			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.sortStyle);
		
		this.sortState[key] = forward;
		this.sortkey = key;
		
		// sort out the sort columns
		
		// apply sort transform to imaginary column
		// then do the sort
		if(!this.sortStyle) {
			this.sortStyle = "str";
		}
		
		var sortfunc = SortTransforms[this.sortStyle];
		if (!sortfunc) {
			throw new TypeError("unsupported sort style" + repr(this.sortStyle));
		}
		var countries = this.data.games;
		for (var i=0; i<countries.length; ++i) {
			var country = countries[i];
			if (this.sortStyle=="isoDate")
				country.__sort__ = sortfunc(convertEnglishAndAmerican(country[key]));
			else
				country.__sort__ = sortfunc(country[key]);
		}
		// now do the sort
		var cmp = (forward? keyComparator: reverseKeyComparator);
		countries.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);

