/* --------------------------------------------------------------------

NET4VISIONS.COM iPlayer - player.js 12-16-2009
Version: 1.0.2
Created by: net4visions.com
Last edited: 02-22-2010
Descriptions: interacts with JW Player
and retrieves covers from Amazon using AJAX
License: MIT License (http://www.opensource.org/licenses/mit-license.php)
Requirements: mootools core 1.2.4.js || mootools more 1.2.4.2.js
Compress: http://www.refresh-sf.com/yui/ || http://yui.2clics.net/ 

-------------------------------------------------------------------- */

var Player = new Class({
	Implements: [Options, Events],
		
	options: {
		path:			'./assets/site/',
		host:			'rs3.radiostreamer.com',
		port:			'9330',
		stream:			'http://rs3.radiostreamer.com:9330/;*.nsv',
		duration:		'43200',	//	12 hrs
		popup:			'./index.php?id=203',
		opacity:		.90,
		volume:			40,
		loader:			true,
		draggable:		true,
		autoplay:		true,
		lightbox:		true,
		limit:			15,
		buttons:		{
			player:		['#btnPlayID', '#btnStopID', '#btnMuteID', '#btnVoldID', '#btnVoluID','#timeSliderPositionID', '#timeSliderDurationID', '#timeSliderRailID'],
			content:	['#btnPrevID', '#btnNextID', '#btnListID'],
			disable:	[]
		}
		//onReady:			$empty,
		//onChangeState:	$empty,
		//onCallback:		$empty,
		//onUpdate:			$empty,
		//onStart:			$empty,
		//onPause:			$empty,
		//onStop:			$empty
	},	
	
	initialize: function(el, options) {
		this.element = document.id(el);
		if (!this.element) return false;
		
		this.setOptions(options);
				
		this.playerWin 				= null;
		this.mediaFiles				= null;
		this.trackRequest			= null;
		this.currentItem 			= 0;
		this.previousItem			= -1;
		
		this.playerEl   			= document.id('playerID');
		this.playerDockEl 			= document.id('togglePlayerID');
		this.btnPlay				= document.id('btnPlayID');
		this.btnMute				= document.id('btnMuteID');
		this.tracklistEl			= document.id('tracklistID');
		this.tracklistContainerEl	= document.id('tracklistContainerID')
		this.tracklistExtEl			= document.id('tracklistExtID');
		this.loaderEl				= this._getLoader();
		this.btnsPlayer				= this.options.buttons.player;
		this.btnsContent			= this.options.buttons.content;
		this.btnsDisable			= this.options.buttons.disable;
		
		this._hideButtons([this.btnsPlayer,this.btnsContent,this.btnsDisable]);
		
		// start request
		this._createPlayer();
		this._prepare();
		
		this.attachEvents();
	},
	
	
	_prepare: function() {
		if (this.options.draggable) { // set drag for player and tracklist		
			var dp = new Drag(this.playerEl, {
				onStart: function(el) {
					el.setStyle('cursor', 'move');
				},
				onComplete: function(el) {
					el.setStyle('cursor', 'default');
				}
			});
			
			var dl = new Drag(this.tracklistContainerEl, {
				onStart: function(el) {
					el.setStyle('cursor', 'move');
				},
				onComplete: function(el) {
					el.setStyle('cursor', 'default');
				}
			});
		}
		
		this._prepareContentSlides();
		
		// set tooltips
		var tips = new Tips(this.playerEl.getElements('li'));
		
		if (!this.playerDockEl) {
			this.open();
			return false;
		}
		
		if (this.tracklistExtEl) this.requestTrack(); // start request if on playlist page
		
		this.fxPlayer = this.fxPlayer || new Fx.Morph(this.playerEl, {
			duration:	1500,
			onComplete: function() {
				if (this.playerEl.isVisible()) this._focus(this.playerEl);
			}.bind(this)
		}).set({ opacity: 0, height: 0, width: 0 });
	},
	
	
	_highlightCurrent: function(idx) {	// highlight current track
		if(!this.tracklistEl) return false;

		var idx  = idx || 0;
		var rows = this.tracklistEl.getElements('tr');
		if (rows.length < 1) return false;
		rows.each(function(el, i){
			el.removeClass('on');
			if (i == idx+1) rows[i].addClass('on');
		});
	},
	
	
	showSlideCounter: function() {	// show slide counter
		this.fxCounter = this.fxCounter || new Fx.Tween('btnScntID', { property: 'opacity', duration: 500, link: 'cancel' });
		this.fxCounter.set(1).start.pass(0, this.fxCounter).delay(3500);
	},
		
		
	attachEvents: function() { // attach player events
	
		// toggle player
		if ($defined(document.id('togglePlayerID'))) {
			document.id('togglePlayerID').addEvent('click', function(e){
				e.stop();
				this.toggle();
			}.bind(this));
		}
		
		this.playerEl.addEvent('mousedown', function(e){
			e.stop();
			this._focus(this.playerEl);
		}.bind(this));
				
		// add player buttons listeners		
		this.playerEl.addEvent('click:relay(li.button)', function(e, el){
			e.stop();
			this._clickPlayerButton(el);
		}.bind(this));
		
		this.tracklistEl.getParent().addEvent('mousedown', function(e){
			e.stop();
			this._focus(this.tracklistEl.getParent());
		}.bind(this));
		
		this.tracklistEl.addEvent('click:relay(tr)', function(e, el) {
			e.stop();
			this.contentSlides.show(el.retrieve('slideIndex'));
			this._focus(this.playerEl);
		}.bind(this));
		
		document.id('btnCloseTracklistID').addEvent('click', function(e){
			e.stop();
			this._clickPlayerButton(e.target);
		}.bind(this))
		
		if (!this.tracklistExtEl) return false;
		this.tracklistExtEl.addEvent('click:relay(a.toggle-track)', function(e, el) {
			e.stop();
			this.onToggleTrack(el);
		}.bind(this));
	},
	
	
	onToggleTrack: function(el) {
		var idx = el.retrieve('slideIndex');
		var slideContainerEl = this.contentSlides.slides[idx].getFirst();
		if (!$defined(slideContainerEl.retrieve('cover'))) { // cover not yet requested
			this.requestCover(idx);
			return false;
		}
		
		if (!slideContainerEl.retrieve('cover')) return false; // cover not found
		
		var coverEl = el.getNext().getElement('.cover');
		this.fxRevealCover = this.fxRevealCover || [];
		this.fxRevealCover[idx] = this.fxRevealCover[idx] || new Fx.Reveal(coverEl);
		
		this.fxRevealCover[idx].toggle();
		var trEl = el.getParent().getParent();
		trEl.toggleClass('on');
	},
	
	
	_addControllerListeners: function() { // player controller listeners
		var p = this.player;
		p.addControllerListener('ITEM', 	'Player._onControllerItem'); 
		p.addControllerListener('MUTE', 	'Player._onControllerMute');
		p.addControllerListener('STOP', 	'Player._onControllerStop');
		p.addControllerListener('VOLUME', 	'Player._onControllerVolume');
	},
	
	
	_onControllerItem: function(obj) { // index, id, client, version 
		if (this.previousItem != obj.index) {
			this.previousItem = this.currentItem;
			this.currentItem = obj.index;
		}
	},
	
	
	_onControllerMute: function(obj) { 	// state, id, client, version
		this.btnMute.toggleClass('on');
		var str = obj.state ? 'mute' : 'unmute';
		this.showStatus(str);
	},
	

	_onControllerStop: function(obj) { // id, client, version
		this.btnPlay.removeClass('on');
		this.resetTimeSlider();
	},
	
	
	_onControllerVolume: function(obj) { // percentage, id, client, version
		this.showStatus('Volume ' + obj.percentage);
	},
	
	
	_addModelListeners: function() { // player model listeners
		var p = this.player;
		p.addModelListener('BUFFER', 	'Player._onModelBuffer');
		p.addModelListener('STATE', 	'Player._onModelState'); 
		p.addModelListener('TIME', 		'Player._onModelTime');
	},
	
	
	_onModelBuffer: function(obj) { // percentage, id, client, version
		if (obj.percentage == 100) {
			if (this.options.loader) this.loaderEl.hide();
		}
		
		this.showStatus(obj.percentage);
	},


	_onModelState: function(obj) { // newstate, oldstate, id, client, version
		// IDLE, BUFFERING, PLAYING, PAUSED, COMPLETED
		//var os = obj.oldstate.toUpperCase();
		var ns = obj.newstate.toUpperCase();
		this.currentState = ns;
		this.showStatus(ns);
		
		switch (ns) {
			case 'IDLE':
				if (this.options.loader) this.loaderEl.hide();
				break;
			case 'BUFFERING':
				if (this.options.loader) this.loaderEl.show();
				break;
			case 'PLAYING':
				if (this.options.loader) this.loaderEl.hide();
				break;
			case 'PAUSED':
				break;
			case 'COMPLETED':
				this.resetTimeSlider();
				break;
			default: 
				return false;
		}
	},
	
	
	_onModelTime: function(obj) { // position, duration, id, client, version
		var d = this.secondsToTime(obj.duration);					// duration
		var p = this.secondsToTime(obj.position);					// played
		var r = this.secondsToTime(obj.duration-obj.position);		// remaining
		var posEl = document.id('timeSliderPositionID');
		var durEl = document.id('timeSliderDurationID');
		
		if (!this.timeSlider) {
			var steps	 = document.id('timeSliderRailID').getSize().x;
			var sliderEl = document.id('timeSliderRailID');
			var handleEl = document.id('timeSliderHandleID');
			
			handleEl.set('tween', { duration: 'short' });
			this.timeSlider  = new Slider(sliderEl, handleEl, {
				steps: steps,
				onTick: function(pos) {
					handleEl.tween('width', pos);
				}
			}).set(0);
		}
		
		// update slider
		var s = this.timeSlider.steps;
		var t = s/obj.duration*obj.position;
		this.timeSlider.set(t);
		
		// update position/duration
		posEl.set('text', p.h+':'+p.m+':'+p.s); 	// position
		durEl.set('text', d.h+':'+d.m+':'+d.s);		// duration
		//durEl.set('text', r.h+':'+r.m+':'+r.s);	// remaining
	},	
	
	
	showStatus: function(msg) {	// show status messages in player
		var el = document.id('statusID');
		el.set('text', msg.toUpperCase());
		
		this.fxStatus = this.fxStatus || new Fx.Tween(el, { property: 'opacity', duration: 500, link: 'cancel' });
		this.fxStatus.set(1).start.pass(0, this.fxStatus).delay(3500);
	},
	
	
	_clickPlayerButton: function(el) {	// player buttons events

		var elID = el.get('id');
		switch(elID) {
			case 'btnPlayID':
				this.play();
				break;
			case 'btnStopID':
				this.stop();
				break;
			case 'btnMuteID':
				this.mute();
				break;
			case 'btnVoluID':
				this.setVolume(10);
				break;
			case 'btnVoldID':
				this.setVolume(-10);
				break;
			case 'btnListID': case 'btnCloseTracklistID':
				this.toggleTracklist();
				break;
			case 'btnTuneID':
				if (this.currentItem < 1)  return false;
				this.currentItem = 0;
				this.load();
				break;
			case 'btnOpenID':
				this.openWindow();
				break;
			case 'btnQuitID':
				this.close();
				break;
			default:
				return false;
		}
	},
	
	
	setVolume: function(step) { // set player volume
		var btnVolIncr = document.id('btnVoluID');
		var btnVolDecr = document.id('btnVoldID');
		var cv = this.player.getConfig().volume; // current volume
		
		if (step > 0) {	// increase volume
			var nv = Math.min(100, cv+step);
			var op = nv < 100 ? 1 : .35;
		} else {		// decrease volume
			var nv = Math.max(0, cv+step);
			var op = nv > 0 ? 1 : .35;
		}
		
		btnVolIncr.set('opacity', (step > 0) ? op : 1);
		btnVolDecr.set('opacity', (step > 0) ? 1 : op);
		
		if (cv == nv) return false; // limits reached
		
		this.player.sendEvent('VOLUME', nv);
	},
	
		
	requestTrack: function() { // request track history (playlist)
		this.trackRequest = this.trackRequest || new Shoutcast(document.id('tracksID'), {
			limit:		this.options.limit,
			covers:		2,
			loader:		this.options.loader,
			lightbox:	this.options.lightbox,
			/*onRequest:	function() {
				if (this.contentSlides) this.contentSlides.show(0); // move to first on resume
			}.bind(this),*/
			onCallback: function() {
				if (this.contentSlides) {
					this.contentSlides.show(0);
					
					this.contentSlides.slides.each(function(item, index){
						var itemEl = item.getFirst();
						if (!$defined(itemEl.retrieve('cover'))) return false; // cover not yet retrieved
						(itemEl.retrieve('cover') == false) ? this._cover(false, index+1) : this._cover(true, index+1);
					}.bind(this))
				}
				
				this._highlightCurrent(0);	
				if (!this.options.lightbox) return false;
				
				var els = $$('.cover a');
				LB.addAnchors(els);
			}.bind(this)
		});		
	},
	
	
	requestCover: function(idx) { // request cover for given track
		if (this.currentItem > 0) return false; // media file
		if (!idx) return false;
		
		if (this.trackRequest) this.trackRequest.pause(); // pause periodical request
		
		var itemEl = this.contentSlides.slides[idx].getFirst();
		if ($defined(itemEl.retrieve('cover'))) return false; // cover already requested
		
		// proceed with requesting cover
		var track  = itemEl.retrieve('track');
		
		// RQUEST COVER
		new Shoutcast(itemEl, {
			limit:		1,
			covers:		1,
			loader:		this.options.loader,
			track:		track,
			trackIndex: idx,
			lightbox:	this.options.lightbox,
			onCallback: function() {
				if (!itemEl.retrieve('cover')) {
					this.showStatus('cover not found');
					this._cover(false, idx+1);
					return false;
				}
				
				this._cover(true, idx+1);
				
				if (!this.options.lightbox) return false;
				var els = $$('.cover a');
				LB.addAnchors(els);
			}.bind(this)
		});
	},
	
	
	load: function() { // load playlist item (track, stream)
		if (!this.player) return false;	
		if (this.currentItem == this.previousItem) return false; // no change
		
		if (this.currentItem > 0 && this.trackRequest) this.trackRequest.stop();
		if (this.currentItem == 0 && this.previousItem > 0 || this.currentItem > 0 && this.previousItem < 1) { // back to radio
			if (!this.mediaFiles) return false;
			if (this.tracklistContainerEl.isVisible() && this.fxRevealTracklist) this.fxRevealTracklist.dissolve();
			
			this.contentSlides = null;
			this._prepareContentSlides();
			this._updateContentSlides();
		}
		
		// move to slide
		if (this.contentSlides) this.contentSlides.show(this._itemToIndex());
		
		// play item
		this.player.sendEvent('ITEM', this.currentItem);
		this.player.sendEvent('STOP');
		
		if (this.playerEl.isVisible() && this.options.autoplay) this.play();		
		
		if (!this.playerEl.isVisible()) this.open();
	},
	
	
	play: function() {
		this.player.sendEvent('PLAY');
		this.btnPlay.toggleClass('on');
	},
	
	
	stop: function() {
		if (!this.player) return false;
		this.player.sendEvent('STOP');
		this.btnPlay.removeClass('on');
		this.resetTimeSlider();
	},
	
	
	mute: function() {
		var bMuted = this.player.getConfig().mute ? null : 'true';
		this.player.sendEvent('MUTE', bMuted);
	},
	
	
	toggleTracklist: function() { // toggle tracklist
		var el = this.tracklistContainerEl
		this.fxRevealTracklist = this.fxRevealTracklist || new Fx.Reveal(el, {
			onComplete: function() {
				this._focus(el);
				el.move({ relativeTo: this.playerEl, position: 'bottomRight', offset: {x: -el.getSize().x, y: 25 } });
			}.bind(this)
		});
		
		this.fxRevealTracklist.toggle();
	},
	
	
	createWindow: function(sUrl) { // create popup
		var sUrl  = this.options.popup
		var sName = 'playerWin';
		var sArgs = '';
			sArgs += 'menubar=no,'
			      + 'personalbar=no,'
				  + 'titlebar=no,'
				  + 'toolbar=no,'
				  + 'resizable=no,'
			      + 'scrollbars=no,'
			      + 'location=no,'
			      + 'status=no,'
				  + 'height=175,'
			      + 'width=350,'
				  + 'top=100,'
				  + 'left=100';
		
		this.playerPopup = window.open(sUrl, sName, sArgs);
		this.playerPopup.focus();
	},
	
	
	openWindow: function() { // open player in popup
		this.close();
		if (this.playerPopup && !this.playerPopup.closed) {
			this.playerPopup.focus();
			if (this.currentState == 'PLAYING') this.playerPopup.Player.sendEvent('PLAY');
		} else {
			this.createWindow();
		}
	},
	
	
	open: function() {
		var el = this.playerEl;
		
		if (this.playerPopup && !this.playerPopup.closed) this.playerPopup.close();
			
		if (this.player) {
			this.player.sendEvent('VOLUME', this.options.volume);
			if (this.options.autoplay) this.play();
		}
		
		if (this.currentItem == 0) { // stream file - request track information
			this.trackRequest ? this.trackRequest.start() : this.requestTrack();
		}
		
		this.showSlideCounter();
		
		if (!this.playerDockEl) {
			this.playerEl.setOpacity(this.options.opacity);
			return false; // is in popup
		}
		
		if (el.isVisible()) {
			this._focus(el);
			return false;	// player already open
		}
		
		$$(this.playerDockEl, document.id('toggleStreamerID')).addClass('on');
				
		// move player to position
		var w = 310; // width playerEl
		var p = document.id('page').getCoordinates();
		var x = p.left + p.width - w;
		var y = document.id('banner-toggle').getFirst().hasClass('off') ? 45 : 40;
		
		var sPos = this.playerDockEl.getPosition();
		this.fxPlayer.start({
			'opacity':	[0, this.options.opacity],
			'height':	[0, 135],
			'width':	[0, 310],
			'top':		[sPos.y, y],
			'left': 	[sPos.x, x]
		});
	},
	
	
	close: function() {
		if (this.tracklistContainerEl.isVisible()) this.fxRevealTracklist.dissolve();
		
		this.currentItem = 0;
		
		this.load();
		this.stop();
		if (!this.tracklistExtEl && this.trackRequest) this.trackRequest.stop();
		if (!this.playerDockEl) return false;
		
		$$(this.playerDockEl, document.id('toggleStreamerID')).removeClass('on');
		var sPos = this.playerDockEl.getPosition();
		this.fxPlayer.start({
			'opacity':	[0],
			'height':	[0],
			'width':	[0],
			'top':		[sPos.y],
			'left': 	[sPos.x]
		});
	},
	
	
	toggle: function() { // toggle player
		if (!this.playerDockEl) return false;
		this.playerEl.isVisible() ? this.close() : this.open();
	},
	
	
	resetTimeSlider: function() {
		if ($defined(this.timeSlider)) this.timeSlider.set(0);
		var p = this.secondsToTime(0);
		var d = (this.currentItem == 0) ? this.secondsToTime(this.options.duration.toInt()) : this.secondsToTime(0);
		this.btnPlay.removeClass('on');
		document.id('timeSliderPositionID').set('text', p.h+':'+p.m+':'+p.s);
		document.id('timeSliderDurationID').set('text', d.h+':'+d.m+':'+d.s);
	},
	
	
	secondsToTime: function (secs) { // convert seconds/milliseconds to hrs, mins, secs
	    var t = new Date(secs*1000);
	    var h = t.getUTCHours(); 
	    var m = t.getUTCMinutes(); 
	    var s = t.getUTCSeconds(); 
	    var o = {
	        'h': h < 10 ? '0' + h : h,
	        'm': m < 10 ? '0' + m : m,
	        's': s < 10 ? '0' + s : s
	    };
	    
	    return o;
	},
	
	
	_prepareMediaFiles: function() { // prepare media files - mp3s
		var aFiles = this._mediaFilesInit();
		this._mediaFileRequest(aFiles);
	},
	
	
	_mediaFilesInit: function() { // init media files
		var aFiles = this._getMediaFiles();
		
		aFiles.each(function(item, idx) {
			item.store('slideIndex', idx);
			item.addEvent('click', function(e) {
				e.stop();
				this.currentItem = idx+1; // 0 == radio stream
				this.load();
			}.bind(this))
		}.bind(this));
		
		return aFiles;
	},
	
	
	_mediaFileRequest: function(aFiles) { // request media file info
		var urls = aFiles.map(function(item){ 
			var loc = window.location.protocol+'//'+window.location.host+'/';
			var href = item.get('href');
			if (href.test(window.location.href)) href = href.replace(window.location.href, '');
			if (href.test(loc))  href = href.replace(loc, '');
			if (href.test('./')) href = href.replace('./','');
			return href;
		});
		
		if (urls.length < 1) return false;
		
		urls = JSON.encode(urls);
		
		this.filesRequest = new Request.JSON({
			method: 'post',
			url:	this.options.path + 'scripts/get_filedata.php',
			onSuccess: function(items) {
				if ($type(items) != 'array') return false;
				this.mediaFiles = items;
			}.bind(this)
		}).post({ 'files': urls });
	},
	
	
	_prepareContentSlides: function() { // prepare content slider
		var cnt  	= this.options.limit;
		var css  	= 'track';
		
		if (this.currentItem > 0) {	// media files
			this.resetTimeSlider();
			cnt = this.mediaFiles ? this.mediaFiles.length : 0;
			css = 'track media';
		}
		
		if (cnt < 1) return false;
		
		this._hideButtons(this.btnsContent); // hide content slider controls
		var el = this.playerEl.getElement('.bd');
		el.empty();
		
		var divEl = new Element('div', {
			id: 		'tracksID',
			'class':	'tracks',
			styles: {
				height: 75,
				width:	290
			}
		}).inject(el);
		
		var html = this._getTrackHtml();
		for (i = 0; i < cnt; i++) {
			var trackEl = new Element('div', {
				'class':	css,
				'html': 	html,
				styles: {
					height: 75,
					width:	280,
					margin: '0 5px 0 5px'
				}
			 }).inject(divEl);
			 if (this.currentItem == 0) trackEl.store('cover', false);
		};
		
		
		document.id('panelTotalID').set('text', cnt);
		
		if (cnt < 2) {
			document.id('panelIndexID').set('text', 1);
			document.id('panelTotalID').set('text', 1);
			return false;
		}
		
		this._showButtons(this.btnsContent); // show content slider controls
		document.id('btnNextID').removeEvents('click');
		document.id('btnPrevID').removeEvents('click');
		// set Carousel
		this.contentSlides = new SimpleSlideShow.Carousel(divEl, {
			slides: 				divEl.getElements('.track'),
			startIndex:				0,
			nextLink:				'btnNextID',
			prevLink:				'btnPrevID',
			crossFadeOptions:		{ duration: 750 },
			currentIndexContainer:	'panelIndexID',
			maxContainer:			'panelTotalID',
			onSlideDisplay: function(idx) { // called after onNext and onPrev
				this.requestCover(idx);
				this._highlightCurrent(idx);
				this.showSlideCounter();
				
				if (this.currentItem < 1) return false;
				if (this.currentItem != idx+1) {
					this.currentItem = idx+1;
					this.load();
				}
			}.bind(this)
		});
	},
	
	
	_updateContentSlides: function() {	// update media slides
		if (this.currentItem > 0) {
			if (!this.mediaFiles) return false;
			var items = this.mediaFiles;
			
			var tbl = new HtmlTable({ // prepare table
				properties: {
					border: 0,
					cellspacing: 0
				},
				zebra: true
			});

			tbl.setHeaders(['<!-- Number -->','Datum','Titel','Gr&ouml;sse']);
			this.tracklistEl.empty().adopt(tbl);
			
			items.each(function(item, idx){
				var itemEl = document.id('tracksID').getElements('.track')[idx];
				itemEl.empty();
				
				var html = '';
				html += '<span class="time">'   + item.date  + '</span><br />';
				html += '<span class="title">'  + item.track + '</span><br />';
				html += '<span class="time">'   + item.size  + '</span><br />';
					
				var divEl = new Element('div', {
					'class': 'descr',
					'html' : html
				}).inject(itemEl);
				
				var rObj = tbl.push([idx+1, item.date, item.track, item.size]);
				rObj.tr.store('slideIndex', idx);
			});
		
			this._highlightCurrent(0);
			this._showButtons('#btnTuneID');
			this._hideButtons('#btnOpenID');
		} else { // radio stream
			this._showButtons('#btnOpenID');
			this._hideButtons('#btnTuneID');
			this.trackRequest ? this.trackRequest.reset('tracksID') : this.requestTrack(); // restart trackRequest
		}	
	},
	
	
	_createPlayer: function() {	// create jw Player
		var elID  = 'swfObjectID';
		var divEl = new Element('div', { id: elID, 'class': 'flash-container' }).inject(this.element, 'bottom');

		var a = new Asset.javascript(this.options.path + 'js/player/swfobject.js', {
			onload: function() {
				var v = '9.0.124'; // minimum Flash version
				if (!swfobject.hasFlashPlayerVersion(v)) {
					return false;
				};
								
				var pFile = this.options.path + 'js/player/player.swf';
				
				var f = { // flashvars
					file: 				''
				};
				
				var p = { // parameters
					allowfullscreen: 	'true',
					allowscriptaccess:	'always' // always || sameDomain
				};
				
				var a = { // attributes
					id:					'jwplayerID',
					name:				'jwplayerID'
				};
						
				swfobject.embedSWF(pFile, elID, '1', '1', v, false, f, p, a);
			}.bind(this)
		})
	},
	

	_ready: function(obj) {
		this.player = document.id(obj.id);
		if (!this.player) return false;
		
		var plist = this._buildPlaylist(); // first item always radio stream!
		this.currentItem = 0;
		this.player.sendEvent('LOAD', plist);
		
		if (plist.length > 1) this._prepareMediaFiles();
				
		document.id('swfContainerID').setStyles({ visibilty: 'hidden', 'margin-left': '-7000px' });
		
		if (this.player.getConfig().mute) this.btnMute.addClass('on'); // check mute
		var btnsVol = $$('#btnVoldID, #btnVoluID');
		btnsVol.set('opacity', 1);				// reset volume buttons
		this._showButtons(this.btnsPlayer);		// show buttons
		this._hideButtons('#btnTuneID');		// hide back to radio button
		this.resetTimeSlider();					// reset time slider
		this._addControllerListeners();			// add controller events
		this._addModelListeners();				// add model events
		
		
		this.fireEvent('onReady', this.player);
		if (!this.playerDockEl && this.options.autoplay) {
			this.play();	// opened in popup
			return false;
		}
		
		// handle toggleStreamer
		var el = document.id('toggleStreamerID');
		if (!el) return false;
		
		el.show();
		el.getFirst().addEvent('click', function(e){ e.stop(); this.toggle(); }.bind(this));
	},
	
	
	_getMediaFiles: function() { // returns all mp3 files on page
		return $$('a[href$=mp3]');
	},
	
	
	_buildPlaylist: function() { // returns playlist for jw Player

		var author =		'CRS';	
		var description	=	'Country Radio Switzerland'; 
		var title =			'Country Radio Switzerland';		
		var type =			'sound';
		
		var alist = new Array();
		alist[0] = {
			author: 		author,
			description:	description,
			title:			title,
			type:			type,
			file:			this.options.stream,
			duration:		this.options.duration		
		}
		
		var files = this._getMediaFiles();
		files.each(function(item, index) {	
			var href = item.get('href');
			if (href.test('./')) href = href.replace('./','');
			if (href.test(window.location.href)) href = href.replace(window.location.href, '');
			
			alist.push({
				author: 		author,
				description:	description,
				title:			title,
				type:			type,
				file:			href,
				duration:		0
			})
		});
		
		return alist;
	},
	
	
	_showButtons: function(els) {
		var dis = $$(this.btnsDisable);
		var els = $$(els).filter(function(item, index){
			return !dis.contains(item);
		});
		$$(els).show();
	},
	
	
	_hideButtons: function(els) {
		$$(els).hide();
	},
	
	
	_getTrackHtml: function() {
		var html = '';
		html += '<div class="descr">';
		html += '	<div class="artist">';
		html += '		CRS';
		html += '	</div>';
		html += '	<div class="title">';
		html += '		Country Radio Switzerland';
		html += '	</div>';
		html += '</div>';
		
		return html;	
	},
	
	
	_getLoader: function() {
		if (!this.options.loader) return false;
		if ($defined(document.id('loaderID'))) return document.id('loaderID');
		
		return new Element('div', { id: 'loaderID', 'class': 'loader' }).inject(this.playerEl, 'top');
	},
	
	
	_focus: function(el) { // focus player, tracklist
		var czi = el.getStyle('z-index').toInt(); // current z-index
		if (el == this.playerEl) {
			var nzi = this.tracklistContainerEl.getStyle('z-index').toInt();
			if (czi > nzi) return false;
			this.tracklistContainerEl.setStyle('z-index', nzi-1);
		} else {
			var nzi = this.playerEl.getStyle('z-index').toInt();
			if (czi > nzi) return false;
			this.playerEl.setStyle('z-index', nzi-1);
		}
		el.setStyle('z-index', nzi);
	},
	
	
	_cover: function(found, idx) { // mark found covers
		var trEls = this.tracklistEl.getElements('tr');
		found ? trEls[idx].addClass('found') : trEls[idx].addClass('not-found');
	},
	
	
	_itemToIndex: function() { // playlist index to slide index
		if (this.currentItem == 0) return 0;
		return this.currentItem - 1; 
	}
});


// JW PLAYER READY
// function is called when JW Player is ready
function playerReady(obj) { // V 4
	Player._ready(obj);
};