Reflow.widgets.ReflowVideo = function ReflowVideo(params, objParent) {
    this.version = "1.0";
    this.parent = objParent;
    this.releaseDate = "22/04/2010";
    this.id = "Video Manager";
    /**
     * add here known HTML5 video codecs
     */
    this.knownHTML5videoCodecs = {
        'ogg': "video/ogg; codecs'theora, vorbis'",
        'ogv': "video/ogg; codecs'theora, vorbis'",
        'mp4': "video/mp4; codecs='vc1.42E01E, mp4a.40.2'",
        'mov': "video/mp4; codecs='vc1.42E01E, mp4a.40.2'",
        'webm': "video/webm; codecs='vorbis,vp8'"
    };
    /**
  * Default plugin's settings
  * @type {object}
  */
    this.defaults = {
        /**
    * The plugin will manage videos with the following class
    * ------------------------------------------------------
    * @param {string}
    */
        classPrefix: "reflowVideo",
        /**
    * Choose the desired controls to be shown
    * ----------------------------------------
    * @type {object}
    * @params {boolean}
    */
        showButtons: {
            play: true,
            stop: false,
            progressBar: true,
            fullBrowser: true,
            closeButtonInFullBrowser: true,
            closeButtonInNormalMode: false,
            volumeBar: true,
            //if this is set to false, volumeValue && mute will not appear
            volumeValue: true,
            mute: true
        },
        /**
    * The following are CSS classes used to manipulate the videos
    * -----------------------------------------------------------
    * @type {object}
    * @params {string}
    */
        cssSelectors: {
            dynamicWrapper: 'dynamic-wrapper',
            loadingImg: 'loading-img',
            controls: 'controls-bar',
            playButton: 'play-pause-btn',
            stopButton: 'stop-btn',
            closeButton: 'close-video',
            fullBrowserButton: 'fullbrowser-btn',
            fullBrowserCloseButton: 'close-fullbrowser',
            volumeWrapper: 'volume-wrapper',
            volumeBar: 'volume-bar-wrapper',
            volumeBarPointer: 'volume-bar-pointer',
            volumeBarValue: 'volume-bar-value',
            volumeBarIcon: 'volume-bar-icon',
            progressBar: 'progress-bar-wrapper',
            progressBarPointer: 'progress-bar-pointer',
            progressBarBuffer: 'progress-bar-buffer',
            elapsedTime: 'elapsed-time',
            remainingTime: 'remaining-time',
            failedVideo: 'failedVideo',
            flashVideo: 'flashVideo'
        },
        /**
    * Global text strings
    * -------------------
    * @type {object}
    * @params {string}
    */
        localisation: {
            textError: 'Video Error :',
            textErrorNotSupported: 'The Video could not be loaded, because the format is not supported.'
        },
        /**
    * Extra settings
    * --------------
    * @type {object}
    * @params {string}
    */
        extraSettings: {
            videoContainer: ".dynamic-wrapper",
            /**
      * defines how the volume pointer should act when being dragged; animate position or size
      * use 'size' or 'position'
      */
            volumePointerAnimationStyle: 'position',
            /**
      * defines the default volume level
      * from '0' to '100'
      */
            defaultVolumeLevel: 80,
            /**
      * defines the default volume style to be horizontal
      */
            volumeVertical: false,

            /**
      * defines if it must show remaining time (true) or total time (false)
      */
            remainingTime: true
        },

        callbacks: {
            onVideoPlaying: null,
            onVideoEnding: null,
            videoEndingArgs: null,
            videoPlayingArgs: null
        },

        flashPlayer: "/media/flash/video.swf",

        customControls: true,
        
        autoplay: false

    };
    /**
  * Final Params
  * ------------
  * @type {object}
  */
    this.params = objParent.core.extend(this.defaults, params);
    /**
  * plugin's actions
  * ----------------
  * @type {object}
  */
    this.actions = {
        /**
    * isHTML5supported
    * ---------------------
    * @type {method}
    */
        isHTML5supported: function isHTML5supported() {
            return !! document.createElement('video').canPlayType;
        },
        /**
    * checkForVideoChildren
    * ---------------------
    * @type {method}
    * @param {object}
    */
        checkForVideoChildren: function checkForVideoChildren(obj, callbackFn) {
            /**
      * The following is a patch for videos with no <source> children,
      * like: <video src="tt.mp4"></video>
      */
            $('.' + obj.params.classPrefix).each(function forEachVideoWithoutSourceChildren() {
                var $oVid = $(this);
                if ($oVid.children('source').length == 0 && $oVid.attr('src') !== 'undefined') {
                    var $src = $oVid.attr('src'),
                    $ext = $src.substr($src.length - 4, $src.length),
                    type = 'unknown';

                    /**
              * parse valid extensions/codecs
              */
                    $.each(obj.knownHTML5videoCodecs,
                    function checkForValidExtensions(key, value) {
                        if (key.indexOf($ext) > -1) {
                            type = value;
                        }
                    });

                    /**
              * apply...
              */
                    if (type !== 'unknown') {
                        $oVid.removeAttr('src').append($('<source />').attr({
                            'src': $src,
                            'type': type
                        }));
                    }
                }
            });

            if (typeof callbackFn == 'function') {
                callbackFn.call(this);
            }
        },
        /**
    * Begin build
    * -----------
    * @type {method}
    * @param {object}
    */
        beginBuild: function beginBuild(obj) {
            var $css = obj.params.cssSelectors,
            $elm = obj.domElmts,
            $act = obj.actions;
            /**
      * For each video found
      */
            $('.' + obj.params.classPrefix).each(function forEachVideoFound() {
                var $video = $(this);
                
                if (/Android/gi.test(navigator.userAgent)) {
	                $video.bind('click',function(){
	                	this.play();
	                },false);
                }
                /*
                $video.children('source').each(
                /**
                * For each <source> found in each video,
                * if the browser cannot play the source then remove() it
                *
                function forEachSourceFound() {
                    var $source = $(this);
                    if ($source.parent().get(0).canPlayType($source.attr('type')).length < 1) {
                        $.data($video, 'source', $source.attr('src'));
                        $source.remove();
                    }
                });*/
                /**
            * If there are still any sources left..
            */
                if ($video.children('source').length > 0) {
                    /**
              * Wrap the video in a dynamic container // bind its hover event
              * Set it's width and height to the video's width and height
              * append an empty control bar & a loading image
              */
                    if (obj.params.customControls == true) {
                        $video.removeAttr('controls').wrap($elm.wrapper).after($elm.controlsWrapper.clone()).after($elm.loadingImg.clone()).parent('.' + $css.dynamicWrapper).width($video.attr("width")).height($video.attr("height"));
                        /**
                * Parsing params
                */
                        var $controlBar = $video.siblings('.' + $css.controls);
                        /**
                * Add play button & bind its events
                */
                        if (obj.params.showButtons.play == true) {
                            $controlBar.append($elm.playButton.clone().bind('click',
                            function clickPlay() {
                                $(this).hasClass('isPaused') ? $(this).parent().siblings('video').get(0).play() : $(this).parent().siblings('video').get(0).pause();
                            }));
                        }
                        /**
                * Add stop button & bind its events
                */
                        if (obj.params.showButtons.stop == true) {
                            $controlBar.append($elm.stopButton.clone().bind('click',
                            function clickStop() {
                                $video.get(0).pause();
                                $video.get(0).currentTime = 0;
                                $video.trigger('ended');
                            }));
                        }
                        /**
                * Add fullBrowser button & bind its events
                */
                        if (obj.params.showButtons.fullBrowser == true) {
                            $controlBar.append($elm.fullBrowserButton.clone().bind('click',
                            function clickFB() {
                                $(this).parent().siblings('video').trigger('fullbrowsing');
                            }));
                        }
                        /**
                * Add close button & bind its events
                */
                        if (obj.params.showButtons.closeButtonInNormalMode == true) {
                            jQuery(obj.params.extraSettings.videoContainer).append($elm.closeButton.clone().bind('click',
                            function clickClose(e) {
                                e.preventDefault();
                                //$video.get(0).currentTime = 0;
                                $video.get(0).pause();
                                $(this).siblings('video').trigger('ended');
                            }));
                        }
                        /**
                * Add progress bar & bind its events
                */
                        if (obj.params.showButtons.progressBar == true) {
                            $controlBar.append($elm.elapsedTime.clone(), $elm.progressBar.clone().append($elm.progressBarBuffer.clone().append($elm.progressBarPointer.clone())).bind({
                                'mouseup': function(mouseEvent) {
                                    var $btn = $(this);
                                    /*$(document)
                            .bind('mouseup', function() {
                              $(document).unbind('mouseup');
                              $btn.unbind('mousemove');
                            });*/
                                    /*$btn
                            .bind('mousemove', function(mouseEvent) {*/
                                    var $oVid = $btn.parents('.' + $css.dynamicWrapper).find('video'),
                                    progress = Math.round(mouseEvent.clientX - $btn.offset().left),
                                    progressPercent = Math.round(progress * 100 / $btn.width());
                                    if (progress < $btn.width()) {
                                        $btn.find('.' + $css.progressBarPointer).css({
                                            'width': progressPercent + "%"
                                        });
                                        $oVid.get(0).duration !== 'NaN' ? $oVid.get(0).currentTime = progressPercent * $oVid.get(0).duration / 100: '';
                                    }
                                    /*});*/
                                    return false;
                                }
                                /*,
                        'mouseup': function() {
                          $(this).unbind('mousemove');
                          $('.' + $css.loadingImg).css('visibility' , 'hidden');
                        }*/
                            }), $elm.remainingTime.clone());
                        }
                        /**
                * Add volume bar & bind its events
                */
                        if (obj.params.showButtons.volumeBar == true) {
                            var $oldValues,
                            $animationStyle = obj.params.extraSettings.volumePointerAnimationStyle,
                            $defaultVolume = obj.params.extraSettings.defaultVolumeLevel,
                            $volumeVertical = obj.params.extraSettings.volumeVertical;

                            if ($controlBar.children('.' + $css.volumeWrapper).size() <= 0) {
                                $controlBar.append($elm.volumeWrapper.clone());
                            }

                            $controlBar.children('.' + $css.volumeWrapper).append($elm.volumeBar.clone().bind({
                                'mousedown': function() {
                                    var $btn = $(this),
                                    $oVid = $btn.parents('.' + $css.dynamicWrapper).find('video');
                                    $(document).bind('mouseup',
                                    function() {
                                        $(document).unbind('mouseup');
                                        $btn.unbind('mousemove');
                                    });
                                    $btn.bind('mousemove',
                                    function(evnt) {
                                        if ($volumeVertical == true) {
                                            var t = $btn.offset().top;
                                            var h = $btn.height();
                                            var b = t + h;
                                            var value,
                                            volume = evnt.clientY - t;
                                            var cssToChange = $animationStyle == "size" ? "height": "top";

                                            volume = h - volume;

                                            if (volume > 0) {
                                                if (volume < h) {
                                                    value = volume;
                                                } else {
                                                    value = h;
                                                }
                                            } else {
                                                value = 0;
                                            }
                                            $btn.children('.' + $css.volumeBarPointer).css(cssToChange, h - value + 'px');
                                            value = Math.round(value * 100 / h);
                                            $btn.siblings('.' + $css.volumeBarValue).text(value);
                                            $oVid.get(0).volume = value / 100;
                                        } else {
                                            var value,
                                            volume = evnt.clientX - $btn.offset().left;
                                            var cssToChange = $animationStyle == "size" ? "width": "left";
                                            if (volume < $btn.width()) {
                                                if (volume > 0) {
                                                    value = volume;
                                                } else {
                                                    value = 0;
                                                }
                                            } else {
                                                value = $btn.width();
                                            }
                                            $btn.children('.' + $css.volumeBarPointer).css(cssToChange, value + 'px');
                                            value = Math.round(value * 100 / $btn.width());
                                            $btn.siblings('.' + $css.volumeBarValue).text(value);
                                            $oVid.get(0).volume = value / 100;
                                        }
                                    });
                                    return false;
                                },
                                'mouseup': function() {
                                    $(this).unbind('mousemove');
                                }
                            }).append($elm.volumeBarPointer.clone().css($animationStyle, $defaultVolume + '%')));
                            if (obj.params.showButtons.mute == true) {
                                if ($controlBar.children('.' + $css.volumeWrapper).size() <= 0) {
                                    $controlBar.append($elm.volumeWrapper.clone());
                                }
                                $controlBar.children('.' + $css.volumeWrapper).append($elm.volumeBarIcon.clone().bind('click',
                                function() {
                                    var $btn = $(this),
                                    $oVid = $btn.parents('.' + $css.dynamicWrapper).find('video');
                                    /**
                                * @see reflowVideoVolumeChange() event on video
                                */
                                    if ($btn.hasClass('isMuted')) {
                                        if (typeof $oldValues == 'object') {
                                            if (obj.params.extraSettings.volumeVertical == true) {
                                                var cssToChange = $animationStyle == "size" ? "height": "top";
                                                $btn.siblings('.' + $css.volumeBar).children('.' + $css.volumeBarPointer).css(cssToChange, $oldValues.barWidth);
                                            } else {
                                                var cssToChange = $animationStyle == "size" ? "width": "left";
                                                $btn.siblings('.' + $css.volumeBar).children('.' + $css.volumeBarPointer).css(cssToChange, $oldValues.barWidth);
                                            }

                                            $btn.siblings('.' + $css.volumeBarValue).text($oldValues.pointerValue);
                                            $oVid.get(0).volume = $oldValues.vidVolume;
                                        } else {
                                            if (obj.params.extraSettings.volumeVertical == true) {
                                                var cssToChange = $animationStyle == "size" ? "height": "top";
                                                $btn.siblings('.' + $css.volumeBar).children('.' + $css.volumeBarPointer).css(cssToChange, $defaultVolume * $(this).parent().height() / 100);
                                            } else {
                                                var cssToChange = $animationStyle == "size" ? "width": "left";
                                                $btn.siblings('.' + $css.volumeBar).children('.' + $css.volumeBarPointer).css(cssToChange, $defaultVolume * $(this).parent().width() / 100);
                                            }
                                            $btn.siblings('.' + $css.volumeBarValue).text($defaultVolume);
                                            $oVid.get(0).volume = $defaultVolume / 100;
                                        }
                                    } else {
                                        var cssToChange = "";
                                        if (obj.params.extraSettings.volumeVertical == true) {
                                            cssToChange = $animationStyle == "size" ? "height": "top";
                                        } else {
                                            cssToChange = $animationStyle == "size" ? "width": "left";
                                        }
                                        $oldValues = {
                                            'barWidth': $btn.siblings('.' + $css.volumeBar).children('.' + $css.volumeBarPointer).css(cssToChange),
                                            'pointerValue': $btn.siblings('.' + $css.volumeBarValue).text(),
                                            'vidVolume': $oVid.get(0).volume
                                        };
                                        if (obj.params.extraSettings.volumeVertical == true) {
                                            var h = $btn.siblings('.' + $css.volumeBar).height();
                                            $btn.siblings('.' + $css.volumeBar).children('.' + $css.volumeBarPointer).css(cssToChange, h);
                                        } else {
                                            $btn.siblings('.' + $css.volumeBar).children('.' + $css.volumeBarPointer).css(cssToChange, '0');
                                        }
                                        $btn.siblings('.' + $css.volumeBarValue).text('0');
                                        $oVid.get(0).volume = 0;
                                    }
                                }));
                            }
                            if (obj.params.showButtons.volumeValue == true) {
                                $controlBar.append($elm.volumeBarValue.clone());
                            }
                        }
                    }
                    /**
              * Bind video events
              */
                    $video.bind({
                        'playing': function reflowVideoPlaying() {
                            $video
                            //target play button && remove class PAUSED
                            .siblings('.' + $css.controls).children('.' + $css.playButton).removeClass('isPaused')
                            //hide loading
                            .parent('.' + $css.controls).siblings('.' + $css.loadingImg).css('visibility', 'hidden');
                            
                            if (obj.params.callbacks.onVideoPlaying != null) {
                                obj.params.callbacks.onVideoPlaying({
                                    video: this,
                                    params: obj.params.callbacks.videoPlayingArgs
                                });
                            }
                        },
                        'pause': function reflowVideoPause() {
                            $video
                            //target play button && add class PAUSED
                            .siblings('.' + $css.controls).children('.' + $css.playButton).addClass('isPaused')
                            //hide loading
                            .parent('.' + $css.controls).siblings('.' + $css.loadingImg).css('visibility', 'hidden');
                        },
                        'load': function reflowVideoLoad(ev) {
                            //console.log('load event ', ev)
                        },
                        'progress': function reflowVideoProgress(ev) {
                            /**
                    * FIREFOX
                    *   crache une erreur sous FF,
                    *   FF ne comprend pas le TIME-RANGE obj 
                    *   vid.get(0).buffered renvoie un TIME-RANGE obj
                    *   info >> https://developer.mozilla.org/En/NsIDOMHTMLMediaElement#section_2
                    *   -----------------
                    *   Nous utilisons alors event.originalEvent
                    *
                    * WEBKIT
                    *   No progress event on <video>, neither on the <source>...
                    */
                            if ($video.get(0).buffered) {
                                $video.siblings('.' + $css.controls).find('.' + $css.progressBarBuffer).width(parseInt(($video.get(0).buffered.end(0) / $video.get(0).duration) * 100) + "%");
                            } else {
                                if (ev.originalEvent.loaded && ev.originalEvent.total) {
                                    $video.siblings('.' + $css.controls).find('.' + $css.progressBarBuffer).css('width', ev.originalEvent.loaded / ev.originalEvent.total * 100 + "%");
                                } else {
                                    $video.siblings('.' + $css.controls).find('.' + $css.progressBarBuffer).css('width', "100%");
                                }
                            }
                        },
                        'timeupdate': function reflowVideoTimeUpdate() {
                            var timeValue = "";
                            if (obj.params.extraSettings.remainingTime == true) {
                                timeValue = "" + $act.secondsToTime($video.get(0).duration - $video.get(0).currentTime)
                            } else {
                                timeValue = "" + $act.secondsToTime($video.get(0).duration);
                            }
                            $video
                            //elapsed time
                            .siblings('.' + $css.controls).children('.' + $css.elapsedTime).text($act.secondsToTime($video.get(0).currentTime))
                            //remaining time
                            .siblings('.' + $css.remainingTime).text(timeValue)
                            //progress bar auto animation
                            .siblings('.' + $css.progressBar).find('.' + $css.progressBarPointer).width($('.' + $css.progressBar).width() * $video.get(0).currentTime / $video.get(0).duration + "px")
                            //hide loading
                            .parents('.' + $css.controls).siblings('.' + $css.loadingImg).css('visibility', 'hidden');
                        },
                        'durationchange': function reflowVideoDurationChange() {
                            $video
                            //total video duration
                            .siblings('.' + $css.controls).children('.' + $css.remainingTime).text("" + $act.secondsToTime($video.get(0).duration));
                        },
                        'volumechange': function reflowVideoVolumeChange() {
                            var $btn = $video.siblings('.' + $css.controls).find('.' + $css.volumeBarIcon);
                            $video.get(0).volume == 0 ? $btn.addClass('isMuted') : $btn.removeClass('isMuted');
                        },
                        'seeking': function reflowVideoSeeking() {
                            $video
                            //show loading
                            .siblings('.' + $css.loadingImg).css('visibility', 'visible');
                        },
                        'waiting': function reflowVideoWaiting() {
                            $video
                            //show loading
                            .siblings('.' + $css.loadingImg).css('visibility', 'visible');
                        },
                        'ended': function reflowVideoEnded() {
                            $video
                            //hide loading
                            .siblings('.' + $css.loadingImg).css('visibility', 'hidden')
                            //revert to the playButton's initial state
                            .siblings('.' + $css.controls).children('.' + $css.playButton).addClass('isPaused');
                            //handles "ended" event when in fullBrowser mode
                            $video.hasClass('isFb') ? $video.trigger('fullbrowsing').get(0).pause() : "";
                            if (obj.params.callbacks.onVideoEnding != null) {
                                obj.params.callbacks.onVideoEnding({
                                    video: this,
                                    params: obj.params.callbacks.videoEndingArgs
                                });
                            }
                        },
                        'dblclick': function reflowVideoDblClick() {
                            $video.trigger('fullbrowsing');
                        },
                        'fullbrowsing': function fbHandler() {
                            if ($video.hasClass('isFb')) {
                                /**
                      * Leave FullBrowsing Mode
                      * @see Go FullBrowsing Mode first
                      */
                                $controlBar.removeClass("fullscreen-mode");

                                $video.removeClass('isFb').parent('.' + $css.dynamicWrapper).insertAfter('#video').css({
                                    'position': 'relative',
                                    'width': $('#video').width(),
                                    'height': $('#video').height()
                                }).children('.' + $css.controls).css('z-index', '2').siblings('video').css({
                                    'position': 'inherit',
                                    'width': '100%',
                                    'height': '100%',
                                    'z-index': '1'
                                });
                                //scroll back to where the user was looking
                                window.location.hash = 'video';
                                //remove anchor
                                $('#video').remove();
                                obj.params.showButtons.closeButtonInFullBrowser == true ? $video.siblings('.' + $css.fullBrowserCloseButton).remove() : '';
                                //restore scrollbars
                                $('body').css('overflow', 'visible');
                            } else {
                                /**
                      * Go FullBrowsing Mode
                      *
                      * 1- i extract the video + its wrapper, and append it to the <body>
                      * 2- consecutively, the page's layout breaks because we MOVE an element from a place to another
                      * 3- to avoid this, i clone an instance of the dynamic wrapper & empty it &
                      * 4- append it where the video was.
                      * 
                      * [now when i go fullscreen, the page doesnt break]
                      */
                                $video.addClass('isFb')
                                //hide original wrapper
                                .parent().hide()
                                //clone original wrapper & empty it & add an ID & show it
                                .clone().empty().attr('id', 'video').show()
                                //move the new wrapper where the old one was
                                .insertAfter($video.parent());
                                if (obj.params.showButtons.closeButtonInFullBrowser == true) {
                                    $video.parent('.' + $css.dynamicWrapper).append($('<div />').attr('class', $css.fullBrowserCloseButton).bind('click',
                                    function killFullBrowser() {
                                        $video.trigger('fullbrowsing');
                                    }));
                                }

                                $controlBar.addClass("fullscreen-mode");

                                $video.parent('.' + $css.dynamicWrapper).show()
                                //move the wrapper and its content to same level as the <body>
                                .appendTo('body')
                                //maximize the wrapper
                                .css({
                                    'position': 'fixed',
                                    'top': '0px',
                                    'left': '0px',
                                    'width': window.innerWidth,
                                    'height': window.innerHeight
                                })
                                //the controls get stucked behind the vid so we must apply a z-index property
                                .children('.' + $css.controls).css('z-index', '1001')
                                //maximize the video
                                .siblings('video').css({
                                    'position': 'absolute',
                                    'top': '0',
                                    'left': '0',
                                    'margin-top': '0',
                                    'margin-left': '0',
                                    'z-index': '1000',
                                    'width': '100%',
                                    'height': '100%'
                                });
                                //scroll to top
                                $(window).scrollTop(0);
                                //hide sccrollbars
                                $('body').css('overflow', 'hidden');
                                //pause all the videos
                                $('.' + obj.params.classPrefix).each(function pauseAllVideos() {
                                    $(this).get(0).pause();
                                });
                                //play the video who just went fullBrowset mode
                                $video.get(0).play();
                            }
                        }
                    })
                    /**
                * Bind wrapper hover event
                */
                    .parent()
                    .bind({
                  'mouseenter':function reflowVideoMouseOver(){
                    $video.siblings('.' + $css.controls).css('visibility','visible');
                  },
                  'mouseleave':function reflowVideoMouseOut(){
                    $video.siblings('.' + $css.controls).css('visibility','hidden');
                  }
                });
                    
                $video.siblings('.' + $css.controls).css('visibility','hidden');
                
                if (obj.params.autoplay) {
                	$video.get(0).play();
                }
                    /**
            * If no sources were left in the <video>..
            * replace it by a <div>
            * add flash callback
            */
                } else {
                    var theSrc = $.data($video, 'source');
                    if (theSrc !== '' && theSrc.indexOf('.ogv') == '-1' && theSrc.indexOf('.ogg') == '-1' && theSrc.indexOf('webm') == '-1') {
                        var d = new Date(),
                        rndId = d.getTime(),
                        flashvars = {
                            'q': theSrc
                        },
                        // aka >> video.swf?q=../videos/movie.mp4
                        params = {
                            'allowfullscreen': 'true'
                        },
                        attributes = {};

                        $video.wrap($elm.flashVideo.clone().attr('id', rndId).height($video.height()).width($video.width()));

                        swfobject.embedSWF(obj.params.flashPlayer, rndId, $video.width(), $video.height(), '10.0.0', '/Frameworks/swfobject/expressInstall.swf', flashvars, params, attributes);

                        $video.remove();
                    } else {
                        $video.wrap($elm.failedVideo.clone().height($video.height()).width($video.width()).text(obj.params.localisation.textErrorNotSupported));
                        //do not chain wrap and remove
                        $video.remove();
                    }
                }
            });
        },
        /**
    * begin Build Flash videos (for browsers that do not support html5)
    * @type {method}
    * @param {object}
    */
        beginBuildFlash: function beginBuildFlash(obj) {
            var $elm = obj.domElmts;
            /**
      * For each <video> found
      */
            $('video.' + obj.params.classPrefix).each(function forEachVideoFound() {
                var $video = $(this);
                $video.children('source').each(
                /**
                * For each <source> found in each video,
                * if its an MP4 video, add the flash player
                */
                function forEachSourceFound() {
                    var $source = $(this);
                    if ($source.attr('src').indexOf('.mp4') > 1) {
                        var vidURL = $source.attr('src'),
                        d = new Date(),
                        rndId = d.getTime(),
                        flashvars = {
                            'q': vidURL
                        },
                        // final >> video.swf?q=../videos/movie.mp4
                        params = {
                            'allowfullscreen': 'true',
                            'wmode': 'opaque'
                        },
                        attributes = {
                            'id': $video.attr("id"),
                            'class': $video.attr("class")
                        },
                        vWidth = $video.attr('width') + "px",
                        vHeight = $video.attr('height') + "px";

                        $source.parent().wrap($elm.flashVideo.clone().attr('id', rndId).height(vHeight).width(vWidth));

                        $video.remove();
                        swfobject.embedSWF(obj.params.flashPlayer, rndId, vWidth, vHeight, '10.0.0', '/Frameworks/swfobject/expressInstall.swf', flashvars, params, attributes);

                    } else {
                        /**
                    * If its not an mp4 video, remove the source
                    */
                        $source.remove();
                    }
                });
            });
            /**
      * again, we enumerate all the videos, replace the ones with no <source> children
      * with a "failed video"
      */
            $('video.' + obj.params.classPrefix).each(function() {
                var $video = $(this);
                if ($video.children('source').length == 0) {
                    $video.wrap($elm.failedVideo.clone().height($video.attr('height') + "px").width($video.attr('width') + "px").text(obj.params.localisation.textErrorNotSupported));
                    $video.remove();
                }
            });
        },
        /**
    * secondsToTime
    * @type {method}
    * @param {integer}
    * @returns {string}
    */
        secondsToTime: function secondsToTime(seconds) {
            var hours,
            minutes;
            hours = Math.floor(seconds / 3600);
            seconds %= 3600;
            minutes = Math.floor(seconds / 60);
            seconds = Math.floor(seconds % 60);
            hours = hours > 0 ? (hours < 10 ? "0" + hours: hours) + ":": "";
            minutes = minutes > 0 ? (minutes < 10 ? "0" + minutes: minutes) + ":": "00:";
            seconds = seconds > 0 ? seconds < 10 ? "0" + seconds: seconds: "00";
            return hours + minutes + seconds;
        }
    };
    /**
  * DOM Elements
  * @type {object}
  * --------------
  * An object containing a set of all the possible appendable elements
  * Each of these elements must be 'cloned' before use
  */
    this.domElmts = {
        wrapper: $('<div />').attr('class', this.params.cssSelectors.dynamicWrapper),
        loadingImg: $('<div />').attr('class', this.params.cssSelectors.loadingImg),
        controlsWrapper: $('<div />').attr({
            'class': this.params.cssSelectors.controls
        }),
        playButton: $('<button />').attr('class', this.params.cssSelectors.playButton + ' isPaused'),
        stopButton: $('<button />').attr('class', this.params.cssSelectors.stopButton),
        fullBrowserButton: $('<button />').attr('class', this.params.cssSelectors.fullBrowserButton),
        volumeWrapper: $('<div />').attr('class', this.params.cssSelectors.volumeWrapper),
        volumeBar: $('<div />').attr('class', this.params.cssSelectors.volumeBar),
        volumeBarPointer: $('<div />').attr('class', this.params.cssSelectors.volumeBarPointer),
        volumeBarIcon: $('<div />').attr('class', this.params.cssSelectors.volumeBarIcon),
        volumeBarValue: $('<span />').attr('class', this.params.cssSelectors.volumeBarValue).text(this.params.extraSettings.defaultVolumeLevel),
        progressBar: $('<div />').attr('class', this.params.cssSelectors.progressBar),
        progressBarPointer: $('<div />').attr('class', this.params.cssSelectors.progressBarPointer),
        progressBarBuffer: $('<div />').attr('class', this.params.cssSelectors.progressBarBuffer),
        elapsedTime: $('<span />').attr('class', this.params.cssSelectors.elapsedTime).text('00:00'),
        remainingTime: $('<span />').attr('class', this.params.cssSelectors.remainingTime).text('00:00'),
        failedVideo: $('<div />').attr('class', this.params.cssSelectors.failedVideo),
        flashVideo: $('<div />').attr('class', this.params.cssSelectors.flashVideo),
        closeButton: $('<div />').attr('class', this.params.cssSelectors.closeButton)

    };
    /**
  * init(obj)
  * @type {method}
  * @param {object}
  * @constructor
  */
    this.init = function init(obj) {
        obj.actions.checkForVideoChildren(obj,
        function() {
            obj.actions.isHTML5supported() == true ? obj.actions.beginBuild(obj) : obj.actions.beginBuildFlash(obj);
        });
    };
    /**
  * Handles windows resizing while in fullbrowser
  */
    $(window).load(function windowLoaded() {
        $(this).resize(function windowResized() {
            $('video.isFb').css({
                'width': window.innerWidth,
                'height': window.innerHeight
            }).parent().css({
                'width': window.innerWidth,
                'height': window.innerHeight
            });
        });
    });
};
