function controller(id,p1,p2,pl){
	this.obj = document.getElementById(id);
	$(this.obj).empty();
	this.player1=p1;
	this.player2=p2;
	this.playlist=pl;
	this.enableNext = false;
	
	this.currentPlayer = null; 
	this.nextPlayer = null; // qed
	
	$(this.obj).append('<input type="button" value="Play Next Track" id="nextbutton" disabled="true" />');
	$(this.obj).append('<div id="statusbar">Controller Status: <span id="controller_status">Initialising...</span></div>');
	
	$("#nextbutton").bind('click',this,function(e){
		e.data.playNext();
	});
	
};

controller.prototype.playNext = function(){
	// fade from the current player to the next player
	//this.setStatus('Nextbutton clicked');
	if(dj_mixer){

		if (this.discoverCurrentPlayer()){

			// start fading
			var varto = null;
			if (this.nextPlayer.id == "p1") varto = '0';
			else if (this.nextPlayer.id == "p2") varto = '100';
			
			if (varto){
				
				this.nextPlayer.playVideo();
				
				// set the crossfader in the middle
				dj_mixer.setCrossFader(50);
				var self = this;
				dj_mixer.smoothFade(varto, function(){ self.currentPlayer.ejectVideo(); });	
			}

		}
	
	}
	return false;
};

controller.prototype.discoverCurrentPlayer = function(){
	 //looks at both players, discovers which one's duration is most finished, and
	//  returns a reference to that player while also setting the class parameter this.currentPlayer.
	// NOTE: we assume the current player to be the one which has played the biggest percentage
	//   of it's currently loaded video.
	
	if (this.player1 && this.player2){	
		
		var p1pc = this.player1.getPercentagePlayed();
		this.setStatus('Player 1 percent played: '+p1pc);
		var p2pc = this.player2.getPercentagePlayed();
		this.setStatus('Player 2 percent played: '+p2pc);
		
		if (p1pc > p2pc) {
			this.currentPlayer = this.player1;
			this.nextPlayer = this.player2;
		}else if (p2pc > p1pc) {
			this.currentPlayer = this.player2;
			this.nextPlayer = this.player1;
		}
		
		
		if (this.currentPlayer && this.nextPlayer){
			this.setStatus('Current player is: '+this.currentPlayer.id);
			this.setStatus('Next player is: '+this.nextPlayer.id);
			return true;
		}
		
	
	}
	return false;
};



controller.prototype.enableNextButton = function(){
	$('#nextbutton').attr('disabled', false);
	this.enableNext = true;
};
controller.prototype.disableNextButton = function(){
	$('#nextbutton').attr('disabled', true);
	this.enableNext = false;
};
controller.prototype.setStatus = function(str){
	$('#controller_status').html(str);
	if (console) console.log(str);
};

controller.prototype.loadPlayers = function(){
	
	if(this.runChecks()){
		
		this.setStatus('Getting ID of next item to play');
		var nextItem;
		if(nextItem = this.playlist.getNextItem()){
			
			this.setStatus('Next to play is: '+nextItem);
			// try and find a player to use to load this video into
			var playerToUse = null;
			if (this.playerReady(this.player1)) playerToUse = this.player1;
			else if (this.playerReady(this.player2)) playerToUse = this.player2;
			if (playerToUse!=null){
				this.setStatus('Able to load into '+playerToUse.id);
				playerToUse.cueVideo(nextItem);
				this.setStatus('Video loaded into '+playerToUse.id);
				this.enableNextButton();
			}
			else this.setStatus('Both Players are busy - can\'t load video into either.');
		}
		else {
			this.setStatus('Nothing next to play in the playlist');
		//	this.disableNextButton();
		}
		
	}
	// else ,the players and/or playlist aren't ready. Do nothing.
	else {
		this.setStatus('Checks failed. One or both players, or the playlist must not be ready yet');
		this.disableNextButton();
	}
}

controller.prototype.playerReady = function(player){
	if (player.ready == true) return true;
	else return false;
}

controller.prototype.runChecks = function(){
	this.setStatus('Running Checks');
	if (this.player1.ytplayer){
		this.setStatus('Player 1 ok');
		if (this.player2.ytplayer){
			this.setStatus('Player 2 ok');
			if(this.playlist){
				this.setStatus('Playlist ok');
				return true;
			}else return false;
		}else return false
	}else return false;
}