(function ($) {
    $.fn.nativeVideo = function (options) {
    
        var defaults = {
            width: 640,
            height: 360,
            mp4source: '',
            m4vsource: '',
            oggsource: '',
            webmsource: '',
            flashsource: '',
            flashplayerswf: '/swfs/FacebookMediaPlayer.swf',
            fullScreenCallback : function(){},
            volume: 1,
            onEnd: ''
        };
    
        var user_options = $.extend(defaults, options);
    
        return this.each(function (iter) {
      
            var embedParent = $(this);
            var percentVideoLoaded = 0;
            var videoState = 'paused';
            var videoVolumeLevel = defaults.volume;
      
            // stuff to be identifed and have listeners attatched
            var videoEmbed;
            var flashEmbed;
      
            var videoEmbed_controls;
            var videoEmbed_videoprogress;
            var videoEmbed_time;
            var videoEmbed_playpause;
            var videoEmbed_playpause_ident;
            var videoEmbed_volume;
            var videoEmbed_volumeident;
            var videoEmbed_volumerail;
            var videoEmbed_volumehandle;
            var videoEmbed_volumeslider;
            var videoEmbed_timetotal;
            var videoEmbed_timecurrent;
            var videoEmbed_timeslider;
            var videoEmbed_duration;
            var videoEmbed_currenttime;
            var videoEmbed_loadprogress;
            var videoEmbed_fullscreen;
            var videoEmbed_fullscreen_ident;
      
            var videoEmbed_bigplay;
            var videoEmbed_loadingAnimation;

            var browserOverflow;
            var browserHeight;
            var browserWidth;
            
            var isiPad = (navigator.userAgent.match(/iPad/i)) ? true : false;
            var isiPod = (navigator.userAgent.match(/iPod/i)) ? true : false;
            var isiPhone = (navigator.userAgent.match(/iPhone/i)) ? true : false;

            embedParent.html('');
            embedParent.css({
                "background": "#ffffff",
                "width": defaults.width + "px",
                "height": defaults.height + "px",
                "position": "relative"
            });
      
            function canPlaySource() {
                var children = videoEmbed.children;
                for (var i = 0, j = children.length; i < j; i++) {
                    if (children[i].tagName.toUpperCase() == "SOURCE") {
                        if (typeof videoEmbed.canPlayType != "undefined") {
                            var canPlay = videoEmbed.canPlayType(children[i].type);
                            if (canPlay == "probably" || canPlay == "maybe") {
                                return true;
                            }
                        }
                    }
                }
                return false;
            }
      
            function formatTime(seconds) {
                seconds = Math.round(seconds);
                minutes = Math.floor(seconds / 60);
                minutes = (minutes >= 10) ? minutes : "0" + minutes;
                seconds = Math.floor(seconds % 60);
                seconds = (seconds >= 10) ? seconds : "0" + seconds;
                return minutes + ":" + seconds;
            }
      
            function getComputedStyleValue(element, style) {
                return window.getComputedStyle(element, null).getPropertyValue(style);
            }
      
            function keyListener(e) {
                if (e.keyCode == 27) {
                    if (videoEmbed_fullscreen_ident.hasClass('full')) {
                        fullscreenToggle();
                    }
                } else if (e.keyCode == 32) {
                    e.preventDefault();
                    playPauseToggle();
                }
            }

            // cache browser size
            function browserSizes() {
                this.browserOverflow = getComputedStyleValue(document.getElementsByTagName('body')[0], "overflow");
                this.browserHeight = window.innerHeight;
                this.browserWidth = window.innerWidth;
                browserOverflow = this.browserOverflow;
                browserHeight = this.browserHeight;
                browserWidth = this.browserWidth;
            }
      
            function positionControls() {
                var controllerwidth = embedParent.width();
                videoEmbed_controls.css({
                    "left": "50%",
                    "width": controllerwidth + "px",
                    "margin": "0",
                    "margin-left": "-" + (controllerwidth / 2) + "px",
                    "bottom": "0"
                });
            }
            
            function setLoadProgress(percentAsDecimal) {
                if (percentAsDecimal > percentVideoLoaded) {
                    percentVideoLoaded = percentAsDecimal;
                    var newwidth = videoEmbed_timetotal.width() * percentVideoLoaded;
                    videoEmbed_loadprogress.width(newwidth);
                }
            }
      
            function setTimeWidth() {
                var newwidth = videoEmbed_controls.width() - (videoEmbed_volume.outerWidth(true) + videoEmbed_playpause.outerWidth(true) + videoEmbed_time.outerWidth(true) + videoEmbed_fullscreen.outerWidth(true)) - (videoEmbed_videoprogress.outerWidth(true) - videoEmbed_videoprogress.outerWidth(false));
                videoEmbed_videoprogress.width(newwidth);
                videoEmbed_timetotal.width(newwidth - 10);
                if (percentVideoLoaded === 1) {
                  videoEmbed_loadprogress.css("width", "100%");
                }
            }
      
            function windowResize() {
                if (videoEmbed_fullscreen_ident.hasClass('full')) {
                    videoEmbed_controls.show();
                    browserSizes();
                    embedParent.css({
                        "background": "#000000",
                        "width": browserWidth + "px",
                        "height": browserHeight + "px"
                    });
                    $(videoEmbed).css({
                        "width": browserWidth + "px",
                        "height": browserHeight + "px"
                    });
                    positionControls();
                    setTimeWidth();
                } else {
                    browserSizes();
                }
            }
      
            function playPauseToggle() {
                if (videoState == 'playing') {
                    videoEmbed.pause();
                } else if (videoState == 'paused') {
                    videoEmbed.play();
                }
            }
      
            function fullscreenToggle() {
                function goFull() {
                    browserSizes();
                    videoEmbed_fullscreen_ident.removeClass('normal');
                    videoEmbed_fullscreen_ident.addClass('full');
                    embedParent.css({
                        "background": "#000000",
                        "width": browserWidth + "px",
                        "height": browserHeight + "px",
                        "z-index": 20000,
                        "position": "absolute",
                        "left": 0,
                        "top": 0
                    });
                    $(videoEmbed).css({
                        "width": browserWidth + "px",
                        "height": browserHeight + "px"
                    });
                    document.getElementsByTagName('body')[0].style.overflow = "hidden";
                    positionControls();
                    setTimeWidth();
                    defaults.fullScreenCallback('full');
                }
                function goNorm() {
                    videoEmbed_fullscreen_ident.removeClass('full');
                    videoEmbed_fullscreen_ident.addClass('normal');
                    embedParent.css({
                        "background": "#ffffff",
                        "width": defaults.width + "px",
                        "height": defaults.height + "px",
                        "position": "relative"
                    });
                    $(videoEmbed).css({
                        "width": defaults.width + "px",
                        "height": defaults.height + "px"
                    });
                    document.getElementsByTagName('body')[0].style.overflow = "visible";
                    positionControls();
                    setTimeWidth();
                    defaults.fullScreenCallback('norm');
                }
                switch (typeof videoEmbed.webkitEnterFullScreen) {
                case "undefined":
                    if (videoEmbed_fullscreen_ident.hasClass('normal')) {
                        goFull();
                    } else {
                        goNorm();
                    }
                    break;
                case "function":
                    // one and only browser sniff to see if its chrome since most of it doesnt work yet.
                    var is_chrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
                    if (!is_chrome) {
                        videoEmbed.webkitEnterFullScreen(); 
                    } else {
                        if (videoEmbed_fullscreen_ident.hasClass('normal')) {
                            goFull();
                        } else {
                            goNorm();
                        }
                    }
                    break;
                }
            }
      
            function removeMouseMove() {
                $(document).unbind('mousemove', volumeMove).unbind('mouseup', removeMouseMove);
            }
      
            function positionVolumeHandle(volume) {
                var newTop = 45 - (45 * volume) - (12 / 2);
                videoEmbed_volumehandle.css({'top': newTop + "px"});
            }
      
            function setVolume(val) {
                if (val === 0) {
                    videoEmbed.volume = val;
                    if (videoEmbed_volumeident.hasClass('unmuted')) {
                        videoEmbed_volumeident.removeClass('unmuted');
                    }
                    if (!videoEmbed_volumeident.hasClass('muted')) {
                        videoEmbed_volumeident.addClass('muted');
                    }
                } else {
                    videoEmbed.volume = val;
                    positionVolumeHandle(val);
                    if (videoEmbed_volumeident.hasClass('muted')) {
                        videoEmbed_volumeident.removeClass('muted');
                    }
                    if (!videoEmbed_volumeident.hasClass('unmuted')) {
                        videoEmbed_volumeident.addClass('unmuted');
                    }
                }
            }
      
            function volumeMove(e) {
                var railHeight = videoEmbed_volumerail.height();
                // only allow it to move within the rail
                var newY = e.pageY - videoEmbed_volumerail.offset().top;
                if (newY < 0) {
                    newY = 0;
                } else if (newY > railHeight) {
                    newY = railHeight;
                }
                // calculate volume			
                var volume = (railHeight - newY) / railHeight;
                // make sure to check mute status
                setVolume(volume);
            }
      
            function createVideoControls() {
                videoEmbed_bigplay = document.createElement('div');
                videoEmbed_bigplay.className = "big_play_btn";
                embedParent.append(videoEmbed_bigplay);
        
                videoEmbed_loadingAnimation = document.createElement('div');
                videoEmbed_loadingAnimation.className = "blank";
                var theanimation = document.createElement('div');
                theanimation.className = "loading";
                videoEmbed_loadingAnimation.appendChild(theanimation);
                embedParent.append(videoEmbed_loadingAnimation);
                
                //
                videoEmbed_controls = document.createElement('ul');
                videoEmbed_controls.className = "nativeVideo_Controls";
                videoEmbed_controls.id = "nativeVideo_controls_" + iter;
                videoEmbed_playpause = document.createElement('li');
                videoEmbed_playpause.className = "nativeVideo_playPause";
                videoEmbed_playpause_ident = document.createElement("div");
                videoEmbed_playpause_ident.className = "paused";
                videoEmbed_playpause.appendChild(videoEmbed_playpause_ident);
                videoEmbed_controls.appendChild(videoEmbed_playpause);

                videoEmbed_videoprogress = document.createElement('li');
                videoEmbed_videoprogress.className = "video_progress_bar";
                
                videoEmbed_timetotal = document.createElement('span');
                videoEmbed_timetotal.className = "video_time_total";
                
                videoEmbed_loadprogress = document.createElement('span');
                videoEmbed_loadprogress.className = "video_time_loaded";
                
                videoEmbed_timecurrent = document.createElement('span');
                videoEmbed_timecurrent.className = "video_time_current";
                
                videoEmbed_timeslider = document.createElement('span');
                videoEmbed_timeslider.className = "video_time_slider";
                
                videoEmbed_timetotal.appendChild(videoEmbed_loadprogress);
                videoEmbed_timetotal.appendChild(videoEmbed_timecurrent);
                videoEmbed_timetotal.appendChild(videoEmbed_timeslider);
                videoEmbed_videoprogress.appendChild(videoEmbed_timetotal);
                videoEmbed_controls.appendChild(videoEmbed_videoprogress);

                videoEmbed_time = document.createElement('li');
                videoEmbed_time.className = "video_time";
                videoEmbed_currenttime = document.createElement('div');
                videoEmbed_currenttime.className = "video_currenttime";
                videoEmbed_currenttime.innerHTML = "00:00";
                var time_seperator = document.createElement('div');
                time_seperator.innerHTML = "/";
                videoEmbed_duration = document.createElement('div');
                videoEmbed_duration.className = "video_duration";
                videoEmbed_duration.innerHTML = "00:00";
                videoEmbed_time.appendChild(videoEmbed_currenttime);
                videoEmbed_time.appendChild(time_seperator);
                videoEmbed_time.appendChild(videoEmbed_duration);
                videoEmbed_controls.appendChild(videoEmbed_time);

                videoEmbed_volume = document.createElement('li');
                videoEmbed_volume.className = "video_volume";
                var vspan = document.createElement('div');
                vspan.className = "unmuted";
                videoEmbed_volumeslider = document.createElement('div');
                videoEmbed_volumeslider.className = "video_volume_slider";
                videoEmbed_volumerail = document.createElement('div');
                videoEmbed_volumerail.className = "video_volume_rail";
                videoEmbed_volumehandle = document.createElement('div');
                videoEmbed_volumehandle.className = "video_volume_handle";

                videoEmbed_volume.appendChild(vspan);
                videoEmbed_volumerail.appendChild(videoEmbed_volumehandle);
                videoEmbed_volumeslider.appendChild(videoEmbed_volumerail);
                videoEmbed_volume.appendChild(videoEmbed_volumeslider);
                videoEmbed_controls.appendChild(videoEmbed_volume);
                
                videoEmbed_fullscreen = document.createElement('li');
                videoEmbed_fullscreen.className = "video_fullscreen";
                var fs_div = document.createElement('div');
                fs_div.className = "video_fs normal";
                videoEmbed_fullscreen.appendChild(fs_div);
                videoEmbed_controls.appendChild(videoEmbed_fullscreen);
                embedParent.append(videoEmbed_controls);
        
                // declare items
                videoEmbed_controls = $('#nativeVideo_controls_' + iter);
                videoEmbed_videoprogress = videoEmbed_controls.find('.video_progress_bar');
                videoEmbed_time = videoEmbed_controls.find('.video_time');
                videoEmbed_playpause = videoEmbed_controls.find('.nativeVideo_playPause');
                videoEmbed_playpause_ident = videoEmbed_playpause.find('div');
                videoEmbed_timetotal = videoEmbed_controls.find('.video_time_total');
                videoEmbed_timecurrent = videoEmbed_controls.find('.video_time_current');
                videoEmbed_timeslider = videoEmbed_controls.find('.video_time_slider');
                videoEmbed_duration = videoEmbed_controls.find('.video_duration');
                videoEmbed_currenttime = videoEmbed_controls.find('.video_currenttime');
                videoEmbed_volume = videoEmbed_controls.find('.video_volume');
                videoEmbed_volumeident = videoEmbed_volume.find('div').eq(0);
                videoEmbed_volumerail = videoEmbed_volume.find('.video_volume_rail');
                videoEmbed_volumehandle = videoEmbed_volume.find('.video_volume_handle');
                videoEmbed_volumeslider = videoEmbed_volume.find('.video_volume_slider');
                videoEmbed_loadprogress = videoEmbed_controls.find('.video_time_loaded');
                videoEmbed_fullscreen = videoEmbed_controls.find('.video_fullscreen');
                videoEmbed_fullscreen_ident = videoEmbed_fullscreen.find('div').eq(0);
                
                videoEmbed_playpause_ident.bind('click', playPauseToggle);
        
                $(videoEmbed_bigplay).bind('click', playPauseToggle);
        
                videoEmbed_videoprogress.find('span').each(function () {
                    $("span", this).bind("click", function (e) {
                        e.preventDefault();
                        var x = e.pageX;
                        var offset = videoEmbed_timetotal.offset();
                        var width = videoEmbed_timetotal.outerWidth();
                        var percentage = ((x - offset.left) / width);
                        var newTime = percentage * videoEmbed.duration;
                        videoEmbed.currentTime = newTime;
                        return false;
                    });
                });
        
                videoEmbed_volume.bind('mouseover', function () {
                    videoEmbed_volumeslider.show();
                });
        
                videoEmbed_volume.bind('mouseout', function () {
                    videoEmbed_volumeslider.hide();
                });
        
                videoEmbed_volume.bind('click', function () {
                    if (videoEmbed.volume === 0) {
                        setVolume(0.65);
                    } else {
                        setVolume(0);
                    }
                });
        
                videoEmbed_volumeslider.bind('mousedown', function (e) {
                    volumeMove(e);
                    $(document).bind('mousemove', volumeMove).bind('mouseup', removeMouseMove);
                });
        
                videoEmbed_fullscreen_ident.bind('click', fullscreenToggle);
        
                $(window).bind('resize', function () {
                    windowResize();
                });

                $(document).bind('keydown', keyListener);

                embedParent.hover(function () { 
                    videoEmbed_controls.fadeIn(200);
                }, function () { 
                    videoEmbed_controls.fadeOut(200);
                });
        
                // fix widths of rails
                setTimeWidth();
                positionControls();
            }
            
            // this is where it all starts and the video embed gets created
            if (defaults.m4vsource !== "" || defaults.mp4source !== "" || defaults.oggsource !== "" || defaults.webmsource !== "") {
                videoEmbed = document.createElement('video');
                videoEmbed.width = defaults.width;
                videoEmbed.height = defaults.height;
                videoEmbed.preload = 'auto';
                videoEmbed.controls = 'controls';
                videoEmbed.tabIndex = '0';
                videoEmbed.id = 'nativeVideo_video_' + iter;
                videoEmbed.autoplay = true;
            }
            
            if (defaults.webmsource !== "") {
                var webmSource = document.createElement('source');
                webmSource.type = 'video/webm';
                webmSource.src = defaults.webmsource;
                videoEmbed.appendChild(webmSource);
            }
            
            if (defaults.mp4source !== "") {
                var mp4Source = document.createElement('source');
                mp4Source.type = 'video/mp4';
                mp4Source.src = defaults.mp4source;
                videoEmbed.appendChild(mp4Source);
            }
            
            if (defaults.oggsource !== "") {
                var oggSource = document.createElement('source');
                oggSource.type = 'video/ogg';
                oggSource.src = defaults.oggsource;
                videoEmbed.appendChild(oggSource);
            }
    
            if (jQuery.browser.msie) {
                flashEmbed = '<object width="' + defaults.width + '" height="' + defaults.height + '" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab" id="nativeVideo_flash_' + iter + '" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"><param value="' + defaults.flashplayerswf + '" name="movie"><param value="high" name="quality"><param value="sameDomain" name="allowScriptAccess"><param value="true" name="allowFullScreen"><param name="wmode" value="transparent"><param name="bgcolor" value="#ffffff"><param name="flashvars" value="url=' + defaults.flashsource + '&amp;type=flv&amp;bgColor=#ffffff&amp;bgAlpha=1"><embed width="' + defaults.width + '" height="' + defaults.height + '" align="middle" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="sameDomain" quality="high" name="nativeVideo_flash_' + iter + '" src="' + defaults.flashplayerswf + '"></embed></object>';
            } else {
                flashEmbed = '<object width="' + defaults.width + '" height="' + defaults.height + '" align="middle" type="application/x-shockwave-flash" data="' + defaults.flashplayerswf + '" id="nativeVideo_flash_' + iter + '"><param name="quality" value="high"><param name="allowScriptAccess" value="sameDomain"><param name="allowFullscreen" value="true"><param name="wmode" value="transparent"><param name="bgcolor" value="#ffffff"><param name="flashvars" value="url=' + defaults.flashsource + '&amp;type=flv&amp;bgColor=#ffffff&amp;bgAlpha=1"></object>';
            }

            if (defaults.mp4source === "" && defaults.oggsource === "" && defaults.webmsource === "") {
                embedParent.append(flashEmbed);
            } else {
                $(videoEmbed).append(flashEmbed);
                videoEmbed.controls = false;
                embedParent.html(videoEmbed);
                
                createVideoControls();
                try{
                  videoEmbed.addEventListener('loadeddata', function (event) {
                      setVolume(videoVolumeLevel);
                  }, true);
                  videoEmbed.addEventListener('loadstart', function () {
                      $(videoEmbed_loadingAnimation).show();
                      if (!$(videoEmbed_controls.is(':visible'))) {
                          videoEmbed_controls.show();
                      }
                  }, true);
                  videoEmbed.addEventListener('play', function () {
                      if ($(videoEmbed_loadingAnimation).is(":visible")) {
                          $(videoEmbed_loadingAnimation).hide();
                      }
                      $(videoEmbed_bigplay).hide();
                      if (videoEmbed_playpause_ident.hasClass('paused')) {
                          videoEmbed_playpause_ident.removeClass('paused');
                          videoEmbed_playpause_ident.addClass('playing');
                      }
                      videoState = 'playing';
                  }, true);
                  videoEmbed.addEventListener('pause', function () {
                      $(videoEmbed_bigplay).show();
                      if (videoEmbed_playpause_ident.hasClass('playing')) {
                          videoEmbed_playpause_ident.removeClass('playing');
                          videoEmbed_playpause_ident.addClass('paused');
                      }
                      videoState = 'paused';
                  }, true);
                  videoEmbed.addEventListener('volumechange', function (event) {
                      positionVolumeHandle(videoEmbed.volume);
                      videoVolumeLevel = videoEmbed.volume;
                      setVideoVolume(videoEmbed.volume);
                  }, true);
                  videoEmbed.addEventListener('error', function (err) {
                      // console.log(err);
                  }, true);
                  videoEmbed.addEventListener('ended', function () {
                      if (typeof defaults.onEnd == "string") {
                          if (defaults.onEnd == "loop") {
                              videoEmbed.currentTime = 0;
                          } else if (defaults.onEnd == "stop") {
                              $(videoEmbed_bigplay).show();
                              videoEmbed.pause();
                          }
                      } else if (typeof defaults.onEnd == "function") {
                          defaults.onEnd();
                      }
                  }, true);
                  videoEmbed.addEventListener('click', playPauseToggle, true);
                  videoEmbed.addEventListener('timeupdate', function (event) {
                      videoEmbed_duration.html(formatTime(videoEmbed.duration));
                      videoEmbed_currenttime.html(formatTime(videoEmbed.currentTime));

                      var newWidth = videoEmbed_timetotal.width() * videoEmbed.currentTime / videoEmbed.duration;
                      videoEmbed_timecurrent.css({"width": newWidth + "px"});
                      videoEmbed_timeslider.css({"left": (newWidth - 5) + "px"});

                      // simple hack for opera not returning buffered.end timeRanges properly
                      if (event.target && event.target.buffered && event.target.buffered.end && event.target.buffered.end.length !== 0) {
                          var percent = videoEmbed.buffered.end(0) / videoEmbed.duration;
                          setLoadProgress(percent);
                      }
                  }, true);
                  videoEmbed.addEventListener('progress', function (event) {
                      if (event.loaded != "undefined") {
                          if (event.total > 0) {
                              setLoadProgress(event.loaded / event.total);
                          }
                      }
                  }, true);
                }catch(e){}
                if (!canPlaySource()) {
                    // cant play html5, remove ogv and mp4 and make flash prominent
                    var controls = embedParent.find('.nativeVideo_Controls');
                    var nativeVideo = embedParent.find('video');
                    var flashObj = nativeVideo.find('object');
                    flashObj.appendTo(embedParent);
                    $(videoEmbed_loadingAnimation).remove();
                    nativeVideo.remove();
                    controls.remove();
                } else {
                    // can play html5
                    if (isiPhone || isiPod || isiPad) {
                        $(videoEmbed_bigplay).remove();
                        $(videoEmbed_loadingAnimation).remove();
                        videoEmbed_controls.remove();
                    }
                }
        
            }

        });
    };
})(jQuery);
