var beronPlayer = new Class({
	vars: {"status":"stopped","playlists":{},"currentPlaylist":0,"currentSongNum":0},
	init: function(){
		this.vars = {"status":"stopped","playlists":{},"currentPlaylist":0,"currentSongNum":0};
		/* Si no hay usuario logueado pasamos a la gestion por cookies */
		if(!VAR_loggerUser){this.cookies_loadPlaylists();}

		var h = $_("player_playlistHolder");
		/* Inicializamos las playlist existentes y las renderizamos en la parte de la derecha */
		for(var a in VAR_userPlaylists){this.vars.playlists[a] = extend(VAR_userPlaylists[a],{"count":0,"songs":{}});this.addPlaylistNameToPlaylistHolder(VAR_userPlaylists[a],h);}
		/* Creamos los manejadores del dropfile */
		var player_body = $_("player_body");
		player_body.addEventListener("dragover",function(e){e.preventDefault();},true);
		player_body.addEventListener("drop",this._dropExternalFile,true);
	},
	_dropExternalFile: function(e){
		e.preventDefault();var dt = e.dataTransfer;var files = dt.files;

		if(files.length < 1){return;}
		/* Si hay una playlist de reproducción activa seleccionamos esa playlist, sino
		 * creamos una volatil para usarla de momento */
		if(_beronPlayer.vars.currentPlaylist > 0){var playlistID = _beronPlayer.vars.currentPlaylist;}
		else{
			/* Creamos una nueva lista de reproducción */
			var playlistID = _beronPlayer.playlist_createNew_nouser({playlistName:"New Playlist",playlistArtist:"",playlistYear:""});
			_beronPlayer.playlistToSongList(playlistID);
		}

		$A(files).each(function(file){if(file.type != "audio/ogg"){return;}_beronPlayer._dropExternalFile_readFile(playlistID,file);});
	},
	_dropExternalFile_readFile: function(playlistID,file){
		var reader = new FileReader();
		reader.onloadend = function(){
			/* TITLE|ARTIST|GENRE|ALBUM|TRACK|YEAR|LENGTH */
			var id3 = _beronPlayer._dropExternalFile_parseOggID3(reader.result);
			reader.onloadend = function(){
				var song = _beronPlayer.playlist_addSongToPlaylist(playlistID,{songTitle:id3['title'],songArtist:id3['artist'],songGenre:id3['genre'],songAlbum:id3['album'],
				songTrack:id3['tracknumber'],songYear:id3['date'],songLink:reader.result});
			};
			reader.readAsDataURL(file);
		};reader.readAsBinaryString(file);
	},
	_dropExternalFile_parseOggID3: function(result){
		result = result.substring(0,1000);

		var breakCodes = $A([]);
		/* http://www.webonweboff.com/tips/js/event_key_codes.aspx */
		/* Tenemos que excluir 32(espacio) y 39(comilla simple) */
		for(i=0;i<48;i++){if(i==32 || i==39){continue;}breakCodes.push(String.fromCharCode(i));}
		var returnChar = String.fromCharCode(0);/* RETURN */

		var songID3 = {};
		$A(['genre','title','artist','date','album','tracknumber']).each(function(elem){
		//$A(['title']).each(function(elem){
			var string = "";var count = 0;
			var index = result.indexOf(elem);if(index < 0){index = result.indexOf(elem.toUpperCase());}
			index += elem.length+1;
			//alert(result.substring(index+7,index+8).charCodeAt(0));
			while(breakCodes.find(result.substring(index,index+1)) < 0 && result.substring(index,index+2) != "b"+returnChar && count < 255){string += result.substring(index,index+1);index++;count++;}
			songID3[elem] = string;
			//alert(string);
		});
		//alert(print_r(songID3));
		return songID3;
	},
	controls_toggle: function(bt){
		switch(this.vars.status){
			case "playing": $_("beronPlayer_audio").pause();return;
			case "paused": $_("beronPlayer_audio").play();return;
			case "stopped":
				if(parseInt(this.vars.currentSongNum) < 1){this.vars.currentSongNum = 1;}
				this.play(this.vars.currentPlaylist,this.vars.currentSongNum,$_("songNode_"+this.vars.currentSongNum));
				return;
		}
	},
	controls_setPlayButtonStatus: function(s,bt){
		if(!bt){var bt = $_("controlPlay");}bt.className = "control"+$capitalize(s);
	},
	playlist_addSongToPlaylist: function(playlistID,song){
		/* song debe tener los siguiente campos : TITLE|ARTIST|GENRE|ALBUM|TRACK|YEAR|LENGTH precedidos
		 * por 'song' y capitalizados -> songTitle. Si la playlist en la que estamos insertando es la
		 * playlist que está renderizada ahora mismo, insertamos el nodo direntamente dentro de songList */

		if(!this.vars.playlists[playlistID]){alert("No existe la lista de reproducción "+playlistID);return;}
		/* Incrementamos el contador de canciones de esta playlist */
		this.vars.playlists[playlistID].count++;
		var n = this.vars.playlists[playlistID].count;
		/* insertamos el nuevo nodo extendiendo lo que ya ha entrado a través de song */
		this.vars.playlists[playlistID].songs[n] = extend(song,{"playlistID":playlistID,"playlistName":this.vars.playlists[playlistID].playlistName,"playlistNum":n});
		/* Si la playlist en la que estamos insertando es la playlist seleccionada, deberiamos agregar el nodo */
		if(this.vars.currentPlaylist == playlistID){/*//FIXME: deprecated*/this.addSongToPlayList_appendNode($_("player_bodySongList"),song);}
		return this.vars.playlists[playlistID].songs[n];
	},
	playlist_createNew: function(h){
		function sendData(h,ths){
			var ops = {};$A(h.$T("INPUT")).append(h.$T("TEXTAREA")).append(h.$T("SELECT")).each(function(elem){if(elem.type=="checkbox"){ops[elem.name] = elem.checked;return;}ops[elem.name] = elem.value;});
			if(!VAR_loggerUser){ths.playlist_createNew_nouser(ops);removeThemeInfo(h);return;}
			/* Loading... */var txt = "Please wait while the new playlist is being created ... ";var d = $C("DIV",{className:"loadingHolder",innerHTML:txt},h.empty());
			
			var params = "command=managePlaylist&"+$toUrl(ops);
			ajaxPetition("resources/PHP/API_beronPlaylist.php",params,function(ajax){
				var r = jsonDecode(ajax.responseText);if(parseInt(r.errorCode)>0){alert(print_r(r));removeThemeInfo(h);return;}
				/* Solo necesitamos informar VAR_userPlaylists que son las señas de la lista de reproducción,
				 * una vez se encuentren ahí las señas, se pedirá mediante AJAX las canciones de dicha lista
				 * de reproducción y se cachearán, por lo que no es necesario informar this.vars.playlists */
				VAR_userPlaylists[r.id] = r.data;this.vars.playlists[r.id] = extend(r.data,{"count":0,"songs":{}});
				this.addPlaylistNameToPlaylistHolder(r.data);removeThemeInfo(h);
			}.bind(ths));
		}

		info_create("createNewPlaylist",{},h);
		var h = $_("info_createNewPlaylist_container");
		$C("H4",{innerHTML:"New playlist"},h);
		$C("SPAN",{innerHTML:"Name of the new playlist"},h);$C("INPUT",{name:"playlistName"},$C("DIV",{className:"inputText"},h));
		$C("SPAN",{innerHTML:"Artist of the disc (if any)"},h);$C("INPUT",{name:"playlistArtist"},$C("DIV",{className:"inputText"},h));
		$C("SPAN",{innerHTML:"Year of the disc (if any)"},h);$C("INPUT",{name:"playlistYear"},$C("DIV",{className:"inputText"},h));

		var d = $C("DIV",{className:"buttonHolder"},h);
		d.appendChild(createGnomeButton("OK",function(){sendData(h,this);}.bind(this)));
		d.appendChild(createGnomeButton("Cancel",function(){removeThemeInfo(h);}));
		$C("I",{className:"floatSeparator"},h);
	},
	playlist_createNew_nouser: function(ops){
		var c = 1;for(var a in this.vars.playlists){c++;}ops.id = c;
		VAR_userPlaylists[c] = ops;this.vars.playlists[c] = extend(ops,{"count":0,"songs":{}});
		this.addPlaylistNameToPlaylistHolder(ops);
		return c;
	},
	playlist_cleanSelected: function(){
		var h = $_("player_playlistHolder");
		$A(h.$T("DIV")).each(function(el){if(el.className.match(/ selected$/)){el.className = el.className.replace(/ selected$/,"");}});
	},
	addPlaylistNameToPlaylistHolder: function(p,h){
		if(!h){h = $_("player_playlistHolder");}
		$C("DIV",{id:"playlist_"+p.id,className:"playlist",innerHTML:p.playlistName+"<span> by "+p.playlistArtist+"</span> ("+p.playlistYear+")",onclick:function(){this.user_loadPlaylistByID(p.id);}.bind(this)},h);
	},
	addSongToPlayList: function(h){
		info_create("addSongDialog",{".width":"400px"},h);
		var h = $_("info_addSongDialog_container");
		$C("H4",{innerHTML:"Add a new song to this playlist"},h);
		$C("SPAN",{innerHTML:"Song Properties"},h);
		$C("TEXTAREA",{id:"newSong_properties",".height":"100px"},$C("DIV",{className:"inputText"},h));
		$C("SPAN",{innerHTML:"Link to this song"},h);
		$C("TEXTAREA",{id:"newSong_link"},$C("DIV",{className:"inputText"},h));

		var d = $C("DIV",{className:"buttonHolder"},h);
		d.appendChild(createGnomeButton("Add song",function(){this.addSongToPlayList_accept();}.bind(this)));
		d.appendChild(createGnomeButton("Cancel",function(){removeThemeInfo(h);}));
		$C("I",{className:"floatSeparator"},h);
	},
	addSongToPlayList_accept: function(){
		if(this.vars.currentPlaylist == 0){alert("No playlist selected.");return;}

		var songProperties = $_("newSong_properties").value;
		var m = songProperties.match(/(TITLE|ARTIST|GENRE|ALBUM|TRACK|YEAR|LENGTH):(.*)/g);
		var node = {};$A(m).each(function(el){el = el.split(":");node["song"+$capitalize(el[0])] = el[1];});

		var songLink = $_("newSong_link").value;
		if(isEmpty(songLink)){return;}
		var pID = this.vars.currentPlaylist;
		this.vars.playlists[pID].count++;
		var n = this.vars.playlists[pID].count;
		node = this.vars.playlists[pID].songs[n] = extend(node,{"playlistID":pID,"playlistName":this.vars.playlists[pID].playlistName,"playlistNum":n,"songLink":songLink});
		var h = $_("player_bodySongList");

		/* Si no hay usuario conectado añadimos la canción directamente */
		if(!VAR_loggerUser){removeThemeInfo($_("info_addSongDialog_container"));this.addSongToPlayList_appendNode(h,node);return;}

		//FIXME: poner un loading

		var params = "command=addSongToPlaylist&playlistID="+pID+"&"+$toUrl(node);
		ajaxPetition("resources/PHP/API_beronPlaylist.php",params,function(ajax){
			var r = jsonDecode(ajax.responseText);if(parseInt(r.errorCode)>0){alert(print_r(r));}
			removeThemeInfo($_("info_addSongDialog_container"));
			this.addSongToPlayList_appendNode(h,node);
		});
	},
	addSongToPlayList_appendNode: function(h,node){
		var tr = $C("TR",{className:h.alt,id:"songNode_"+node.playlistNum},h);
		$C("TD",{},tr);
		$C("A",{innerHTML:$htmlEntitiesEncode(node.songTitle),onclick:function(){this.play(node.playlistID,node.playlistNum,tr);}.bind(this)},$C("TD",{},tr));
		$C("TD",{innerHTML:((node.songArtist) ? node.songArtist : "")},tr);
		$C("TD",{innerHTML:((node.songLength) ? node.songLength : "--:--")},tr);
		$C("TD",{innerHTML:((node.songAlbum) ? node.songAlbum : "")},tr);
		$C("TD",{},tr);
		var d = $C("DIV",{},$C("TD",{},tr));
		d.appendChild(createGnomeButton("Properties",function(){this.songNode_properties(d,node);}.bind(this),"gnomeButtonMini"));
		h.alt = (isEmpty(h.alt) ? " alt" : "");

		/* Aumentamos el contador de canciones de la playlist */
		var s = $_("player_bodySongListOptions_songCounter");
		s.innerHTML = parseInt(s.innerHTML)+1;
	},
	event_onended: function(){
		this.vars.status = "stopped";
		var cPlaylist = this.vars.playlists[this.vars.currentPlaylist];
		if(cPlaylist.count <= this.vars.currentSongNum){return;/* Se ha terminado el disco */}
		/* Hay que reproducir la siguiente canción */
		var n = this.vars.currentSongNum+1;
		setTimeout(function(){this.play(this.vars.currentPlaylist,n,$_("songNode_"+n));}.bind(this),200);
	},
	event_onpause: function(){
		this.vars.status = "paused";this.controls_setPlayButtonStatus("play");
	},
	event_onplay: function(){
		this.vars.status = "playing";this.controls_setPlayButtonStatus("pause");
		eFadeout($_("player_message"),function(el){el.style.display = "none";});
	},
	event_ontimeupdate: function(player){
		/* Firefox actualmente falla al obtener la duración de un archivo de sonido
		 * que se ha obtenido a través de dropfile, si la duracion no es superior a 1 salimos */
		if(!player.duration){return;}
		var fraction = player.currentTime/player.duration;
		var newWidth = (($_("bar_background").offsetWidth-8)*fraction)+7;
		$_("bar_foreground",{".width":newWidth+"px"});
		$_("bar_point",{".left":(newWidth-8)+"px"});

		var timeLeft = parseInt(player.duration-player.currentTime);
		var mins = parseInt(timeLeft/60);var secs = timeLeft-(mins*60);
		if(mins<10){mins = "0"+mins;}if(secs<10){secs = "0"+secs;}
		$_("player_songTimeLeft",{innerHTML:mins+":"+secs});
	},
	songNode_properties: function(d,node){
		info_create("songNode_properties",{},d,(d.offsetWidth/2)-7);
		var h = $_("info_songNode_properties_container");
		$C("H4",{innerHTML:"About this song"},h);
		$C("DIV",{innerHTML:"Remove from playlist.",onclick:function(){this.songNode_properties_removeSong(d,node);}.bind(this)},h);
		$C("DIV",{innerHTML:"Move to another playlist.",onclick:function(){this.songNode_properties_moveToAnotherPlaylist(h,node);}.bind(this)},h);
		$C("SPAN",{innerHTML:"Cancel",".cursor":"pointer",onclick:function(){removeThemeInfo(h);}},h);
	},
	songNode_properties_removeSong: function(d,node){
		if(!confirm("Are you sure you want to remove this song?")){return;}
		if(!VAR_loggerUser){this.songNode_properties_removeSong_nouser(d,node);return;}
		var params = "command=getSongsFromSongID&songID="+node.id;
		ajaxPetition("resources/PHP/API_beronPlaylist.php",params,function(ajax){
			var r = jsonDecode(ajax.responseText);if(parseInt(r.errorCode)>0){alert(print_r(r));}
			while(d.parentNode && d.tagName.toUpperCase()!="TR"){d = d.parentNode;}
			if(!d.parentNode){return;}d.parentNode.removeChild(d);
		});
	},
	songNode_properties_moveToAnotherPlaylist: function(h,node){
		h.empty();
		//FIXME: move
		for(var a in VAR_userPlaylists){$C("DIV",{innerHTML:VAR_userPlaylists[a].playlistName},h)}
		$C("SPAN",{innerHTML:"Cancel",".cursor":"pointer",onclick:function(){removeThemeInfo(h);}},h);
	},
	songNode_properties_removeSong_nouser: function(d,node){
		alert(print_r(node));
	},
	play: function(playlistID,nodeNum,trElem){
		if(parseInt(nodeNum) == 0){nodeNum = 1;}
		var songNode = this.vars.playlists[playlistID].songs[parseInt(nodeNum)];
		/* Establecemos la canción actual que se va a reproducir */
		this.vars.currentSongNum = parseInt(nodeNum);
		var audio = $_("beronPlayer_audio",{autoplay:"autoplay",src:songNode.songLink}).load();

		$_("player_messageSontTitle",{innerHTML:$htmlEntitiesEncode(songNode.songTitle)});
		$_("player_messageSontArtist",{innerHTML:$htmlEntitiesEncode(songNode.songArtist)});
		eFadein($_("player_message",{".visibility":"hidden",".display":"block"}));

		$A($fix(trElem.parentNode).$T("TR")).each(function(el){el.className = el.className.replace(" playing","");});
		trElem.className += " playing";
	},
	playlistToSongList: function(playlistID){
		/* Tenemos que establecer esta lista de reproducción como la predeterminada */
		this.vars.currentPlaylist = playlistID;

		/* Comprobamos que la lista de reproducción sea correcta */
		if(!this.vars.playlists[playlistID] || !this.vars.playlists[playlistID].songs){return;}

//FIXME: cuando esto ocurra, poner la barra a 0, poner la currentSong a 1 y el status a stopped

		/* Renderizamos los nodos de la lista de reproducción actual */
		var h = $_("player_bodySongList",{alt:""}).empty();
		for(var a in this.vars.playlists[playlistID].songs){this.addSongToPlayList_appendNode(h,this.vars.playlists[playlistID].songs[parseInt(a)]);}

		/* Establecemos el número de canciones que tiene la playlist en las propiedades */
		$_("player_bodySongListOptions_songCounter",{innerHTML:this.vars.playlists[playlistID].count});

		/* Limpiamos los estilos previos de las playlists seleccionadas */
		this.playlist_cleanSelected();
		var p = $_("playlist_"+playlistID);p.className += " selected";
	},
	/**COOKIES**/
	cookies_savePlaylists: function(){
		for(var a in this.vars.playlists){cookieSet("playlist_"+a,jsonEncode(this.vars.playlists[a]),100);}
	},
	cookies_loadPlaylists: function(){
		var coo = cookiesToObj();
		//FIXME: a menos que solo haya una playlist no es necesario renderizarla directamente
		for(var a in coo){if(a.match(/^playlist_/)){var p = jsonDecode(coo[a]);this.vars.playlists[p['name']] = p;this.playlistToSongList(p['name']);}}
	},
	/**USER**/
	user_preferences: function(h){
		if(!VAR_loggerUser){this.user_loginDialog(h);return;}
		//FIXME: de momento
		this.user_logout();
	},
	user_loadPlaylistByID: function(playlistID){
		/* Si tenemos la playlist en memoria, evitamos la petición al servidor */
		if(this.vars.playlists[playlistID] && this.vars.playlists[playlistID].count){this.playlistToSongList(playlistID);return;}
		/* Si no hay usuario logueado no tenemos otra opción que renderizar directamente */
		if(!VAR_loggerUser){this.vars.playlists[playlistID].count = 0;this.playlistToSongList(playlistID);return;}

		var params = "command=getSongsFromPlaylistID&playlistID="+playlistID;
		ajaxPetition("resources/PHP/API_beronPlaylist.php",params,function(ajax){
			var r = jsonDecode(ajax.responseText);if(parseInt(r.errorCode)>0){alert(print_r(r));}
			var n = this.vars.playlists[playlistID].count;
			//FIXME: usar la funcion playlist_addSongToPlaylist
			$A(r.data).each(function(el){n++;this.vars.playlists[playlistID].songs[n] = extend(el,{"playlistID":playlistID,"playlistNum":n});}.bind(this));
			this.vars.playlists[playlistID].count = n;
			/* Usamos la función genérica especificamente creada para ello */
			this.playlistToSongList(playlistID);
		}.bind(this));
	},
	user_removeCurrentPlaylist: function(){
		if(this.vars.currentPlaylist == 0){return;};
		this.user_removePlaylistByID(this.vars.currentPlaylist);
	},
	user_removePlaylistByID: function(playlistID){
		if(!confirm("Are you sure you want to remove the selected playlist?")){return;}
		var params = "command=removePlaylistFromPlaylistID&playlistID="+playlistID;
		ajaxPetition("resources/PHP/API_beronPlaylist.php",params,function(ajax){
			var r = jsonDecode(ajax.responseText);if(parseInt(r.errorCode)>0){alert(print_r(r));return;}
			this.vars.currentPlaylist = 0;
			//FIXME: cuando esto ocurra, poner la barra a 0, poner la currentSong a 1 y el status a stopped
			/* Renderizamos los nodos de la lista de reproducción actual */
			var h = $_("player_bodySongList",{alt:""}).empty();
			var p = $_("playlist_"+playlistID);p.parentNode.removeChild(p);
			//alert(print_r(r));
		}.bind(this));
	},
	user_loginDialog: function(h){
		function sendData(h){
			//FIXME: poner loader

			var ops = {};$A(h.$T("INPUT")).append(h.$T("TEXTAREA")).append(h.$T("SELECT")).each(function(elem){if(elem.type=="checkbox"){ops[elem.name] = elem.checked;return;}ops[elem.name] = elem.value;});
			var params = "command=userLogin&"+$toUrl(ops);
			ajaxPetition("resources/PHP/general.php",params,function(ajax){
				var r = jsonDecode(ajax.responseText);if(parseInt(r.errorCode)>0){alert(print_r(r));return;}
				VAR_loggerUser = {userName:r.data.userName,userAlias:r.data.userAlias};
				//FIXME: faltan las playlists
				//alert(print_r(r));
				//removeThemeInfo(h);
				window.location.reload();
			});
		}

		info_create("user_loginDialog",{},h,(h.offsetWidth/2)-7);
		var h = $_("info_user_loginDialog_container");
		$C("H4",{innerHTML:"Please log in"},h);
		$C("SPAN",{innerHTML:"Mail account"},h);
		$C("INPUT",{id:"loginDialog_mail",name:"user"},$C("DIV",{className:"inputText"},h));
		$C("SPAN",{innerHTML:"Password"},h);
		$C("INPUT",{id:"loginDialog_pass",name:"pass",type:"password"},$C("DIV",{className:"inputText"},h));
		$C("SPAN",{innerHTML:"Login",".cursor":"pointer",onclick:function(){sendData(h);}},h);
		$C("SPAN",{innerHTML:"Cancel",".cursor":"pointer",onclick:function(){removeThemeInfo(h);}},h);
	},
	user_logout: function(){
		var params = "command=userLogout";
		ajaxPetition("resources/PHP/general.php",params,function(ajax){
			var r = jsonDecode(ajax.responseText);if(parseInt(r.errorCode)>0){alert(print_r(r));return;}
			window.location.reload();
		});
	},
	/* SEARCH */
	search_artists: function(e,el){
		var t = (document.all) ? e.keyCode : e.which;
		if(t!=13){return;}
		if(isEmpty(el.value)){return;}

		var params = "command=searchArtists&str="+el.value;
		ajaxPetition("resources/PHP/API_beronStorage.php",params,function(ajax){
			var r = jsonDecode(ajax.responseText);if(parseInt(r.errorCode)>0){alert(print_r(r));return;}
			$_("player_search_artistCount",{innerHTML:r.data.length});
			var h = $_("player_search_artistSuggestions").empty();
			$A(r.data).each(function(el,n){
				$C("SPAN",{innerHTML:$htmlEntitiesEncode(el.artistName)},h);
				if(n<(r.data.length-1)){h.appendChild(document.createTextNode(" • "));}
			});
		});
	}
});

