function $each(iterable, fn, bind){
	if (iterable && typeof iterable.length == 'number' && $type(iterable) != 'object'){
		for(var i = 0; i < iterable.length; i++){
			fn.call(bind || iterable, iterable[i], i, iterable);
		}
	} else {
		 for (var name in iterable){
			fn.call(bind || iterable, iterable[name], name, iterable);
		}
	}
}
function $type(obj){
	if (!$defined(obj)) return false;
	if (obj.htmlElement) return 'element';
	var type = typeof obj;
	if (type == 'object' && obj.nodeName){
		switch(obj.nodeType){
			case 1: return 'element';
			case 3: return (/\S/).test(obj.nodeValue) ? 'textnode' : 'whitespace';
		}
	}
	if (type == 'object' || type == 'function'){
		switch(obj.constructor){
			case Array: return 'array';
			case RegExp: return 'regexp';
			case Class: return 'class';
		}
		if (typeof obj.length == 'number'){
			if (obj.item) return 'collection';
			if (obj.callee) return 'arguments';
		}
	}
	return type;
};

function $defined(obj){
	return (obj != undefined);
};


function $merge(){
	var mix = {};
	for (var i = 0; i < arguments.length; i++){
		for (var property in arguments[i]){
			var ap = arguments[i][property];
			var mp = mix[property];
			if (mp && $type(ap) == 'object' && $type(mp) == 'object') mix[property] = $merge(mp, ap);
			else mix[property] = ap;
		}
	}
	return mix;
};

function $extend(){
	var _args = arguments;
	for(var prop in _args[1]){
		_args[0][prop] = _args[1][prop];
	}
	return _args[0];
}
var Class = function(properties){
	var klass = function(){
		return (arguments[0] !== null && this.initialize && $type(this.initialize) == 'function') ? this.initialize.apply(this, arguments) : this;
	};
	$extend(klass, this);
	klass.prototype = properties;
	klass.constructor = Class;
	return klass;
};
Class.empty = function(){};

Class.prototype = {
	extend: function(properties){
		var proto = new this(null);
		for (var property in properties){
			var pp = proto[property];
			proto[property] = Class.Merge(pp, properties[property]);
		}
		return new Class(proto);
	},

	implement: function(){
		for (var i = 0, l = arguments.length; i < l; i++) $extend(this.prototype, arguments[i]);
	}

};



var ai = {
	each: $each,
	merge: $merge
}

ai.log = function(message){
		$id('ai_log').innerHTML += message+'<br />';
}


 ai.aitunes = function(options){
	
		this.sm = soundManager;
		var _this = this;
		this.playlist = [];
		this.order = [];
		this.position = null;
		this.song_id = null;
		this.state = 'stopped';
		this.options = ai.merge({
			path:'',
			autoPlay:false,
			volume: 50,
			shuffle: false,
			repeat: 'all'
		}, options);
		
		this.sm_options = {
			autoPlay:false,
			onfinish: function(){
				_this.onfinish();
			},
			whileplaying: function(){
				_this.whileplaying(this.position, this.durationEstimate);
			},
			whileloading: function(){
				_this.whileloading(this.bytesLoaded, this.bytesTotal);
			}, 
			onload:function(){
				_this.onload();
			}
		}

		this.loaded = [];

	
	//options
	this.setOptions = function(options){
		ai.each(options, function(value, option){
			this.options[option] = value;
		}, this);
 	}

	
	
	//playlist
	this.setPlaylist = function(playlist){
		this.playlist = playlist;
		this.order = this.options.shuffle ? this.shufflePlaylist(playlist) : playlist;
	}

	//shuffle
	this.toggleShuffle = function(){
		if(this.options.shuffle == true){
			this.order = this.playlist;
			this.options.shuffle = false;
		}else{
			this.order = this.shufflePlaylist(this.playlist);
			this.options.shuffle = false;
		}
		this.position = this.getPositionById(this.song_id);
	}
	
	//fisher-yates shuffle
	this.shufflePlaylist = function(playlist){
		var num_songs = playlist.length;
		var random_int; var tmp = null;
		
		while(num_songs > 1){
			random_int = Math.floor(Math.random()*num_songs);
			num_songs--;
			tmp = playlist[num_songs];
			playlist[num_songs] = playlist[random_int];
			playlist[random_int] = tmp;
		}
		return playlist;
	}
	
	
	//play pause stop
	this.playPosition = function(position){
		if(this.state == 'playing'){
			this.stop(this.order[this.position]);
		}		
		this.play(this.order[position]);
	}
	
	this.setPosition = function(position){
		this.last_id = this.song_id;
		this.position = parseInt(position);
		this.song_id = this.order[this.position];
		if(this.options.onsongchange){
			this.options.onsongchange(this.song_id, this.last_id);
		}
	}
	
	this.stop =  function(){
		this.sm.pause(this.song_id);
		this.sm.setPosition(this.song_id,0);
		this.state = 'stopped';
	}
	
	this.play = function(id){
		this.song_id = id;
		this.setPosition(this.getPositionFromId(id));
		this.loadAndPlay(id);
		if(this.options.onplay){
			this.options.onplay(id);
		}
		this.state = 'playing';
	}
	
	this.loadAndPlay = function(id, options){
		var url =  '/mp3.php?id='+id;
		var volume = this.options.volume;
		if(!this.loaded[id]){
			this.sm.createSound(ai.merge(this.sm_options, {'url':url, 'id':id, 'volume':volume}));
			this.loaded[id] = true;
		}else{
			this.sm.play(id);
		}
	}
	
	this.loadSound = function(id){
		var url =  '/mp3.php?id='+id;
		if(!this.loaded[id]){
			this.sm.createSound(ai.merge(this.sm_options, {'url':url, 'id':id,'autoPlay':false}));
			this.loaded[id] = true;
		}
	}
	
	this.getPositionFromId = function(id){
		var pos = null;
		ai.each(this.order, function(song_id, index){
			if(song_id == id){ pos = index; }
		});

		return pos;
	}
	
	this.togglePause= function(){
		if(this.state == 'playing'){
			this.pause();
		}else{
			this.resume();
		}
	}
	
	this.pause= function(){
		this.state = 'paused';
		this.sm.pause(this.song_id);
	}
	
	this.resume= function(){
		this.state = 'playing';
		this.sm.play(this.song_id);
	}
	
	//next previous song_position
	this.next= function(){
		var position = this.position + 1;
                if(position > this.playlist.length - 1){
                    position = 0;
                }
		this.playOrSetPosition(position);
	}
	
	this.previous= function(){
		if(this.song_position < 3000){
			var position = this.position - 1;
                        if(position < 0){
                            position = this.playlist.length - 1;
                        }
			this.playOrSetPosition(position);
		}else{
			this.skip(0);
		}
	}
	
	this.rewind= function(amount){
		this.sm.setPosition(this.song_id, this.sm.getSoundById(this.song_id).position - parseInt(amount || 2000));
	}
	
	this.fastForward= function(amount){
		this.sm.setPosition(this.song_id, this.sm.getSoundById(this.song_id).position + parseInt(amount || 2000));
	}
	
	this.skip= function(to_percent){
		this.sm.setPosition(this.song_id, (to_percent / 100 * this.duration ));
	}

	//volume
	this.setVolume= function(volume){
		this.options.volume = volume;
		this.sm.setVolume(this.song_id, volume);
	}
		
	//onXXXX actions
	this.onfinish= function(){
		if(this.options.onfinish){
			this.options.onfinish();
		}else{
			this.next();
		}
	}
	
	this.onload = function(){
		if(this.options.onload){
			this.options.onload();
		}
	}
	
	this.whileloading= function(loaded, total){
		if(this.options.whileloading){
			this.options.whileloading(loaded, total);
		}
		this.setVolume(this.options.volume);
	}
	
	this.whileplaying= function(position, total){
		this.song_position = position;
		this.duration = total
		if(this.options.whileplaying){
			this.options.whileplaying(position, total);
		}
		this.setVolume(this.options.volume);
		
	}
	
	this.playOrSetPosition= function(position){
		if(this.state == 'playing'){
			this.playPosition(position);
		}else{
			this.setPosition(position);
			this.loadSound(this.song_id);
		}
	}

};
function get_ids(songs){
	var ids = [];
	ai.each(songs, function(song){
		ids.push(song.id);
	});
	return ids;
}
function get_song(id){
	var song_obj = '';
	ai.each(songs, function(song){
		if(song.id == id){
			song_obj = song;
		}
	});
	return song_obj;
}



var aitunes  = new ai.aitunes({
	'onsongchange':function(id){
		document.getElementById('current_song').innerHTML = get_song(id).title;
	},
            shuffle:true
});

function start_aitunes(){
	aitunes.setPlaylist(get_ids(songs));
	aitunes.playPosition(0);
	aitunes.pause();
}	


