//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.id");
	}
	
	// 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;
	}
};

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/GetSeasonOverview.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});
		}
				
		// catch the links to load different divisions
		var anchors = getElementsByTagAndClassName("a",null);
		
		for (var i=0; i<anchors.length; ++i) {
			var node = anchors[i];
			
			var division = getAttribute(node, "mochi:division");
			
			if (division) {
				node.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 = "expPts";
		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
		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);
//		this.displayRows();
	},
	
	"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.overview;
		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);

