/**
 * flowplayer.controls 3.0.2. Flowplayer JavaScript plugin.
 *
 * This file is part of Flowplayer, http://flowplayer.org
 *
 * Author: Tero Piirainen, <info@flowplayer.org>
 * Copyright (c) 2008 Flowplayer Ltd
 *
 * Dual licensed under MIT and GPL 2+ licenses
 * SEE: http://www.opensource.org/licenses
 *
 * Date: 2008-11-25 11:29:03 -0500 (Tue, 25 Nov 2008)
 * Revision: 1424
 */
$f.addPlugin("controls", function(wrap, options) {


//{{{ private functions

	function fixE(e) {
		if (typeof e == 'undefined') {e = window.event;}
		if (typeof e.layerX == 'undefined') {e.layerX = e.offsetX;}
		if (typeof e.layerY == 'undefined') {e.layerY = e.offsetY;}
		return e;
	}

	function w(e) {
		return e.clientWidth;
	}

	function offset(e) {
		return e.offsetLeft;
	}

	/* a generic dragger utility for hoirzontal dragging */
	function Draggable(o, min, max, offset) {

		var dragging = false;

		function foo() { }

		o.onDragStart	= o.onDragStart || foo;
		o.onDragEnd		= o.onDragEnd 	 || foo;
		o.onDrag			= o.onDrag 		 || foo;

		function move(x) {
			// must be withing [min, max]
			if (x > max) {return false;}
			if (x < min) {return false;}
			o.style.left = x + "px";
			return true;
		}

		function end() {
			document.onmousemove = null;
			document.onmouseup   = null;
			o.onDragEnd(parseInt(o.style.left, 10));
			dragging = false;
		}

		function drag(e) {
			e = fixE(e);
			var x = e.clientX - offset;
			if (move(x)) {
				dragging = true;
				o.onDrag(x);
			}
			return false;
		}

		o.onmousedown = function(e)  {
			e = fixE(e);
			o.onDragStart(parseInt(o.style.left, 10));
			document.onmousemove		= drag;
			document.onmouseup		= end;
			return false;
		};

		this.dragTo = function(x) {
			if (move(x)) {
				o.onDragEnd(x);
			}
		};

		this.setMax = function(val) {
			max = val;
		};

		this.isDragging = function() {
			return dragging;
		};

		return this;
	}

	function extend(to, from) {
		if (from) {
			for (key in from) {
				if (key) {
					to[key] = from[key];
				}
			}
		}
	}

	function byClass(name) {
		var els = wrap.getElementsByTagName("*");
		var re = new RegExp("(^|\\s)" + name + "(\\s|$)");
		for (var i = 0; i < els.length; i++) {
			if (re.test(els[i].className)) {
				return els[i];
			}
		}
	}

	// prefix integer with zero when nessessary
	function pad(val) {
		val = parseInt(val, 10);
		return val >= 10 ? val : "0" + val;
	}

	// display seconds in hh:mm:ss format
	function toTime(sec) {

		var h = Math.floor(sec / 3600);
		var min = Math.floor(sec / 60);
		sec = sec - (min * 60);

		if (h >= 1) {
			min -= h * 60;
			return pad(h) + ":" + pad(min) + ":" + pad(sec);
		}

		return pad(min) + ":" + pad(sec);
	}

	function getTime(time) {
		return toTime(time);
	}

        function sound(level) {
            if (level != null) {
                if (level == 0) {
                    $("div." + opts.soundClass + " a").removeClass("active");
                } else {
                    var number = Math.round(level / 100 * 8);
                    $("div." + opts.soundClass + " a:lt(" + number + ")").addClass("active");
                    $("div." + opts.soundClass + " a:gt(" + number + ")").removeClass("active");
                }
            } else {
                level = Math.round($("div." + opts.soundClass + " a.active").length / 8 * 100);
            }
            return level;
        }

//}}}


	var self = this;
        var volume = 50;

	var opts = {
		playHeadClass: 'playhead',
		trackClass: 'track',
		playClass: 'play',
		pauseClass: 'pause',
		bufferClass: 'buffer',
		progressClass: 'progress',

		timeClass: 'time',
		durationClass: 'duration',
		fullscreenClass: 'fullscreen',
		muteClass: 'mute',
		unmuteClass: 'unmute',
		soundClass: 'sound',
		duration: 0,

		template: '<a  href="#"class="play"></a>' +
                                        '<div class="time"></div>' +
					 '<div class="track">' +
					 	'<div class="buffer"></div>' +
					 	'<div class="progress"></div>' +
					 	'<div class="playhead"></div>' +
					 '</div>' +
					 '<div class="duration"></div>' +
					 '<a href="#" class="fullscreen"></a>' +
					 '<a  href="#"class="mute"></a>'
	};

	extend(opts, options);

	if (typeof wrap == 'string') {
		wrap = document.getElementById(wrap);
	}

	if (!wrap) {return;}

	// inner HTML
	//if (!wrap.innerHTML.replace(/\s/g, '')) {
                opts.template += '<div class="sound">';
                for(var i = 0; i < 8; i++) {
                    opts.template += '<a href="#" class="active"></a>';
                }
                opts.template += '</div>';
		wrap.innerHTML = wrap.innerHTML + opts.template;
	//}

	// get elements
	var ball = byClass(opts.playHeadClass);
	var bufferBar = byClass(opts.bufferClass);
	var progressBar = byClass(opts.progressClass);
	var track = byClass(opts.trackClass);
	var time = byClass(opts.timeClass);
	var duration = byClass(opts.durationClass);
	var fullscreen = byClass(opts.fullscreenClass);
	var mute = byClass(opts.muteClass);

	// initial time
	time.innerHTML = getTime(0, opts.duration);
	duration.innerHTML = getTime(opts.duration);

	// get dimensions
	var trackWidth = w(track);
	var ballWidth = w(ball);

	// initialize draggable playhead
	var head = new Draggable(ball, 0, 0, offset(wrap) + offset(track) + (ballWidth / 2));

	// track click moves playHead
	track.onclick = function(e) {
		e = fixE(e);
		if (e.target == ball) {return false;}
		head.dragTo(e.layerX - ballWidth / 2);
	};

	// play/pause button
	var play = byClass(opts.playClass);

	play.onclick = function() {
            if (self.isLoaded()) {
                self.toggle();
            } else {
                self.play();
            }
	};

	// mute/unmute button
	mute.onclick = function() {
            if (self.getStatus().muted)  {
                self.unmute();
            } else {
                self.mute();
            }
	};

        fullscreen.onclick = function () {
            self.pause();
            if (typeof(opts.onfullscreen) == "function") opts.onfullscreen(self);
            self.resume();
        }

        $("div." + opts.soundClass + " a").click(function () {
            var element = $(this);

            var previousElement = element.prevAll();
            previousElement.addClass("active");

            var number = previousElement.length + 1;

            element.addClass("active");
            element.nextAll().removeClass("active");

            volume = Math.round(number / 8 * 100);
            self.setVolume(volume);
        });

        sound(volume);

	// setup timer
	var timeTimer = null;


	function getMax(len, total) {
		var x = parseInt(len / total * trackWidth, 10);
		return isNaN(x) ? 0 : x;
	}

	self.onStart(function(clip) {
            var total = clip.duration || 0;
            duration.innerHTML = getTime(total);
            
            clearInterval(timeTimer);
            timeTimer = setInterval(function()  {
                try {
                    var status = self.getStatus();

                    // time display
                    if (status.time)  {
                            time.innerHTML = getTime(status.time);
                    }

                    if (status.time === undefined) {
                            clearInterval(timeTimer);
                            return;
                    }

                    // buffer width
                    var x = getMax(status.bufferEnd, total);
                    bufferBar.style.width = x + "px";
                    head.setMax(x);

                    // progress width
                    if (!self.isPaused() && !head.isDragging()) {
                            x = getMax(status.time, total);
                            progressBar.style.width = x + "px";
                            ball.style.left = (x -ballWidth / 2) + "px";
                    }
                } catch(error) {
                    clearInterval(timeTimer);
                    return;
                }
            }, 500);
	});

	self.onBegin(function() {
            play.className = opts.pauseClass;
	});

        self.onStop = function () {
            clearInterval(timeTimer);
            play.className = opts.playClass;
        }

	// pause / resume states
	self.onPause(function() {
            play.className = opts.playClass;
	});

	self.onResume(function() {
            play.className = opts.pauseClass;
	});

	// mute / unmute states
	self.onMute(function() {
            mute.className = opts.unmuteClass;
            volume = self.getVolume();
            sound(0);
	});

	self.onUnmute(function() {
            mute.className = opts.muteClass;
            sound(volume);
	});


	// clear timer when clip ends
	self.onFinish(function(clip) {
            clearInterval(timeTimer);
            play.className = opts.playClass;
	});

	self.onUnload(function() {
		time.innerHTML = getTime(0, opts.duration);
	});


	ball.onDragEnd = function(x) {
		var to = parseInt(x / trackWidth  * 100, 10) + "%";
		progressBar.style.width = x + "px";
		if (self.isLoaded()) {
			self.seek(to);
		}
	};

	ball.onDrag = function(x) {
		progressBar.style.width = x + "px";
	};

        this.unload = function () {
            clearInterval(timeTimer);
            $(wrap).remove();
        }

	// return player instance to enable plugin chaining
	return self;

});





