var ChessTournament = Class.create();
Object.extend(ChessTournament.prototype, {
	isteam: 0,
	boards: 8,
	points: '0,1,2',
	players: [],
	player_results: [],
	rounds: 0,
	roundsInfo: [],
	roundsOrder: '',
	sortParam: null,
	updateUrl: '',
	autostart: false,
	noresults: 0,
	todayDate: '??',

	initialize: function(props) {
		Object.extend(this, props || {});
		if (!this.sortParam) {
			if (this.isteam) this.sortParam = 'total,points,-num';
			else this.sortParam = 'total,sb,rp,-num';
		}
		if (this.autostart && this.mainID) {
			$(this.mainID).innerHTML = this.mainTpl.evaluate(this.stepTable());
			this.setHooks(this.mainID);
		}
	},
	
	refresh: function() {
		this._playersInfo = null;
		$(this.mainID).innerHTML = this.mainTpl.evaluate(this.stepTable());
	},

	stepTable: function() {
//		if (this._stepTable) return this._stepTable;
		this.processPlayers();
		var players = [];
		for(var i in this._playersInfo) players.push(this._playersInfo[i]);
		var arr = this.sortParam.split(',');
		var arr2 = [];
		for(var i = 0; i < arr.length; i++) {
			if(arr[i].substr(0,1) == '-') arr2.push('(a.'+arr[i].substr(1)+'-b.'+arr[i].substr(1)+')');
			else arr2.push('(b.'+arr[i]+'-a.'+arr[i]+')');
		}
		var func = new Function('a', 'b', 'return ('+arr2.join('||')+')');
		players.sort(func);
		//if (this.isteam) function(a,b) {return ((b.total - a.total) || (b.points - a.points) || (a.num - b.num));});
		//else players.sort(function(a,b) {return ((b.total - a.total) || (b.sb - a.sb) || (b.rp - a.rp) || (a.num - b.num));});
		for(var j = 0; j < this.players.length; j++) {
			players[j].rank = j + 1;
		}
		this._stepTable = {players: players, roundsInfo: this.roundsInfo};
		return this._stepTable;
	},
	
	playerInfo: function(num) {
		this.processPlayers();
		return this.infoPlayerTpl.evaluate(this._playersInfo[num]);
	},
	
	roundInfo: function(num) {
		this.processPlayers();
		return this.roundInfoTpl.evaluate(this._roundsInfo[num]);
	},
	
	resultInfo: function(num) {
		this.processPlayers();
		var a = num.split('_');
		return this.infoResultTpl.evaluate(this._playersInfo[a[1]].rounds[a[0]-1]);
	},
	
	changeOrderOfRounds: function() {
		if (this._orderOfRoundsChanged) return;
		this._orderOfRoundsChanged = true;
		if (!this.roundsOrder) return;
		var roundsOrder2 = this.roundsOrder.split(',');
		var roundsOrder = [];
		if (roundsOrder2.length != this.rounds) return;
		for(var j = 0; j < this.rounds; j++) {
			var i = j + 1;
			roundsOrder[i] = parseInt(roundsOrder2[j]);
			if (roundsOrder[i] < 1 || roundsOrder[i] > this.rounds) roundsOrder[i] = i;
		}
		for(var i = 0; i < this.player_results.length; i++) {
			var r = this.player_results[i];
			r.dbround = r.round;
			r.round = roundsOrder[r.round];
		}
	},
	
	processPlayers: function() {
		if (this._playersInfo) return;
		this.changeOrderOfRounds();
		var players = {};
		var rounds = {};
		var points = this.points.split(',');
		for(var j = 0; j < points.length; j++) points[j] = parseInt(points[j]);
		for(var j = 0; j < this.roundsInfo.length; j++) {
			this.roundsInfo[j].istoday = (this.roundsInfo[j].date == this.todayDate);
			rounds[this.roundsInfo[j].number] = {boards:[], info:this.roundsInfo[j]};
		}
		for(var i = 0; i < this.players.length; i++) {
			var num = this.players[i].number;
			players[num] = {rounds:[], points:0, total:0, sb:0, wins:0, games:0, avgRating:0, num:num, total2:0, points2:0};
			Object.extend(players[num], this.players[i]);
			for(var j = 0; j < this.rounds; j++) {
				players[num].rounds[j] = {};
			}
		}
		for(var i = 0; i < this.player_results.length; i++) {
			var r = this.player_results[i];
			if (this.noresults) {
				r.result = '';
				r.result1 = '';
				r.result2 = '';
			}
			if (!r.dbround) r.dbround = r.round;
			if (this.player_results2[r.dbround+'_'+r.player1+'_'+r.player2]) Object.extend(r, this.player_results2[r.dbround+'_'+r.player1+'_'+r.player2]);
			rounds[r.round].boards.push(Object.extend(r, {player1Info: players[r.player1], player2Info: players[r.player2]}));
			var result1 = parseFloat(r.result1);
			var result2 = parseFloat(r.result2);
			var points1 = (result1 == result2 ? points[1] : (result1 > result2 ? points[2] : points[0]));
			var points2 = (result1 == result2 ? points[1] : (result1 < result2 ? points[2] : points[0]));
			players[r.player1].rounds[r.round - 1] = {player: r.player2, playerInfo: players[r.player2], result:r.result1, points:points1, white:true, number: r.round};
			players[r.player2].rounds[r.round - 1] = {player: r.player1, playerInfo: players[r.player1], result:r.result2, points:points2, white:false, number: r.round};
			if (r.result1) players[r.player1].total += result1;
			if (r.result2) players[r.player2].total += result2;
			if (r.result) {
				players[r.player1].games++;
				players[r.player1].avgRating += parseInt(players[r.player2].rating);
				players[r.player2].games++;
				players[r.player2].avgRating += parseInt(players[r.player1].rating);
				players[r.player1].points += points1;
				players[r.player2].points += points2;
				if (result1 > result2) players[r.player1].wins++;
				if (result1 < result2) players[r.player2].wins++;
			}
		}
		for(var i in players) {
			for(var j = 0; j < players[i].rounds.length; j++) {
				if (players[i].rounds[j].player) {
					players[i].sb += players[i].rounds[j].result * players[players[i].rounds[j].player].total;
					if (players[players[i].rounds[j].player].total == players[i].total) {
						players[i].total2 += players[i].rounds[j].result;
						players[i].points2 += players[i].rounds[j].points;
					}
				}
			}
			players[i].rp = countRp(players[i].games, players[i].avgRating, players[i].total);
			players[i].diffRating = (new Number(countdiffElo(players[i].games, players[i].avgRating, players[i].total, players[i].rating))).toFixed(2);
			players[i].sb = (new Number(players[i].sb)).toFixed(2);
		}
		this._playersInfo = players;
		this._roundsInfo = rounds;
		return;
	},
	
	setHooks: function(div) {
		$(div).onmouseover = this.onmouseover.bindAsEventListener(this);
		$(div).onmouseout = this.onmouseout.bindAsEventListener(this);
		$(div).onmousemove = this.onmousemove.bindAsEventListener(this);
		$(div).onclick = this.onmouseclick.bindAsEventListener(this);
	},
	
	onmouseclick: function(e) {
		if (!this.updateUrl) return;
		var id = Event.element(e).id;
		var match = id.match(/^_info_(result|player|rating)_([_\d]+)$/);
		if (!match) return;
		var props = Object.extend({}, this.updateParam);
		if (match[1] == 'result') {
			var options = [];
			var boards = this.isteam ? this.boards : 1;
			for(var i=0; i<boards; i++) {
				options.push((boards-i)+'-'+i);
				options.push((boards-i-0.5)+'-'+(i+.5));
			}
			options.push('0-'+boards);
			options.push('?-?');
			var options2 = [];
			for(var i = 0; i < options.length; i++) options2.push({text:options[i]});
			this._selectBox = this.showToolTip(e, this._selectBox, this.selectBoxTpl.evaluate({options:options2, id:match[2]}));
			var that = this;
			this._selectBox.onclick = (function(e) {
				if (Event.element(e).id == '_selectBox_close') that._selectBox.hide();
				if (Event.element(e).tagName.toLowerCase() != 'a') return false;
				new Updater(that.updateUrl, Object.extend(props, {resultid: match[2], roundsOrder:that.roundsOrder, result:Event.element(e).innerHTML}), {
					onOK: function(response) {
						that._selectBox.hide();
						if (!that.player_results2) that.player_results2 = {};
						that.player_results2[response.id] = response.value;
						that.refresh();
					}
				});
				return false;
			}).bindAsEventListener();
		}
		if (match[1] == 'player' || match[1] == 'rating') {
			var prop = match[1] == 'player' ? 'name' : match[1];
			this._playerUpdate = this.showToolTip(e, this._playerUpdate, this.playerUpdateTpl.evaluate({value:this._playersInfo[match[2]][prop]}));
			var that = this;
			this._playerUpdate.onclick = (function(e) {
				var el = Event.element(e);
				if (el.id == '_playerUpdate_close') that._playerUpdate.hide();
				if (el.tagName.toLowerCase() != 'input' || el.type.toLowerCase() != 'button') return false;
				var newValue = el.form.elements['name'].value;
				new Updater(that.updateUrl, Object.extend(props, {playerid: match[2], prop: prop, newvalue:newValue}), {
					onOK: function(response) {
						that._playerUpdate.hide();
						$(id).innerHTML = newValue;
						for(var i = 0; i < that.players.length; i++) {
							if(that.players[i].number == match[2]) {
								that.players[i][prop] = newValue;
							}
						}
					}
				});
				return false;
			}).bindAsEventListener();
		}
	},
	onmouseover: function(e) {
		var match = Event.element(e).id.match(/^_info_(player|round|result)_([_\d]+)$/);
		if (!match) return;
		this._tooltip = this.showToolTip(e, this._tooltip, this[match[1]+'Info'](match[2]));
	},
	
	onmousemove: function(e) {
		if (!Event.element(e).id.match(/^_info_(player|round|result)_([_\d]+)$/)) return;
		if (this._tooltip) this.moveToolTip(e, this._tooltip);
	},
	onmouseout: function(e) {
		if (!Event.element(e).id.match(/^_info_(player|round|result)_([_\d]+)$/)) return;
		this.hideToolTip(this._tooltip);
	},
	
	showToolTip: function(e, div, html) {
		if (!div) {
			div = $(document.createElement('div'));
			Element.setStyle(div, { position:'absolute'});
			div.className = "tooltip";
			document.body.appendChild(div);
		}
		//alert(e.pointerX);
		this.moveToolTip(e, div);
		div.innerHTML = html;
		div.show();
		return div;
	},
	
	moveToolTip: function(e, div) {
		Element.setStyle(div, {
//			position:'absolute',
			left:Event.pointerX(e)+20+"px",
			top:Event.pointerY(e)+10+"px"
		});
	},

	hideToolTip: function(div) {
		if (div) div.hide();
	}
	
});
	