jQuery(function($)
{	
	var win		= window,
	doc			= document,
	$win		= $(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)
	{
		$(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);
		}
	}


	$(doc).ready(init);

	function init()
	{
		$('audio.AudioPlayerV1').AudioPlayerV1();
	}

	$.fn.AudioPlayerV1 = function(options)
	{
		var opt = $.extend({}, $.fn.AudioPlayerV1.defaultOptions, options);

		$(this).each(function()
		{
			var audio = this,
				$audio = $(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		= $(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($('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 += $(this).width();					
				});

				if(widthMin > w)
				{
					$(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;
	};

	$.fn.AudioPlayerV1.defaultOptions = {
		width: 300,
		height: 29,
		'data-time': true,
		'data-volume': true,
		'data-duration': true
	};

});
