//SOUNDMANAGER GLOBALS
soundManager.onload = function() { SOUNDMANAGER_LOADED = true; };	
soundManager.onerror = function() {}; // alert('unable to initialize audio engine.  perhaps you need to visit http://get.adobe.com/flashplayer/ and install the latest version of Flash Player.');
soundManager.url = '/js/soundmanager/swf/'; // directory where SM2 .SWFs live
soundManager.waitForWindowLoad = false;
soundManager.debugMode = false;
soundManager.nullURL = '/js/soundmanager/null.mp3';
soundManager.consoleOnly = true;

var SOUNDMANAGER_LOADED = false;
var ALBUM_ART_URL = '/dyn_images/65/50/';
var MEDIA_SOURCE_URL = 'http://musiclicensingstore.com/rumblefish_audio/';

Object.extend(Object, {
	deepClone: function (obj) {
		if ( obj !== null ) {
			var objectClone = new obj.constructor();
			for (var property in obj) {
				if (typeof obj[property] == 'object')
					objectClone[property] = Object.deepClone(obj[property]);
				else
					objectClone[property] = obj[property];
			}
			return objectClone;
		} else {
			return obj;
		}
	}
});


// PLAYER REGISTRY, SO CALLBACKS CAN LOOK UP THE CORRECT INSTANCE TO EXECUTE IN!!
// THIS HANDLES N NUMBER OF PLAYERS ALL TALKING TO THE SAME SOUNDMANAGER FLASH INTERFACE
var PLAYER_REGISTRY = Class.create({
		options: { players: {} },
		initialize: function() { },
		add: function(playerID, player) {
			if ( Object.isString(playerID) && playerID != '' )
				if ( typeof this.options.players[playerID] != 'undefined' ) //NO OVERWRITES, ONLY EXPLICIT DELETES
					return false;
				else
					this.options.players[playerID] =  player;
				return true;
		},
		del: function(playerID) {
			return delete this.options.players[playerID];
		},
		get: function(playerID) {
			return this.options.players[playerID];
		}
	});

var PLAY_PEN = new PLAYER_REGISTRY(); // each PLAYER should have a unique ID string, and may use it's (static) soundmanager instance id

// play_song -> _retrieve_song_data -> ( server ) -> play_song_callback -> _handle_state_change -> ... -> render
//SIMPLE PLAYER CLASS
var PLAYER = Class.create({
		currentMediaID:null,
		currentSongTitle:null,
		currentSongArtist:null,
		currentAlbumArtURL:null,
		currentMediaURL:null,
		currentPlaylistName:null,
		__currentSongInfo:null, //holds the raw song data object returned
		opts: {
			defaultSoundID: null, // required unique ID for the "sound"
			defaultAnchor: null,  //selector or element to tether the player to
			defaultVolume:45,
      waitForSongLoad:false,
			playButton:null,
			pauseButton:null,
			nextButton:null,
			prevButton:null
		},
/*
		get_opt:function(opname) {
			return ( typeof this.opts[opname] != 'undefined' ? this.opts[opname] : '' );
		},
		set_opt:function(opname,opval) {
			this.opts[opname] = opval;
		},
*/
		initialize: function() {

			if ( typeof arguments[0] != 'undefined' ) {
				this.opts = {
					defaultVolume: 	( typeof arguments[0]['defaultVolume'] 	!= 'undefined' ? 	arguments[0]['defaultVolume'] 	: 	this.opts.defaultVolume ),
					waitForSongLoad: 	( typeof arguments[0]['waitForSongLoad'] 	!= 'undefined' ? 	arguments[0]['waitForSongLoad'] 	: 	this.opts.waitForSongLoad ),
					playButton: 	( typeof arguments[0]['playButton'] 	!= 'undefined' ? 	arguments[0]['playButton'] 		: 	this.opts.playButton ),
					pauseButton: 	( typeof arguments[0]['pauseButton'] 	!= 'undefined' ? 	arguments[0]['pauseButton'] 	: 	this.opts.pauseButton ),
					nextButton: 	( typeof arguments[0]['nextButton'] 	!= 'undefined' ? 	arguments[0]['nextButton'] 		: 	this.opts.nextButton ),
					prevButton: 	( typeof arguments[0]['prevButton'] 	!= 'undefined' ? 	arguments[0]['prevButton'] 		: 	this.opts.prevButton ),
					defaultAnchor: 	( typeof arguments[0]['defaultAnchor'] 	!= 'undefined' ? 	arguments[0]['defaultAnchor'] 		: 	document.body )
				};
			}
						
			
			this.opts.defaultSoundID = 'sound_'+parseInt( Math.random(10) * 10000 );

			// NOW ADD YOURSELF TO THE REGISTRY
			if ( ! PLAY_PEN.add( this.opts.defaultSoundID, this ) ) {
				throw 'Failed to add player to the registry, you must use a unique defaultSoundID.';
			}

 			this.play = this._play.bindAsEventListener(this);
 			this.pause = this._pause.bindAsEventListener(this);
 			this.play_song_callback = this._play_song_callback.bindAsEventListener(this)

			this._handle_state_change('initialized');
		},
		currentSound: function() {  /// reference to the current SoundManager SMSound object being played
			return soundManager.getSoundById(this.opts.defaultSoundID);
		},
		play_song: function(media_id) { // handle a request to play a given MEDIA ID
						// includes:  	retreiving song data from server 
						//		honoring place data passed (where in song to play FROM)
						//		generating/destroying soundmanager object in play
						//		calling the state_change handler (which will render)
			var obj = this;
			if ( ! media_id || media_id != this.currentMediaID ) {
				this._retrieve_song_data( media_id, function() { obj._play() });
			} else if ( media_id == this.currentMediaID  ) { // play but starting from beginning
				this._play(null,0);
			} else { // just start it
				this._play();
			}
		},
		_stop: function() {
/*
			if ( this.currentSound() )
				this.currentSound().stop();
*/
			this._unload_current_song();
		},
		
/*
		_set_position: function(pos) {
			this.currentSound().setPosition(pos);
		},
*/
		_is_playing: function() {
				return ( this.currentSound() && this.currentSound().playState && ! this.currentSound().paused )
		},
		_pause: function(e) {
			this.currentSound().pause();
		},
		_play: function(e,position) {

			if ( this.currentSound() && typeof this.currentSound().playState != 'undefined' )  {
				if ( typeof position != 'undefined' && parseInt(position) != 'NaN' )  {
					this.currentSound().setPosition(position);
					this.currentSound().play();
				} else {
					if ( ! this._is_playing() )
						this.currentSound().play();
					else
						this.currentSound().pause();
				}
			}

		},
		_mute:function(e) {
			this.currentSound().mute();
		},
		_unmute:function(e) {
			this.currentSound().unmute();
		},
		_play_song_callback: function (song_info) { 
			//part 2, where data about the song is returned from the server, and we continue the execution
			var obj = this;
			this._unload_current_song();
			this.__currentSongInfo = song_info;
			this.currentMediaID = song_info.id;
			this.currentSongTitle = song_info.title;
			this.currentSongArtist = song_info.artist;
			this.currentAlbumArtURL = ALBUM_ART_URL + ( Object.isString(song_info.id) ? song_info.id : '' ).substr(0,5) + '00000.JPG';
			this.currentMediaURL = MEDIA_SOURCE_URL + song_info.id+'.mp3';
			if ( ! soundManager.canPlayURL( this.currentMediaURL ) ) {
				this.error('Can\'t play: '+this.currentMediaURL);
				return;
			}
			
			soundManager.createSound({
			    id: obj.opts.defaultSoundID,
			    url: obj.currentMediaURL,
					volume: obj.opts.defaultVolume,
			        stream: ( obj.opts.waitForSongLoad ? false : true ),
			        autoLoad: ( obj.opts.waitForSongLoad ? true : false ),
			        autoPlay: ( obj.opts.waitForSongLoad ? true : false ),
					onload: function() { 
            if ( obj.opts.waitForSongLoad )
              this.play();

						PLAY_PEN.get(this.sID)._handle_state_change('loaded');
					},
					onplay: function() {
						PLAY_PEN.get(this.sID)._handle_state_change('played');
					},
					whileplaying: function() {
						PLAY_PEN.get(this.sID)._handle_state_change('playing');
					},
					whileloading:function() {
						PLAY_PEN.get(this.sID)._handle_state_change('loading');	
					},
					onpause: function() {
						PLAY_PEN.get(this.sID)._handle_state_change('paused');
					},
					onresume: function() {
						PLAY_PEN.get(this.sID)._handle_state_change('resumed');
					},
					onstop: function() { //stop explicitly called
						PLAY_PEN.get(this.sID)._handle_state_change('stopped');
					},
					onfinish: function() {
						PLAY_PEN.get(this.sID)._handle_state_change('finished');
					}
			});
			
 			this.render(); 
		},
		_unload_current_song: function() {
			this.__currentSongInfo = null;
			this.currentMediaID = null;
			this.currentSongArtist = null;
			this.currentSongTitle = null;
			this.currentAlbumArtURL = null;
			this.currentMediaURL = null;
/* 			this.currentPlaylistName = null; */

			if ( this.currentSound() && typeof this.currentSound().sID != 'undefined' )  {
//				var csID = ;
				soundManager.destroySound(this.currentSound().sID); //stops, unloads, and destroys
			}
		},
		_handle_state_change: function(state) { // should be called whenever the 'state' of the player has changed.
			// state == initialized, playing, buffering, etc...
		},
		_handle_error: function() {

		},
		render: function(state,playerDom) {  //draws the current player

		},
		_retrieve_song_data: function(media_id, callback) {  //gathers data object for the song from server about to be played 
			var docallback = function(sound_id,dat,stat) {
				PLAY_PEN.get(sound_id).play_song_callback(dat);
				if ( typeof callback == 'function' )
					callback(dat);
			};

			if ( ! media_id || media_id == null ) {
				if ( SOUNDMANAGER_LOADED ) {
						docallback(this.opts.defaultSoundID,{});
				} else {
						soundManager.onready(docallback.curry(this.opts.defaultSoundID,{}));
				}
			} else {
				new Ajax.Request('/AjaxHandlers/SongInfo/get_song/'+media_id+'.json', {
							method: 'GET',
							parameters: { 'sID':this.opts.defaultSoundID + ''},
							onComplete: function (trans) { 
								var sID = trans.request.parameters.sID;
								var ret = ( trans.responseText ? trans.responseText : '{}' ).evalJSON(true);
								
								/*PLAY_PEN.get(sID).play_song_callback(ret);
								if ( typeof callback == 'function' )
									callback(ret);*/
									
								if ( SOUNDMANAGER_LOADED ) {
										docallback(sID,ret);
								} else {
										soundManager.onready(docallback.curry(sID,ret));
								}									
							},
							onFailure: function () { },
							onException: function(req,e) {
								if ( typeof console != 'undefined' )
									console.log(e);
								//else 
									//alert( e.number+' : '+e.name+' :: '+ e.message );
							}
					});
			}
		},
		error:function(msg) {
			if ( typeof console != 'undefined' )
				console.log('ERROR: '+message);
		}
	});
