$j(function()
{	
	var win		= window,
	doc			= document,
	$win		= $j(win),
	
	template	= '<ul class="AudioPlayerV1 APV1_wrapper"><li><div class="APV1_play_button"></div></li><li><div class="APV1_seperator APV1_for_play"></div></li><li><div class="APV1_time_text">00:00</div></li><li><div class="APV1_seperator APV1_for_time"></div></li><li class="APV1_container"><div class="APV1_progress_bar_container"><div class="APV1_seek_bar"><div class="APV1_play_bar APV1_transition"></div></div></div></li><li><div class="APV1_seperator APV1_for_duration"></div></li><li><div class="APV1_duration_text">00:00</div></li><li><div class="APV1_seperator APV1_for_volume"></div></li><li><div class="APV1_volume_button"></div></li><li><div class="APV1_volume_bar_container"><div class="APV1_volume_bar"></div></div></li></ul>',

	PROCENT		= '%',
	TRANSITION	= 'APV1_transition',
	PLAYING		= 'APV1_playing',
	MUTE		= 'APV1_mute',
	ERROR		= 'APV1_error',
	IMPORTANT	= '0 !important',

	index		= 0,
	lib = [];
		
	function pauseAll(current)
	{
		$j(lib).each(function()
		{
			if(current != this && !this.paused && this.pause)
				this.pause();
		});
	}
	
	function getTime(time)
	{
		var rem = parseInt(time, 10),
		mins = Math.floor(rem / 60,10),
		secs = rem - mins*60;
				
		if(mins < 10)mins = '0' + mins;
		if(secs < 10)secs = '0' + secs;
		
		return mins + ':' + secs;
	}
	
	function createCookie(name,value,days)
	{
		if(days)
		{
			var date = new Date();
				date.setTime( date.getTime() + (days*86400000) );
				
			var expires = '; expires=' + date.toGMTString();
		}
		else var expires = '';
		
		doc.cookie = name + "=" + value+expires + "; path=/";
	}

	function readCookie(name)
	{
		var nameEQ = name + "=";
		var ca = doc.cookie.split(';');
		
		for(var i=0;i < ca.length;i++)
		{
			var c = ca[i];
			
			while (c.charAt(0)==' ')
				c = c.substring(1,c.length);
			
			if (c.indexOf(nameEQ) == 0)
				return c.substring(nameEQ.length,c.length);
		}
		return null;
	}
	
	function setVolumeState(id, volume)
	{
		if(win.localStorage !== null)
		{
			try { localStorage.setItem(id, volume); }
			catch(e){}
		}
		else
		{
			createCookie('vol_'+id, volume, 30);
		}
	}
	
	function getVolumeState(id)
	{
		if(win.localStorage !== null)
		{
			try { return localStorage.getItem(id); }
			catch(e){}
		}
		else
		{
			return readCookie('vol_'+id);
		}
	}

	
	$j(doc).ready(init);
	
	function init()
	{
		$j('audio.AudioPlayerV1').AudioPlayerV1();
	}
		
	$j.fn.AudioPlayerV1 = function(options)
	{
		var opt = $j.extend({}, $j.fn.AudioPlayerV1.defaultOptions, options);
		
		$j(this).each(function()
		{
			var audio = this,
				$audio = $j(audio);
			
			if(!$audio.is('audio'))return;
			
			var id = index++,
				offset = 0,
				time = 0,
				seeking = false,
				width = $audio.attr('width'),
				height = $audio.attr('height'),
				w = width ? width : opt.width,
				h = height ? height : opt.height,
			
			controls		= $j(template)
							.mousedown(false)
							.width(w)
							.height(h),
								
			playButton		= controls.find('.APV1_play_button'),
			
			timeText		= controls.find('.APV1_time_text'),
			
			container		= controls.find('.APV1_container'),
			progressCon		= controls.find('.APV1_progress_bar_container'),
			seekBar			= controls.find('.APV1_seek_bar'),
			playBar			= controls.find('.APV1_play_bar'),
			
			durationText	= controls.find('.APV1_duration_text'),
			
			volumeButton	= controls.find('.APV1_volume_button'),
			volumeCon		= controls.find('.APV1_volume_bar_container'),
			volumeBar		= controls.find('.APV1_volume_bar');
			
			
			checkAttributes();
			
			$audio.after(controls);
			$audio.removeAttr('controls').css({height:IMPORTANT, width:IMPORTANT});

			setContainerWidth();
			
			
			if(!audio.canPlayType)
			{
				error('Please upgrade your browser.');
				return;
			}
			
			
			
			if(audio.networkState && audio.currentSrc)
				init();
			else if($j('source', $audio).get(0))
				$audio.bind('loadstart', init);
			else
				error('Audio file not found.');
	
	
			function init()
			{
				if(!audio.currentSrc)
				{
					error('Audio file not found.');
					return;
				}
				
				
				var vol = getVolumeState(id);
								
				if(vol != null) audio.volume = vol;
				else vol = audio.volume;
				
				setVolumeView(vol);
				
				
				$audio
				.bind('timeupdate',		timeupdate)
				.bind('progress',		progress)
				.bind('volumechange',	volumechange)
				.bind('durationchange',	durationchange)
				.bind('playing',		play)
				.bind('pause',			pause)
				.bind('ended',			ended)
				.bind('canplay',		canplay)
				.bind('error',			error);
				
				playButton.click(loadSound);
				
				volumeCon.mousedown(volumeDown);
				volumeButton.click(muteToggle);
				
				lib[id] = audio;
			}
			
			function checkAttributes()
			{
				if(!ifAttr('data-time'))
				{					
					timeText.hide();
					controls.find('.APV1_for_time').hide();
				}

				if(!ifAttr('data-duration'))
				{
					durationText.hide();
					controls.find('.APV1_for_duration').hide();
				}

				if(!ifAttr('data-volume'))
				{
					volumeButton.hide();
					volumeCon.hide();
					controls.find('.APV1_for_volume').hide();
				}
			}
			
			function ifAttr(attr)
			{
				var val = $audio.attr(attr);
				
				if(val)
				{
					if(val == 'false' || val == 'off' || val == 'no')
						return false;
						
					else if(val == 'true' || val == 'on' || val == 'yes')
						return true;
				}
				
				return opt[attr];
			}
			
			function setContainerWidth()
			{	
				var widthMin = 0;
				controls.find('li:not(.APV1_container)').each(function()
				{
					widthMin += $j(this).width();					
				});
								
				if(widthMin > w)
				{
					$j(window).load(setContainerWidth);
					return;
				}
				
				container.width(w - widthMin);
			}
			
			function canplay()
			{
				$audio.unbind('canplay', canplay);
				
				seekBar.mousedown(seekDown);
				playButton.unbind('click', loadSound).click(playToggle);
			}
			
			function loadSound()
			{
				audio.preload = "auto";
				audio.play();
				
				playButton.unbind('click', loadSound);
			}
			
			function playToggle()
			{
				if(audio.paused || audio.ended) 
				{
					audio.play();
					controls.addClass(PLAYING);
				}
				else 
				{
					audio.pause();
					controls.removeClass(PLAYING);
				}
			}
			
			function muteToggle()
			{
				if(audio.volume) audio.volume = 0;
				else audio.volume = 1;
			}
						
			function volumeDown(e)
			{
				offset = volumeCon.offset().left;
												
				audio.volume = (e.pageX - offset) / volumeCon.width();
				
				$win.mousemove(volumeMove);
				$win.mouseup(volumeUp);
										
				return false;
			}

			function volumeUp()
			{				
				$win.unbind('mousemove', volumeMove);
				$win.unbind('mouseup', volumeUp);				
			}
			
			function volumeMove(e)
			{
				var pos = (e.pageX - offset) / volumeCon.width();
				
				if(pos > 1) 		pos = 1;
				else if(pos < 0)	pos = 0;

				audio.volume = pos;
			}
						
			function seekDown(e)
			{
				seeking = true;
				offset = seekBar.offset().left;
				
				var pos = (e.pageX - offset) / progressCon.width();
				
				audio.pause();
				time = audio.duration * pos;
				
				playBar.removeClass(TRANSITION).width(pos * 100 + PROCENT);
				
				timeText.text(getTime(time));
				
				$win.mousemove(seekMove);
				$win.mouseup(seekUp);
								
				return false;
			}
			
			function seekUp()
			{
				seeking = false;
				playBar.addClass(TRANSITION);
				
				$win.unbind('mousemove', seekMove);
				$win.unbind('mouseup', seekUp);
				
				audio.currentTime = time;
				audio.play();
			}
			
			function seekMove(e)
			{
				var pos = (e.pageX - offset) / progressCon.width();
				
				if(pos > 1) 		pos = 1;
				else if(pos < 0)	pos = 0;

				playBar.width(pos * 100 + PROCENT);
				time = audio.duration * pos;
				
				timeText.text(getTime(time));
			}
			
			function timeupdate()
			{
				if(seeking)return;
				
				var pos = audio.currentTime / audio.duration;
				
				if(pos > 1) 		pos = 1;
				else if(pos < 0)	pos = 0;
				
				playBar.width(pos * 100 + PROCENT);
				
				timeText.text(getTime(audio.currentTime));				
			}
						
			function progress()
			{
				if(audio.buffered && audio.duration)
					seekBar.width(audio.buffered.end(0) / audio.duration * 100 + PROCENT);
			}
			
			function volumechange()
			{
				var vol = audio.volume;
				
				setVolumeView(vol);
				setVolumeState(id, vol);
			}
			
			function setVolumeView(volume)
			{
				volumeBar.width(volume * 100 + PROCENT);
				
				if(volume)controls.removeClass(MUTE);
				else controls.addClass(MUTE);
			}
			
			function durationchange()
			{
				durationText.text(getTime(audio.duration));
			}
						
			function play()
			{
				if(seeking)return;
				
				pauseAll(audio);
				controls.addClass(PLAYING);
			}
			
			function pause()
			{
				if(seeking)return;
				controls.removeClass(PLAYING);
			}
			
			function ended()
			{
				controls.removeClass(PLAYING);
			}
			
			function error(msg)
			{
				if(typeof msg != 'string')
					msg = 'An error occurred.';
				
				playButton.unbind();
				controls.addClass(ERROR);
				timeText.show().text(msg);
			}
		});
		
		return this;
	};
	
	$j.fn.AudioPlayerV1.defaultOptions = {
		width: 300,
		height: 29,
		'data-time': true,
		'data-volume': true,
		'data-duration': true
	};
	
});
