//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;
		}
		
		if (lst.length == 0) {
			var newDOM = dom.cloneNode(true);
			processMochiTAL(newDOM, null);
			parent.insertBefore(newDOM, dom);
			
		}
		
		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) {
		dom.removeAttribute("mochi:content");
		var dataValue = valueForKeyPath(data, attr);
		if (dataValue == null)
			dataValue = getAttribute(dom, "mochi:default");
			
		replaceChildNodes(dom, dataValue);
		return;
	}
	
	attr = getAttribute(dom, "mochi:formattedContent");
	if (attr) {
		dom.removeAttribute("mochi:formattedContent");
		var format = getAttribute(dom, "mochi:format");
		if (format) {
			var dataValue = valueForKeyPath(data, attr);
			if (dataValue == null) {
				dataValue = getAttribute(dom, "mochi:default");
				replaceChildNodes(dom, 	dataValue);
			} else {				
				replaceChildNodes(dom, 	numberFormatter(format)(dataValue));
			}
		} else {
			var dataValue = valueForKeyPath(data, attr);
			if (dataValue == null) {
				dataValue = getAttribute(dom, "mochi:default");
				replaceChildNodes(dom, 	dataValue);
			} else {
				replaceChildNodes(dom, 	numberFormatter("#%")(dataValue));
			}
		}		
		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);
	}	
};

convertEnglishAndAmerican = function(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;
};

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

	}

};

toggleTeamVisibility = function (ev) {
	ignoreEvent(ev);
	
	var hiddenLinks = getElementsByTagAndClassName(null, "submenu2");
	var myListID = getAttribute(this, "mochi:listID");
	
	for (var i=0; i<hiddenLinks.length; ++i) {
		if(getAttribute(hiddenLinks[i], "mochi:listID") == myListID) {
			// now toggel the attribute...
			var vis = hiddenLinks[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(hiddenLinks[i], {"display": "none"});
		}
	}	
};

selectTeamAndSimulate = function (ev) {
	ignoreEvent(ev);
	
	var teamID = getAttribute(this, "mochi:teamID");
	var teamName = getAttribute(this, "mochi:teamName");

	if (teamID) {
		// hide this panel now
		closeTeamPanels();

		// and simulate the game

		//simManager.simulateGivenGame();
		gameManager.loadFromURL(gameManager.scriptName, {teamID: teamID});
	}

};

closeTeamPanels = function() {
	var hiddenLinks = getElementsByTagAndClassName(null, "submenu2h");

	for (var i=0; i<hiddenLinks.length; ++i) {
		setStyle(hiddenLinks[i], {"display": "none"});
	}

	var hiddenLinks = getElementsByTagAndClassName(null, "submenu2");

	for (var i=0; i<hiddenLinks.length; ++i) {
		setStyle(hiddenLinks[i], {"display": "none"});
	}

};


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

valueForKeyPath = function (data, keyPath) {
	var chunks = keyPath.split(".");
	var curChunk = null;
	while (chunks.length && data) {
		curChunk = chunks.shift();
		data = data[curChunk];
	}
	
	if (compare(curChunk, "Date") == 0) {
		data = convertEnglishAndAmerican(data);	
		if (data == "01/01/1999") {
			data = "POSTPONED";
		}
	}
	return data;
};

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


GameManager = function() {
	this.defaultTeamId = 6;
	this.templates = [];
	this.deferred = null;
	this.data = null;
	this.loadingData = null;
	this.scriptName = "/cgi-bin/GetSeasonEnd.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 find the mochi-list links
		var teamLinks = getElementsByTagAndClassName(null, "mochi-visList");
		
		for (var i=0; i<teamLinks.length; ++i) {
			var listID = getAttribute(teamLinks[i], "mochi:listID");
			if (listID) {
				teamLinks[i].onclick = toggleTeamVisibility;
			}			
		}

		// go through and get the team links
		var links = getElementsByTagAndClassName("a", null);
		
		for (var i=0; i<links.length; ++i) {
			var teamID = getAttribute(links[i], "mochi:teamID");
			
			if (teamID) {
				links[i].onclick = selectTeamAndSimulate;
			}				
		}
		
		// catch the table header, and set for sorting
		
		var thead = getElementsByTagAndClassName(null, "tabletop");
		for (var j=0; j<thead.length; ++j) {
			log("in tabletop", j);
			var tempThead = thead[j].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 sortStyle = sortinfo[1];
					header.onclick = this.onSortClick(sortkey, sortStyle, getAttribute(header, "mochi:sortTable"));
				}		
			}
			swapDOM(thead[j], tempThead);
		}

		if (PHP_getID != -1) {
			this.teamID = PHP_getID;
		} else
			this.teamID = this.defaultTeamId;

		
		this.sortkey = "Date";
		this.sortStyle = "isoDate";
		this.loadFromURL(this.scriptName, {teamID: this.teamID});
	},
	
	"loadFromURL": function(url, vars) {
		log("loadFromURL", url, vars.teamID);
		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;
		
		// get the total expected points (ie, exp + curr)
		this.data.totalExpPnts = this.data.ExpectedPoints + this.data.CurrentPoints;
		
		log("total Exp Pnts", this.data.totalExpPnts);
		// convert date to american for sorting
		for (var i=0; i<this.data.UpComingGames.length; ++i) {
			var tempDate = this.data.UpComingGames[i].Date;
			
			tempDate = convertEnglishAndAmerican(tempDate);
			this.data.UpComingGames[i].Date = tempDate;
		}
		
		// sort
		var order = this.sortState[this.sortkey];
		if (typeof(order) == 'undefined') {
			order = true;
		}
		
		
		// display the rows
		this.displaySortedRows(this.sortkey, order, false, this.sortStyle, this.data.UpComingGames);
//		this.displayRows();
	},
	
	"onSortClick": function(name, sortStyle, sortTable) {
		var self = this;
		
		return function () {
			log('onSortClick', name, sortStyle, sortTable);
			evalSortTable = eval("self.data." + sortTable);
			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, sortStyle, evalSortTable);
		}
	},
		
	"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, sortstyle, subTable) {
		log("displaySortedRows", key, forward, clicked, sortstyle, subTable);
		
		this.sortState[key] = forward;
		this.sortkey = key;
				
		// 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 = subTable;
		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];
			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);

