var PlayerClass = Class.extend({
	init : function(name) {
		this.name = name;
	},
	setName : function(name) {
		this.name = name;
	},
	getName : function () {
		return this.name;
	}
});

var TeamClass = Class.extend({
	init : function (name) {
		this.name = name;
	},
	setName : function(name) {
		this.name = name;
	},
	getName : function() {
		return this.name;
	},
	setHomepage : function(homepage) {
		this.homepage = homepage;
	},
	getHomepage : function() {
		return this.homepage;
	}
});

var SoccerFieldClass = Class.extend({
	init : function (name) {
		this.name = name;
	},
	setName : function(name) {
		this.name = name;
	},
	getName : function() {
		return this.name;
	},
	setMapsLink : function(link) {
		this.link = link;
	},
	getMapsLink : function() {
		return this.link;
	}
});

var AppointmentClass = Class.extend({
	init : function() {
	},
	setDate : function(date) {
		this.date = date;
	},
	getDate : function() {
		return this.date;
	}
});

var TrainingClass = AppointmentClass.extend({
	init : function() {
	}
});

var MatchClass = AppointmentClass.extend({
	init : function () {
	},
	setHome : function(home) {
		this.home = home;
	},
	getHome : function() {
		return this.home;
	},
	setGuest : function(guest) {
		this.guest = guest;
	},
	getGuest : function() {
		return this.guest;
	},
	setSoccerField : function(soccerfield) {
		this.soccerfield = soccerfield
	},
	getSoccerField : function() {
		return this.soccerfield;
	},
	setResult: function(result) {
		this.result = result;
	},
	getResult: function() {
		return this.result;
	},
	setParticipants : function(participants) {
		this.participants = participants;
	},
	getParticipants : function() {
		return this.participants;
	},
	setGoalScorers : function(goalscorers) {
		this.goalscorers = goalscorers;
	},
	getGoalScorers : function() {
		return this.goalscorers;
	},
	setComment : function(comment) {
		this.comment = comment;
	},
	getComment : function() {
		return this.comment;
	},
	
	////////////////
	// do not modify, will be set automatically by MatchTournamentAssociator
	setTournament : function(tournament) {
		this.tournament = tournament;
	},
	getTournament : function() {
		return this.tournament;
	}
});

var TournamentClass = Class.extend({
	init : function( name ) {
		this.name = name;
	},
	addMatch : function(match) {
		throw "Not implemented";
	},
	getMatches : function() {
		throw "Not implemented";
	}
});

var LeagueClass = TournamentClass.extend({
	init : function( name ){
		this._super(name);
		this.matches = [];
	},
	addMatch : function ( match ) {
		this.matches.push(match);
	},
	getMatches : function () {
		return this.matches;
	}
});

var ExhibitionMatchesClass = TournamentClass.extend({
	init : function( name ){
		this._super(name);
		this.matches = [];
	},
	addMatch : function ( match ) {
		this.matches.push(match);
	},
	getMatches : function () {
		return this.matches;
	}
});

var SeasonClass = Class.extend({
	init : function() {
		this.tournamentlist = [];
	},
	addTournament : function(tournament) {
		this.tournamentlist.push(tournament);
	},
	getTournaments : function() {
		return this.tournamentlist;
	}
});

var SoccerIsEverythingClass = Class.extend({
	init : function() {
		this.seasonlist = [];
	},
	addSeason : function(season) {
		this.seasonlist.push(season);
	},
	getSeasons : function() {
		return this.seasonlist;
	},
	setCurrentSeason : function(season) {
		this.season = season;
	},
	getCurrentSeason : function() {
		return this.season;
	}
});

/////////////////////////////////////////////////////////////////////////////////
var MatchTournamentAssociatorClass = Class.extend({
	init: function() {
	},
	associate : function(where) {
		var stack = [where];
		var currentTournament = null;
		while (stack.length != 0) {
			where = stack.pop();
			if (where instanceof MatchClass) 
			{
				if (where.getTournament()) {
					throw "Match already has a tournament";
				}
				else if (!currentTournament) {
					throw "InvalidArgument";
				}
				where.setTournament(currentTournament);
			}
			else if (where instanceof Array) {
				for (var i=0;i<where.length;++i) {
					stack.push(where[i]);
				}
			}
			else if (where instanceof TournamentClass) {
				currentTournament = where;
				stack.push(where.getMatches());
			}
			else if (where instanceof SeasonClass) {
				stack.push(where.getTournaments());
			}
			else if (where instanceof SoccerIsEverythingClass) {
				stack.push(where.getSeasons());
			}
			else {
				throw "InvalidArgument";
			}
		}
	}
});

var TrainingGeneratorClass = Class.extend({
	init : function() {
		this.date = new Date();
	},
	getNextTraining : function(ignore, date) {
		if (!date) {
			date = this.date;
		}
		
		// a random training day
		var training = new Date(2011, Month.JUL, 4, 20, 30, 0);
		for (;;) {
			if (training.valueOf() > date.valueOf()) {
				var gooddate = true;
				if (ignore) {
					for (var i=0;i<ignore.length;++i) {
						if (training.getDate() == ignore[i].getDate()
							&& training.getMonth() == ignore[i].getMonth()
							&& training.getFullYear() == ignore[i].getFullYear())
						{
							gooddate = false;
							break;
						}
					}
				}
				
				if (gooddate) {
					break;
				}
			}
			training.setDate(training.getDate() + 7);
		}
		
		var trainingObj = new TrainingClass();
		trainingObj.setDate(training);
		return trainingObj;
	}
});

var DuplicateCheckerClass = Class.extend({
	init : function (enabled) {
		this.enabled = enabled;
	},
	checkForDuplicates : function( array ) {
		if (this.enabled) {
			for (var i=1;i<array.length;++i) {
				for (var j=0; j<i;++j) {
					if (array[i] === array[j]) {
						throw "Found duplicate";
					}
				}
			}
		}
	}
});

var PlayerFinderClass = Class.extend({
	findPlayers : function(where) {
		var stack = [where];
		var players = [];
		while (stack.length != 0) {
			where = stack.pop();
			if (where instanceof MatchClass) 
			{
				var participants = where.getParticipants();
				if (participants) {
					for (var i=0;i<participants.length;++i)
					{
						var foundPlayer = false;
						for (var j=0;j<players.length;++j) {
							if (players[j] === participants[i]) {
								foundPlayer = true;
								break;
							}
						}
				
						if (!foundPlayer) {
							players.push(participants[i]);
						}
					}
				}
				
				var goalscorer = where.getGoalScorers();
				if (goalscorer) {
					for (var i=0;i<goalscorer.length;++i)
					{
						var foundPlayer = false;
						for (var j=0;j<players.length;++j) {
							if (players[j] === goalscorer[i]) {
								foundPlayer = true;
								break;
							}
						}
				
						if (!foundPlayer) {
							players.push(goalscorer[i]);
							// TODO: goalscorer was not participant
						}
					}
				}
			}
			else if (where instanceof Array) {
				for (var i=0;i<where.length;++i) {
					stack.push(where[i]);
				}
			}
			else if (where instanceof TournamentClass) {
				stack.push(where.getMatches());
			}
			else if (where instanceof SeasonClass) {
				stack.push(where.getTournaments());
			}
			else if (where instanceof SoccerIsEverythingClass) {
				stack.push(where.getSeasons());
			}
			else {
				throw "InvalidArgument";
			}
		}
		return players;
	}
});

var MatchFinderClass = Class.extend({
	findMatches : function(where) {
		var stack = [where];
		var matches = [];
		while (stack.length != 0) {
			where = stack.pop();
			if (where instanceof MatchClass) 
			{
				matches.push(where);
			}
			else if (where instanceof Array) {
				for (var i=0;i<where.length;++i) {
					stack.push(where[i]);
				}
			}
			else if (where instanceof TournamentClass) {
				stack.push(where.getMatches());
			}
			else if (where instanceof SeasonClass) {
				stack.push(where.getTournaments());
			}
			else if (where instanceof SoccerIsEverythingClass) {
				stack.push(where.getSeasons());
			}
			else {
				throw "InvalidArgument";
			}
		}
		return matches;
	}
});

var StatisticsGrapperClass = Class.extend({
	grapGoals : function( where, player, playerScore) {
		var count = 0;
		if (where instanceof MatchClass && player instanceof PlayerClass) {
			var goalscorers = where.getGoalScorers();
			if (goalscorers) {
				for (var i=0;i< goalscorers.length; ++i) {
					if (goalscorers[i] === player) {
						++count;
					}			
				}
			}
		}
		else if (player instanceof Array) {
			DuplicateChecker.checkForDuplicates(player);
			for (var i=0;i<player.length;++i) {
				var goals = this.grapGoals(where, player[i], playerScore);
				if (playerScore) {
					if (playerScore.length == i) {
						playerScore.push({player : player[i], goals : goals});
					}
					else {
						playerScore[i] = {player : player[i], goals : goals};
					}
				}
				count += goals;
			}
		}
		else if (where instanceof Array) {
			DuplicateChecker.checkForDuplicates(where);
			for (var i=0;i<where.length;++i) {
				count += this.grapGoals(where[i], player, playerScore);
			}
		}
		else if (where instanceof TournamentClass) {
			count += this.grapGoals(where.getMatches(), player, playerScore);
		}
		else if (where instanceof SeasonClass) {
			count += this.grapGoals(where.getTournaments(), player, playerScore);
		}
		else if (where instanceof SoccerIsEverythingClass) {
			count += this.grapGoals(where.getSeasons(), player, playerScore);
		}
		else {
			throw "InvalidArgument";
		}
		return count;
	},
	grapDeployments : function( where, player, playerScore) {
		var count = 0;
		if (where instanceof MatchClass && player instanceof PlayerClass) {
			var participants = where.getParticipants();
			if (participants) {
				DuplicateChecker.checkForDuplicates(participants);
				for (var i=0;i< participants.length; ++i) {
					if (participants[i] === player) {
						++count;
						break;
					}			
				}
			}
		}
		else if (player instanceof Array) {
			DuplicateChecker.checkForDuplicates(player);
			for (var i=0;i<player.length;++i) {
				var deployments = this.grapDeployments(where, player[i], playerScore);
				if (playerScore) {
					if (playerScore.length == i) {
						playerScore.push({player : player[i], deployments : deployments});
					}
					else {
						playerScore[i] = {player : player[i], deployments : deployments};
					}
				}
				count += deployments;
			}
		}
		else if (where instanceof Array) {
			DuplicateChecker.checkForDuplicates(where);
			for (var i=0;i<where.length;++i) {
				count += this.grapDeployments(where[i], player, playerScore);
			}
		}
		else if (where instanceof TournamentClass) {
			count += this.grapDeployments(where.getMatches(), player, playerScore);
		}
		else if (where instanceof SeasonClass) {
			count += this.grapDeployments(where.getTournaments(), player, playerScore);
		}
		else if (where instanceof SoccerIsEverythingClass) {
			count += this.grapDeployments(where.getSeasons(), player, playerScore);
		}
		else {
			throw "InvalidArgument";
		}
		return count;
	}
});

var DateConverterClass = Class.extend({
	init : function() {
	},
	getShortDate : function(date) {
		var year = (date.getFullYear() % 100);
		if (year < 10) {
			year = "0" + year;
		}
		return date.getDate() + "." + (date.getMonth() + 1) + "." + year;
	},
	getShortDateTime : function(date) {
		var year = (date.getFullYear() % 100);
		if (year < 10) {
			year = "0" + year;
		}
		var minutes = date.getMinutes();
		if (minutes < 10) {
			minutes = "0" + minutes;
		}
		return date.getDate() + "." + (date.getMonth() + 1) + "." + year 
				+ " " + date.getHours() + ":" + minutes;
	}
});

