(function($) {

    $.fn.xprMediaPlayer = function( method ) {
        // Method calling logic
        if ( methods[method] ) {
          return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
        } else if ( typeof method === 'object' || ! method ) {
          return methods.init.apply( this, arguments );
        } else {
          $.error( 'Method ' +  method + ' does not exist on jQuery.xprMediaPlayer' );
        }    

    };

    var settings = {
        controls: false,
        removePlayed: true,
        autoAdvance: true,
        height: 720,
        width: 1280,
        loopPlaylist: false // if yes overrides removePlayed
    }

    var methods = {
        init: function (options) {
            this.data('playlist', []);
            this.data('videos', []);
            this.data('playbackPosition', 0);
            this.data('queuePosition', 0);
            settings = $.extend({}, settings, options);
        },
        play: function() {
            methods.log('play()');
            //this.xprMediaPlayer('currentVideo')[0].play();
            this.xprMediaPlayer('currentVideo').jPlayer('play');
            var audioPlayer = this.data('audioPlayer');
            if (audioPlayer) {
                audioPlayer.jPlayer('play');
            }
        },
        pause: function() {
            //this.xprMediaPlayer('currentVideo')[0].pause();
            this.xprMediaPlayer('currentVideo').jPlayer('pause');
            var audioPlayer = this.data('audioPlayer');
            if (audioPlayer) {
                audioPlayer.jPlayer('pause');
            }
        },
        mute: function() {
            var audioPlayer = this.data('audioPlayer');
            if (audioPlayer) {
                audioPlayer.jPlayer('mute');
            }
        },
        unmute: function() {
            var audioPlayer = this.data('audioPlayer');
            if (audioPlayer) {
                audioPlayer.jPlayer('unmute');
            }
        },
        log: function(msg) {
            if (window.console) {
                console.log(msg);
            }
        },
        destroy: function() {
            methods.log('destroying media player');
            this.unbind('.xprMediaPlayer');
            //this.find('video').unbind('.xprMediaPlayer');
        },
        addAudioTrack: function(formats) {
            this.data('hasAudio', true);
            this.data('audioTrack', formats);
        },
        setPlaylist: function(list) {
            this.data('playlist', list);
            methods.log('setting playlist');
        },
        addVideo: function(file_obj) {
            var playlist = this.data('playlist');
            playlist.push(file_obj);   
            this.data('playlist', playlist);
        },
        getVideo: function(index) {
            var videos = this.data('videos');
            if (videos.length > index) {
                return videos[index];
            } else {
                methods.log('attempted to retrieve video out of bounds, index#: ' + index);
            }
        },
        currentVideo: function() {
            var playbackPosition = this.data('playbackPosition');
            //var clip = $('video[rel=clip' +playbackPosition+ ']', this);
            var clip = this.data('videos')[playbackPosition];
            return clip;
        },
        nextVideo: function() {
            var playbackPosition = this.data('playbackPosition') + 1;
            var clip = this.data('videos')[playbackPosition];
            //var clip = $('video[rel=clip' + playbackPosition + ']', this);
            return clip;
        },
        currentPlaylistId: function() {
            var playbackPosition = this.data('playbackPosition');
            return playbackPosition;
        },
        getAudio: function() {
            return $('audio', this)[0];
        }, 
        loadPlaylist: function(url) {
            methods.log('loading playlist: ' + url);
            $.ajax({
                url: url,
                method: 'GET',
                context: this,
                dataType: 'json',
                success: function(data) {
                    this.xprMediaPlayer('setPlaylist', data.videos);
                    this.trigger('playlistLoaded');
                },
                error: function(data) {
                    methods.log('could not load playlist');   
                    methods.log(data.responseText);
                }
            });
        },
        addAudioObject:function(audioTrack) {
            var self = this;
            var player = $('<div></div>');
            player.css('height', 0);
            methods.log('adding audio track');
            this.append(player);
            player.jPlayer({
                ready: function() {
                    $(this).jPlayer("setMedia", {
                        mp3: audioTrack.mp3,
                        oga: audioTrack.ogg
                    });
                },
                swfPath: "/includes/libs/js/jplayer/",
                preload: "auto",
                supplied: "mp3, oga"
            });
            this.data('audioPlayer', player);
            return player;
        },
        addVideoObject:function(video) {
            var self = this;
            var player = $('<div></div>');
            var queuePosition = this.data('queuePosition');
            //player.css('height', 0);
            //player.css('width', settings.width);
            player.attr("rel", "clip" + queuePosition);
            methods.log('adding video id#' + queuePosition);
            this.append(player);
            player.jPlayer({
                ready: function() {
                    $(this).jPlayer("setMedia", {
                        m4v: video['filename_mov'],
                        ogv: video['filename_ogg']
                    });
                },
                swfPath: "/includes/libs/js/jplayer/",
                preload: "auto",
                supplied: "m4v, ogv",
                size: {
                    height: settings.height,
                    width: settings.width
                }
            });
            if (video['loop']) {
                methods.log('Adding auto loop');
                player.bind($.jPlayer.event.ended, {}, function() {
                  this.jPlayer('play');
                });
            }  else {
                player.bind($.jPlayer.event.ended, {}, function() {
                  self.xprMediaPlayer('playNextVideo'); 
                });
            }
            var videos = this.data('videos');
            videos.push(player);
            return player;
        },
        startVideo: function(index) {
            methods.log('starting video id#' + index);
            var clip = this.xprMediaPlayer('getVideo', index);
            clip.css('height', settings.height);

            this.data('playbackPosition', index);

            this.xprMediaPlayer('play');
        },

        endVideo: function() {
            var playbackPosition = this.data('playbackPosition');
            var clip = this.xprMediaPlayer('getVideo', playbackPosition);
            //clip.unbind('ended.xprMediaPlayer');
            //clip.hide();
            clip.css('height', 0);
            clip.jPlayer('pause');
            //clip[0].pause();
            //clip[0].currentTime = 0;
            if (!settings.loopPlaylist && settings.removePlayed) {
                methods.log('removing clip: ' + playbackPosition);
                clip.remove();
            }
        },

        playNextVideo: function() {
            var playlist = this.data('playlist');
            var playbackPosition = this.data('playbackPosition');
            if (playbackPosition >= playlist.length - 1) {
                if (settings.loopPlaylist) {
                    methods.log('looping playlist');
                    this.xprMediaPlayer('endVideo');
                    playbackPosition = 0;
                } else {
                    return this.xprMediaPlayer('playlistOver');
                }
            } else {
                try {
                    this.xprMediaPlayer('endVideo');
                } catch (error) {
                    methods.log('error ending video: ' + error);
                }
                playbackPosition++;
            }

            this.data('playbackPosition', playbackPosition);
            this.xprMediaPlayer('startVideo', playbackPosition);
        },

        queueNextVideo: function() {
            var playlist = this.data('playlist');
            var queuePosition = this.data('queuePosition');
            if (queuePosition < playlist.length) {
                var nextClip = this.xprMediaPlayer('addVideoObject', playlist[queuePosition]);
                queuePosition++;
                this.data('queuePosition', queuePosition);
                return nextClip;
            } else {
                methods.log('All clips queued');
                this.trigger('bufferingComplete');
                //clearTimeout(this.data('queueTimer'));
                return false;
            }
        },
        
        intervalBuffer: function() {
            // use a simple fixed rate timer to load videos
            var self = this;
            //var queueTimer = setInterval(function() { self.xprMediaPlayer('queueNextVideo');  }, 2500);
            var video = this.xprMediaPlayer('queueNextVideo'); 
            if (video) {
                setTimeout(function() {  self.xprMediaPlayer('intervalBuffer'); }, 2500);
            }
            //this.data('queueTimer', queueTimer);
        },
        progressBuffer: function() {
            // use firefox's custom progress event for monitoring 
        },
        standardsBuffer: function() {
            // use standards compliant buffered attribute for monitoring
            var self = this;
            var bufferTimer = setTimeout(function() { self.xprMediaPlayer('standardsBuffer');  }, 200);
            this.data('queueTimer', bufferTimer);
            var video = $('video:last', this);
            try {
                if (video.length > 0 && video[0].networkState > 1) { 
                    video = video[0];
                    //xprLog("readyState:" + video.readyState + " networkState: " +  video.networkState + " duration:" + video.duration + " buffered: " + video.buffered.end());
                    //xprLog(video.buffered);
                    //xprLog(video.buffered.end(''));
                    if (video.readyState == 4 || (video.duration == video.buffered.end())) {
                        var currentBuffer = this.data('bufferDuration');
                        this.data('bufferDuration', currentBuffer + video.duration);
                        this.xprMediaPlayer('queueNextVideo');
                    }
                }
            } catch (error) {
                methods.log('error while buffering videos: ' + error);
            }
        },
        startBuffering: function() {
            this.xprMediaPlayer('queueNextVideo'); 
            this.xprMediaPlayer('intervalBuffer');
            this.xprMediaPlayer('addAudioObject', this.data('audioTrack'));
        },
        playlistOver: function() {
            methods.log('playlist ended');
            this.trigger('playlistEnded');
        },
        startPlayer: function() {
            methods.log('starting player');
            var self = this;
            var audioPlayer = this.data('audioPlayer');
            methods.log(audioPlayer);
            if (audioPlayer) {
                audioPlayer.jPlayer('play');
            }
            self.xprMediaPlayer('startVideo', 0);
        }
    };
})(jQuery);

