/**
* flowplayer.playlist 3.0.7. 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: 2009-02-16 06:51:28 -0500 (Mon, 16 Feb 2009)
* Revision: 1454 
*/
(function($) {

    $f.addPlugin("playlist", function(wrap, options) {


        // self points to current Player instance
        var self = this;

        var opts = {
            playingClass: 'playing',
            pausedClass: 'paused',
            progressClass: 'progress',
            template: '<a href="${url}">${title}</a>',
            loop: false,
            playOnClick: true,
            manual: false
        };

        $.extend(opts, options);
        wrap = $(wrap);
        var manual = self.getPlaylist().length <= 1 || opts.manual;
        var els = null;


        //{{{ "private" functions

        function toString(clip) {
            var el = template;

            $.each(clip, function(key, val) {
                if (!$.isFunction(val)) {
                    el = el.replace("$\{" + key + "\}", val).replace("$%7B" + key + "%7D", val);
                }
            });
            return el;
        }

        // assign onClick event for each clip
        function bindClicks() {
            els = wrap.children().unbind("click.playlist").bind("click.playlist", function() {
                return play($(this), els.index(this));
            });
        }

        function buildPlaylist() {
            wrap.empty();

            $.each(self.getPlaylist(), function() {
                wrap.append(toString(this));
            });

            bindClicks();
        }


        function play(el, clip) {

            if (el.hasClass(opts.playingClass) || el.hasClass(opts.pausedClass)) {
                self.toggle();

            } else {
                el.addClass(opts.progressClass);
                self.play(clip);
            }

            return false;
        }


        function clearCSS() {
            if (manual) { els = wrap.children(); }
            els.removeClass(opts.playingClass);
            els.removeClass(opts.pausedClass);
            els.removeClass(opts.progressClass);
        }

        function getEl(clip) {
            var url = clip.isInStream ? clip.parentUrl : clip.originalUrl;
            return (manual) ? els.filter("[href=" + url + "]") : els.eq(clip.index);
        }
        //}}}  

        /* setup playlists with onClick handlers */

        // internal playlist
        if (!manual) {

            var template = wrap.is(":empty") ? opts.template : wrap.html();
            buildPlaylist();


            // manual playlist
        } else {

            els = wrap.children();

            // allows dynamic addition of elements
            if ($.isFunction(els.live)) {
                $(wrap.selector + "> *").live("click", function() {
                    var el = $(this);
                    return play(el, el.attr("href"));
                });

            } else {
                els.click(function() {
                    var el = $(this);
                    return play(el, el.attr("href"));
                });
            }

            // setup player to play first clip
            var clip = self.getClip(0);
            if (!clip.url && opts.playOnClick) {
                clip.update({ url: els.eq(0).attr("href") });
            }

        }

        // onBegin
        self.onBegin(function(clip) {
            clearCSS();
            getEl(clip).addClass(opts.playingClass);
        });

        // onPause	
        self.onPause(function(clip) {
            getEl(clip).removeClass(opts.playingClass).addClass(opts.pausedClass);
        });

        // onResume
        self.onResume(function(clip) {
            getEl(clip).removeClass(opts.pausedClass).addClass(opts.playingClass);
        });

        // what happens when clip ends ?
        if (!opts.loop && !manual) {

            // stop the playback exept on the last clip, which is stopped by default
            self.onBeforeFinish(function(clip) {
                if (!clip.isInStream && clip.index < els.length - 1) {
                    return false;
                }
            });
        }

        // on manual setups perform looping here
        if (manual && opts.loop) {
            self.onBeforeFinish(function(clip) {
                if (clip.isInStream) { return; }

                var el = getEl(clip);
                if (el.next().length) {
                    el.next().click();
                } else {
                    els.eq(0).click();
                }
                return false;
            });
        }

        // onUnload
        self.onUnload(function() {
            clearCSS();
        });

        // onPlaylistReplace
        if (!manual) {
            self.onPlaylistReplace(function() {
                buildPlaylist();
            });
        }

        // onClipAdd
        self.onClipAdd(function(clip, index) {
            els.eq(index).before(toString(clip));
            bindClicks();
        });

        return self;

    });

})(jQuery);		

