VPorn.com - A New Layout II - updated

A unique great site got A new layout, with som added functionality and lost some. This script adds browser full video, bigger thumbnails, key and mouse navigation and interaction.

As of 2015-04-24. See the latest version.

/**
 * Created by Pegaasus on 2015-04-10.
 */
//// ==UserScript==
// @name            VPorn.com - A New Layout II - updated
// @namespace       http://use.i.E.your.homepage/
// @version         0.39
// @description     A unique great site got A new layout, with som added functionality and lost some. This script adds browser full video, bigger thumbnails, key and mouse navigation and interaction.
// @match           http://www.vporn.com/*
// @exclude         http://www.vporn.com/embed/*
// @require         http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js
// @require         https://greasyfork.org/scripts/9160-my-function-library/code/My%20Function%20library.js?version=45900
// @grant           GM_getValue
// @grant           GM_setValue
// @grant           GM_deleteValue
// @grant           GM_listValues
// @grant           GM_xmlhttpRequest
// @run-at          document-start
// @created         2015-01-28
// @released        2014-00-00
// @updated         2014-00-00
// @history         @version 0.25 - first version: public@released - 2015-02-11
// @history         @version 0.39 - pre relese second version: public@released - 2015-04-12
// @compatible      Greasemonkey, Tampermonkey
// @license         GNU GPL v3 (http://www.gnu.org/copyleft/gpl.html)
// @copyright       2014+, Magnus Fohlström
// ==/UserScript==

/*global $, jQuery*/

/*jshint -W014*/
// -W014, laxbreak, Bad line breaking before '+'
// -W030, Expected assignment or funtion call insted saw an expression
// -W082, a function declaration inside a block statement

(function($){



    var w           = function( text, tag, style ){
            style = style || '';
            return fn.obj2Str( html.wrapTag( text, tag, style ) );
        },
        cl          = function( text, style ){
            style = style || '';
            return fn.obj2Str( $( '<span/>',{ class: style, text: text }) );
        },
        em          = function( text ){
            return fn.obj2Str( $( '<em/>' ).html(text) );
        },
        b           = function( text ){
            return fn.obj2Str( $( '<b/>' ).html(text) );
        },
        v           = function( text,width,height,src, firstLine ){
            return fn.obj2Str( $( '<span/>',{ class:'videolink menuTM', text:text, 'data-command':'video',
                'data-width':width, 'data-height':height, 'data-src':src }).append( $( '<span/>' ).text( firstLine ).hide() ) );
        },
        p           = function( text, style ){
            style = style || '';
            var obj = $( '<span/>', { class: style });
            $.each( text.split('\r'), function(id,elem){
                obj.append( $('<p/>').html(
                    elem.split('\n').join('<br>')
                        .split('\t').join('&nbsp;&nbsp;&nbsp;')
                        .split(/\s+/g).join(' ')
                ))
            });
            return fn.obj2Str( obj );
        },
        a           = function( txt, href ){
            var link = href.search('mailto:') == 0 ? '' : 'http://';
            return fn.obj2Str( $( '<a/>',{ href: link + href, class:'external', target: '_blank', text: txt }) );
        },
        l           = function( txt, cl, data, page ){
            return fn.obj2Str( $( '<a/>',{ class: cl, 'data-command': data, 'data-page': page, href:'javascript:;', text: txt }) );
        },
        GM          = {
            first   : function(){
                GM_setValue('firstRun','Done');
                this.manager('set');
                setTimeout(function(){
                    render.tm();
                    $('#holderTM').show();
                    c.i('firstRun')
                },2000)
            },
            manager : function( fn ){
                fn === 'del' && GM_deleteValue( 'firstRun' );
                $.each( sharedData.GM(), function(i,val){
                    switch (fn){
                        case 'set':     GM_setValue( val.name, val.default );           break;
                        case 'get':     config[ val.name ] = GM_getValue( val.name );   break;
                        case 'del':     GM_deleteValue( val.name );                     break;
                    }
                })
            }
        },
        config      = {
            fullWidth   : 80,
            d80Width    : 80,
            orgWidth    : 960,
            normWidth   : 1100,
            wideWidth   : 1400,
            extraWidth  : 1800,
            startWidth  : function( ){
                var winWidth = $(window).width(), setWidth = config[ config.pageWidth ];
                config.pageWidthNR = setWidth + 60 > winWidth ? winWidth - 60 : setWidth;
            },
            locDoc      : window.location.href,
            prevDoc     : function( ){
                return $('.pager a.prev').attr('href')
            },
            nextDoc     : function( ){
                return $('.pager a.next').attr('href')
            }
        },
        sharedData  = {
            GM          : function(){
                return [
                    { default : false,          name :'menuState'       },
                    { default : 4,              name :'thumbCol'        },
                    { default : 'normWidth',    name :'pageWidth'       },
                    { default : false,          name :'inMenu'          },
                    { default : 0,              name :'imgHeight'       },
                    { default : 'r',            name :'randis'          }
                ]
            },
            settings2   : function(){
                return [
                    { default : true,   name :'dynThumb',       title : 'Show thumbs in correct ratio aspect' },
                    { default : false,  name :'startButton',    title : 'Inside the user menu / as a separated button' },
                    { default : false,  name :'ads',            title : 'Show Ads' },
                    { default : true,   name :'welcome',        title : 'Show welcome Screen' },
                    { default : true,   name :'menuPos',        title : '' },
                    { default : false,  name :'menuVisible',    title : 'Show menu' },
                    { default : false,  name :'start',          title : 'Do you know how to find this dialog' },
                    { default : false,  name :'resetDelete',    title : 'Reset All Settings' }
                ];
            }
        },
        css         = {
            head        : function( ){
                $('<style id="fontsCss"></style>'
                + '<style id="mainCss"></style>'
                + '<style id="bxCss"></style>'
                + '<style id="tmCss"></style>'
                + '<style id="fullCss"></style>').appendTo('head');
            },
            fontsCss    : function( ){
                var CssHead = $( '#fontsCss' ),
                    css = '@import url(https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.css);';
                CssHead.html().length < 10 && CssHead.empty().append( css.formatString() );
            },
            basicCss    : function( ){
                var css, CssHead = $('#mainCss'), pageWidth = config.pageWidthNR, thumbCol = config.thumbCol;
                css = ''
                +	'.overheaderbanner, #vz_im_ad, #video-right-holder, .red-adv, '
                +	".topSbanner, div[style*='width: 720px'], .leftbanner, #leftmenu, #video-banner {"
                +		'display: none !important;'
                +		'}'
                +	'#head, .navwrap, .nwrap, #footer-nav4, .warapper-menu {'
                +		'width: '+pageWidth+'px !important;'
                +		'max-width: '+pageWidth+'px !important;'
                +		'}'
                +	'.account-videos {'
                +		'width: calc( 100% - 190px );'
                +		'}'
                +	'.video-details {'
                +		'width: calc( '+pageWidth+'px - 18px );'
                +		'}'
                +	'.playerholder {'
                +		'width: calc( '+pageWidth+'px - 18px );'
                +		'height: calc( ( '+pageWidth+'px - 18px ) * ( 405/720 ) );'
                +		'}'

                +	'.menu-video-left > span {'
                +		'width: 100%;'
                +		'max-width: none !important;'
                +		'}'
                +	'.menu-video-left {'
                +		'width: calc( 100% - 65px );'
                +		'height: 39px;'
                +		'line-height: 39px;'
                +		'padding-left: 5px;'
                +		'}'

                +	'object#as3_js {'
                +		'width: 100%;'
                +		'height: 100%;'
                +		'}'
                +	'.conteiner, .conteiner>div, #video, .related, .related_outer, .related_container {'
                +		'width: 100% !important;'
                +		'}'
                +	'#content {'
                +		'padding-top: 0;'
                +		'overflow: visible;'
                +		'}'
                +	'.nwrap >  * , body >  *  {'
                +		'position: relative;'
                +		'}'
                +	'.related_outer, .related_container {'
                +		'overflow: visible !important;'
                +		'position: static !important;'
                +		'height: initial !important;'
                +		'}'
                +	'.tplace {'
                +		'width: 100%;'
                +		'height: inherit;'
                +		'}'
                +	'.time {'
                +		'top: inherit;'
                +		'bottom: 85px;'
                +		'}'
                +	'.thumblist .bx {'
                +		'width: calc( 100% / '+thumbCol+' - 15px ) !important;'
//                +		'height: calc( ('+pageWidth+'px / 5 - 15px )*(215/210)) !important;'
//                +		'min-height: 227px;'
                +		'}'
                +	'.thumblist .bx .time {'
                +		'top: inherit;'
                +		'bottom: 5px;'
                +		'}'
                +	'.thumblist .bx .thumb {'
                +		'position: relative;'
/*                +		'width: 100%;'
                +		'height: 100%;'
                +		'display: inline;'
*/                +		'}'
                +	'.cholder, .cholder>div {'
                +		'width: calc( '+pageWidth+'px  ) !important;'
                +		'}'
                +	'.bx {'
                +		'margin-right: 13px !important;'
                +		'}'
                +	'.cholder .bx {'
                +		'width: calc( 100% / '+thumbCol+' - 15px ) !important;'
                +		'}'
                +	'.cholder .thumblist, .related_outer .thumblist {'
                +		'width: calc( 100% + 14px );'
                +		'}'
                +	'.thumblist div.bx div:nth-last-child( 1 ) {'
                +		'bottom: 3px;'
                +		'}'
                +	'.thumblist div.bx div:nth-last-child( 2 ) {'
                +		'bottom: 22px;'
                +		'}'

                +	'.grayarea.wline {'
                +		'height: 39px;'
                +		'line-height: 39px;'
                +		'text-align: center;'
                +		'width: 100%;'
                +		'}'


                +	'.warapper-menu {'
                +		'background-color: white;'
                +		'border-width: 1px;'
                +		'border-style: solid;'
                +		'border-color: rgb( 228, 228, 228 );'
                +		'border-radius: 12px;'
                +		'overflow: hidden;'
                +		'}'
                +	'.account-menu {'
                +		'border-width: 0;'
                +		'margin-right: 0;'
                +		'}'
                +	'.account-videos {'
                +		'width: calc( 100% - 178px );'
                +		'}'
                +	'.account-title {'
                +		'border: 0px solid #e4e4e4;'
                +		'border-bottom: 1px solid #e4e4e4;'
                +		'}'
                +	'.account-videos-wrapp.clearfix {'
                +		'border: 0px solid #e4e4e4;'
                +		'}'

                +	'i.btn.btn-default {'
                +		'float: left;'
                +		'padding: 11px 9px 12px 9px;'
                +		'margin: 9px;'
                +		'margin-top: 15px;'
                +		'color: white;'
//               +		'font-family: "Open Sans", Arial, Helvetica, sans-serif;'
                +		'font-weight: 600;'
                +		'font-size: 12px;'
                +		'border-radius: 3px;'
                +		'background-color: rgb( 253, 69, 66 );'
                +		'cursor: pointer;'
                +		'}'
                +	'.search {'
                +		'width: initial !important;'
                +		'margin: 15px 0px 0 15px !important;'
                +		'}'
                ;

                pageWidth < 1800 && ( css += ''
                +	'.thumblist .bx .bx_1line {'
                +		'position: absolute;'
                +		'width: calc( 100% - 17px );'
                +		'}' );
                //CssHead.html().length < 10 &&
                CssHead.empty().append( css.formatString() );
            },
            fullCss     : function( input ){
                $('html').addClass('fullplayer');
                var css, CssHead = $('#fullCss'),
                    inputSize = input || 3,
                    pageWidth = $(window).width() - inputSize,
                    pageHeight = $(window).height() - 18;
                css = ''
                +	'header, br, .menu-video, .video-details, .video_panel, .related-videos, '
                +	'.clear, .related, #popup_content, .overheaderbanner, footer, #vz_im_ad {'
                +		'display: none !important;'
                +		'}'
                +	'html {'
                +		'overflow: hidden;'
                +		'}'
                +	'body {'
                +		'padding-right: 2px;'
                +		'}'
                +	'.conteiner>div {'
                +		'margin: 9px auto !important;'
                +		''
                +		'}'
                +	'.nwrap {'
                +		'width: '+pageWidth+'px !important;'
                +		'max-width: '+pageWidth+'px !important;'
                +		'}'
                +	'.video-details {'
                +		'width: calc( '+pageWidth+'px - 18px );'
                +		'}'
                +	'.playerholder {'
                +		'width: calc( '+pageWidth+'px - 18px );'
                +		'height: calc( '+pageHeight+'px - 18px );'
                +		'}';
                CssHead.empty().append( css.formatString() );
            },
            bxCss       : function( i ){
                var css, CssHead = $('#bxCss');
                css = ''
                +	'.thumblist .bx {'
                +		'min-height: '+( i + ( 13 + 13 + 21 + 29 ) )+'px;'
                +		'}';
                CssHead.empty().append( css.formatString() );
            },
            tmCss       : function( ){
                var css, CssHead = $('#tmCss');
                css = ''
                +	'#holderTM {'
                +		'position: fixed;'
                +		'top: 50%;'
                +		'left: 50%;'
                +		'width: 0px;'
                +		'height: 0px;'
                +		'z-index: 1000;'
                +		'}'
                +	'.wrapperTM {'
                +		'position: absolute;'
                +		'transform: translate( -50%, -50% );'
                +		'background-color: rgba( 250, 244, 241, 0.91 );'
                +		'border-radius: 20px;'
                +		'border-width: 5px;'
                +		'border-style: ridge;'
                +		'border-color: rgb( 229, 78, 41 );'
                +		'}'
                +	'.contentTM {'
                +		'padding: 20px;'
                +		'box-sizing: border-box;'
                +		'float: left;'
                +		'overflow: auto;'
                +		'min-height: 300px'
                +		'}'

                +	'i#closeButton {'
                +		'position: absolute;'
                +		'z-index: 1000;'
                +		'right: 4px;'
                +		'top: 2px;'
                +		'text-shadow: 0px 0px 3px rgb( 178, 37, 37 );'
                +		'color: rgb( 244, 244, 244 );'
                +		'}'
                +	'i#closeButton:hover {'
                +		'color: rgb( 145, 49, 26 );'
                +		'text-shadow: 0px 0px 4px #91311A;'
                +		'margin-left: -1px;'
                +		'cursor: pointer;'
                +		'}'
                +	'i#menuButton {'
                +		'position: absolute;'
                +		'z-index: 1000;'
                +		'left: 4px;'
                +		'top: 2px;'
                +		'text-shadow: 0px 0px 3px rgb( 178, 37, 37 );'
                +		'color: rgb( 244, 244, 244 );'
                +		'}'
                +	'i#menuButton:hover {'
                +		'color: rgb( 145, 49, 26 );'
                +		'text-shadow: 0px 0px 4px #91311A;'
                +		'margin-left: -1px;'
                +		'cursor: pointer;'
                +		'}'

                +	'.contHeadTM {'
                +		'text-align: center;'
                +		'font-weight: bold;'
                +		'font-variant: small-caps;'
                +		'font-size: 46px;'
                +		'}'
                +	'.firstLine {'
                +		'font-style: italic;'
                +		'font-weight: bold;'
                +		'font-size: 20px;'
                +		'}'
                +	'.normPresentation {'
                +		'font-size: 18px;'
                +		'line-height: 22px;'
                +		'}'
                +	'.normPresentation p {'
                +		'text-indent: 32px;'
                +		'margin-bottom: 10px;'
                +		'}'

                +	'.contBodyTM em {'
                +		'color: rgb( 217, 78, 44 );'
                +		'}'
                +	'.contBodyTM .menuTM:not(.pageLi), .contBodyTM .external {'
                +		'color: blue;'
                +		'cursor: pointer;'
                +		'}'
                +	'.contBodyTM .click {'
                +		'color: blue;'
                +		'cursor: pointer;'
                +		'}'


                +	'#holderTM .foot .checkbox {'
                +		'float: left;'
                +		'line-height: 34px;'
                +		'margin-left: 2px;'
                +		'}'
                +	'#holderTM .foot .copyright {'
                +		'float: right;'
                +		'line-height: 34px;'
                +		'margin-right: 5px;'
                +		'}'

                +	'.myMenu li, .myMenu li a {'
                +		'line-height: 28px;'
                +		'height: 28px;'
                +		'width: 100%;'
                +		'display: inline-block;'
                +		'}'
                +	'ul.myMenu {'
                +		'margin-left: -10px;'
                +		'}'
                +	'.myMenu li {'
                +		'padding-left: 10px;'
                +		'border-radius: 5px;'
                +		'border-style: groove;'
                +		'border-width: 2px;'
                +		'margin-bottom: 5px;'
                +		'background-color: rgb( 244, 244, 244 );'
                +		'}'
                +	'.myMenu li:hover {'
                +		'background-color: rgb( 145, 49, 26 );'
                +		'box-shadow: 1px 1px 2px 0px #1D0601;'
                +		'border-color: rgb( 229, 78, 41 );'
                +		'border-style: outset;'
                +		'border-width: 2px;'
                +		'margin-left: -1px;'
                +		'}'
                +	'.myMenu li:active {'
                +		'background-color: rgb( 117, 93, 12 );'
                +		'}'
                +	'.myMenu li:hover a {'
                +		'color: rgb( 233, 228, 224 );'
                +		'text-shadow: 0px 0px 6px rgba( 255, 255, 255, 0.6 );'
                +		'}'

                +	'#myForm input, #myForm textarea {'
                +		'float: right;'
                +		'width: 200px;'
                +		'}'
                +	'#myForm textarea {'
                +		'width: 198px;'
                +		'height: 80px;'
                +		'}'
                +	'#myForm ul.myMenu {'
                +		'width: 64px;'
                +		'margin-left: 20px;'
                +		'}'
                +	'#myForm ul.myMenu li {'
                +		'padding: 5px 12px 5px 20px;'
                +		'}'

                +	'#aboutTM #table {'
                +		'display: table;'
                +		'}'
                +	'#aboutTM #table .row {'
                +		'display: table-row;'
                +		'}'
                +	'#aboutTM #table .label, #aboutTM #table .details {'
                +		'display: table-cell;'
                +		'padding-bottom: 8px;'
                +		'line-height: 20px;'
                +		'}'
                +	'#aboutTM #table .label {'
                +		'width: 120px;'
                +		'font-weight: bold;'
                +		'}'

                +	'#helpTM .row {'
                +		'display: table-row;'
                +		'}'
                +	'#helpTM .label, #helpTM .details {'
                +		'display: table-cell;'
                +		'}'
                +	'#helpTM .label {'
                +		'padding-left: 33px;'
                +		'width: 133px;'
                +		'}'
                +	'#helpTM .details {'
                +		'padding-bottom: 8px;'
                +		'line-height: 20px;'
                +		'}'
                +	'#helpTM h4 {'
                +		'padding-bottom: 10px;'
                +		'}'
                +	'#helpTM .mouseNav {'
                +		'padding-left: 33px;'
                +		'padding-top: 10px;'
                +		'}'

                +	'#configTM .description {'
                +		'margin: 10px 0 5px 10px;'
                +		'}'
                +	'#configTM .row {'
                +		'display: table-row;'
                +		'}'
                +	'#configTM .label, #configTM .details {'
                +		'display: table-cell;'
                +		'}'
                +	'#configTM .label {'
                +		'padding-left: 25px;'
                +		'width: 75px;'
                +		'}'
                +	'#configTM input[type="radio"] {'
                +		'margin-right: 7px;'
                +		'top: 1.5px;'
                +		'cursor: pointer;'
                +		'transform: scale(1.4);'
                +		'transform-origin: center center;'
                +		'position: relative;'
                +		'}'

                +	'#configTM #more .label {'
                +		'width: 200px;'
                +		'padding-right: 20px;'
                +		'padding-bottom: 10px;'
                +		'padding-top: 5px;'
                +		'font-weight: 600;'
                +		'}'
                +	'#configTM #more .details {'
                +		'vertical-align: middle;'
                +		'}'

                +	'#configTM form#columns {'
                +		'margin: 16px 0;'
                +		'}'
                +	'#configTM form#columns h4 {'
                +		'margin-bottom: 10px;'
                +		'}'
                +	'#configTM form#columns .details span {'
                +		'margin-right: 15px;'
                +		'}'
                +	'#configTM ul#setColSize {'
                +		'margin: auto;'
                +		'width: 250px;'
                +		'}'
                +	'#configTM ul#setColSize li a.menuTM {'
                +		'text-align: center;'
                +		'color: black;'
                +		'}'
                +	'#configTM ul#setColSize li {'
                +		'padding: 0;'
                +		'}'
                +	'#configTM ul#setColSize li:hover a.menuTM {'
                +		'color: aliceblue;'
                +		'}'
                +	'#configTM #pageSize span, #configTM #columns span {'
                +		'line-height: 24px;'
                +		'}'

                +	'#pagerTM {'
                +		'position: relative;'
                +		'height: 40px;'
                +		'line-height: 40px;'
                +		'overflow: hidden;'
                +		'}'
                +	'#pagerTM ul.pagerUl {'
                +		'position: absolute;'
                +		'left: 66%;'
                +		'transform: translateX( -50% );'
                +		'width: 100%;'
                +		'}'
                +	'#pagerTM ul.pagerUl li {'
                +		'float: left;'
                +		'padding: 0px 10px;'
                +		'width: initial;'
                +		'margin: 0 5px;'
                +		'}';

                CssHead.empty().append( css.formatString() );
            }
        },
        fn          = {
            obj2Str     : function( obj ){
                var objArr = $.makeArray(obj);
                return objArr[0].outerHTML;
            },
            imgHeightSub: function( id ){
                var imgHeight = config.imgHeight || 0, thisImg = $( id ).height();
                imgHeight = thisImg > imgHeight ? thisImg : imgHeight;
                imgHeight > 66 && imgHeight > config.imgHeight && (css.bxCss( imgHeight ),
                config.imgHeight = imgHeight);
            },
            imgHeight   : function( ){
                $('.thumblist').find('.bx').each(function(){
                    var $this = $( this ), id = '#' + $this.find('.tplace').attr('id');
                    fn.imgHeightSub(id);
                });
            },
            heightTime  : function( ){
                $('.thumblist').find('.bx').each(function(){
                    var $this = $( this ), id = '#' + $this.find('.tplace').attr('id');
                    $this.find('.time').appendTo( $this.find('.thumb') );
                    $( id ).load(function() {
                        fn.imgHeightSub(id);
                    });
                });
            },
            esc         : function( ){
                $('#fullCss').empty();
                $('html').removeClass('fullplayer')
            },
            sortMenu    : function( ){
                var arr = ['newest','longest','views','rating','favorites','comments','votes'],
                    locDoc = config.locDoc, thisSort = '';

                $.each(arr,function(key,value){
                    locDoc.search( value ) > 0 && ( thisSort = value );
                });

                thisSort = thisSort.length < 2 ? 'newest' : thisSort;

                $('.account-menu').find('a').each(function(i,el){
                    var elem = $( el );
                    elem.attr('href', elem.attr('href') + thisSort );
                });

                GM_xmlhttpRequest({
                    method: "GET",
                    url: "http://www.vporn.com/",
                    crossDomain: false,
                    onload: function( res ) {
                        res = $( res.responseText ).find('.grayarea.wline');
                        $( res )
                            .find('ul>li').removeClass('current').wrap('<a href="http://www.vporn.com/newest"></a>').end()
                            .find('.sorts').attr('style','width: 100%;').end()
                            .find('.maincat').remove().end()
                            .find('.timefilter').remove().end()
                            .find('a').each(function(i,el){
                                var elem = $( el ), elemType = elem.attr('href').split('/').pop();
                                elem.attr('href', locDoc.search( thisSort ) > 0 ? locDoc.replace( thisSort, elemType ) : locDoc + '/' + thisSort );
                                thisSort === elemType && elem.find('li').addClass('current').unwrap();
                            });
                        $('.grayarea.wline').replaceWith( res );
                    }
                });
            },
            chkPager    : function( ){
                var elem = $('.pagerwrap');
                elem.parents().is('.related') && elem.hide();
            },
            timeDate    : function ( d, /* Date instance */ fo /* Format string */ ) {
                var f = fo || '';
                return f.replace( // Replace all tokens
                    /{(.+?)(?::(.*?))?}/g, // {<part>:<padding>}
                    function (
                        v, // Matched string (ignored, used as local var)
                        c, // Date component name
                        p // Padding amount
                    ) {
                        //noinspection StatementWithEmptyBodyJS
                        for(v = d["get" + c]() // Execute date component getter
                        + /h/.test(c) // Increment Mont(h) components by 1
                        + ""; // Cast to String
                            v.length < p; // While padding needed,
                            v = 0 + v); // pad with zeros
                        return v; // Return padded result
                    })
            },
            submitForm  : function( ){
                var name       = $('#cname').val(),
                    email      = $('#cemail').val(),
                    subject    = $('#csubject').val(),
                    text       = $('#ccomment').val(),
                    dateParam  = function(){
                        return "{FullYear}-{Month:2}-{Date:2} {Hours:2}:{Minutes:2}:{Seconds:2}"
                    },
                    date       = function(){
                        return new Date
                    };

                $.ajax({
                    type: 'POST',
                    url: 'https://mandrillapp.com/api/1.0/messages/send.json',
                    data: {
                        'key': 'Hk5nxsMx5Ov4zVL7GHJkSQ',
                        'message': {
                            'from_name' : name,
                            'from_email': email,
                            'to': [{ 'email': '[email protected]' }],
                            'auto_text': true,
                            'subject': 'myUserScript: VPorn.com' + subject,
                            'text': text + '\r\r\t TimeStamp: ' + fn.timeDate(date,dateParam)
                        }
                    }
                }).done(function(response) {
                    console.log(response); // if you're into that sorta thing
                });
            },
            setColSize  : function( page ){
                var configTM = $( '#configTM' );
                if( $('.switchAble').data('page') == 1 ) {
                    GM_setValue('pageWidth', configTM.find('#pageSize input.size:checked').val()),
                    GM_setValue('thumbCol', configTM.find('#columns input.col:checked').val())
                } else {
                    $.each( sharedData.settings2(), function(i,e) {
                        c.i('nr: ' + i +', ' + e.name + ', ' + e.title + '.');
                        GM_setValue( e.name, configTM.find( '#more input.' + e.name ).val() )
                    })
                }
                configTM.find('#setColSize .menuTM').text('Settings are now Saved');
            }
        },
        listeners   = {
            resize      : function( ){
                $(window).resize(function(){
                    $('html').hasClass('fullplayer') && css.fullCss(18);
                })
            },
            navKey      : function( ){
                document.addEventListener('keydown', function(e){
                    if( $('input').is(':focus') ) return false;

                    var key = e.keyCode;
                    ( key == 37 || key == 39 ) && ( window.location.href = key == 37 ? config.prevDoc() : config.nextDoc() );
                    key == 66 && css.fullCss();
                    key == 27 && fn.esc();
                }, false);
            },
            navThumb    : function(e){
                var ContentElem     =   $( e ),
                    ContentLeft     =   parseInt( ContentElem.offset().left ),
                    ContentRight    =   ContentLeft + ContentElem.width();

                $(document).on('mouseup','#content',function(e){
                    var X_spot      =   e.clientX;
                    this == e.target && e.which == 1 && (
                    ( X_spot < ContentLeft || X_spot > ContentRight ) && (
                        window.location.href = X_spot < ContentLeft ? config.prevDoc() : config.nextDoc() ) );
                });

                listeners.navKey();
            },
            navVideo    : function( ){
                $(document).on('mouseup','#content, html.fullplayer',function(e){
                    this == e.target && e.which == 1 && g.ms === 0 && (
                        g.timer(64), $('html').hasClass('fullplayer') ? fn.esc() : css.fullCss() );
                });
                listeners.navKey();
                listeners.resize();
            },
            menuButtonTM: function( ){
                $( document ).on('mousedown','#menuButton',function(){
                    var elem = $('#menuTM'), width = $('.switchAble').width();
                    config.menuState = config.menuState ? false : true;
                    elem.length == 1 ? elem.toggle(0) : html.sideTM();
                    html.wrapWidth( width + 40 );
                })
            },
            openCloseTM : function( ){
                $( document ).on('mousedown','.openCloseTM',function(evt){
                    var elem = $('#holderTM');
                    evt.ctrlKey ? (
                        GM.manager('del'), alert('GM Settings are deleted') ) :
                        elem.length == 1 ? elem.toggle(256) : render.tm();
                })
            },
            menuTM      : function( ){
                $( document ).on('mouseup','.menuTM',function(e){
                    if( e.which !== 1 || e.target !== this ) return false;

                    var $this = $(this), command = $this.data('command'), page = $this.data('page'),
                        height = $this.data('height'), width = $this.data('width'), src = $this.data('src'), firstLine = $this.find('span').text();

                    switch( command ){
                        case 'about'            : html.aboutTM();                                   break;
                        case 'firstIntro'       : html.welcomeTM();                                 break;
                        case 'config'           : html.configTM( page );                            break;
                        case 'help'             : html.helpTM( page , 400);                         break;
                    //    case 'similarScripts'   : html.otherScript();                                 break;
                        case 'update'           : html.updatedTM();                                 break;
                        case 'video'            : html.videoTM( height, width, src, firstLine );    break;
                        case 'menu'             : html.sideTM();                                    break;
                        case 'submit'           : fn.submitForm();                                  break;
                        case 'setColSize'       : fn.setColSize();                                  break;
                        case 'contact'          : html.contactTM();                                 break;
                        default                 :                                                   break;
                    }
                });
                $( document ).on('mouseup','#holderTM .foot .checkbox input',function(){
                    GM_setValue('menuState', $( this ).is(':checked') ? false : true );
                });
            },
            setColSize  : function( ){
                var reloadCss = function(){
                    html.configTM( $('.switchAble').data('page')  );
                    $( '#configTM' ).find('#setColSize .menuTM').text('Save Settings');
                    css.basicCss();
                    config.imgHeight = null;
                    fn.imgHeight();
                };
                $(document).on('click','#configTM #pageSize input.size', function(){
                    var val = $( this ).val();
                    config.pageWidth = val;
                    config.pageWidthNR = config[val];
                    reloadCss(); });
                $(document).on('click','#configTM #columns input.col', function(){
                    config.thumbCol = $( this ).val();
                    reloadCss(); });
            }
        },
        html        = {
            wrapWidth   : function( width ){
                var menuWidth = config.menuState ? 175 : 0;
                $('.wrapperTM').width( menuWidth + width );
            },
            switcher    : function( elem ){
                var switchAble = $( '.switchAble' );
                switchAble.length == 1 ? switchAble.replaceWith( elem ) : elem.prependTo('.wrapperTM');
            },

            wrapTag     : function( text, tag, style ){
                style = style || '';
                return $( '<'+tag+'/>',{ class: style, text: text });
            },
            li_Item     : function( txt, cl, data, page ){
                return $( '<li>').append( cl == 'external' ? a(txt, data) : l(txt, cl, data, page) );
            },
            singleRow   : function( label, text ){
                var outer = $('<div/>',{ class: 'row' });
                return outer
                    .append( $('<span/>',{ class: 'label', text: label+':' }) )
                    .append( $('<span/>',{ class: 'details', html: text }) );
            },
            pager       : function( pageType, page, pageEnd ){
                var elem = $('<div/>',{ id:'pagerTM' }),
                    ul = $('<ul/>',{ class:'pagerUl myMenu' } );
                for( var i = 1; i < pageEnd + 1 ; i++  ){
                    ul.append( this.li_Item( 'page: ' + i, 'menuTM pageLi', pageType, i ).addClass( i === page ? 'active' : '' ) );
                }
                return elem.append( ul );
            },
            embeded     : function( height, width, src ){
                return $('<iframe/>',{ height:height, width:width, src:src, frameborder:0, allowfullscreen:true });
            },

            closeButton : function( ){
                return $('<i/>',{ id:'closeButton', class:'fa fa-times-circle fa-2x openCloseTM' });
            },
            menuButton  : function( ){
                return $('<i/>',{ id: 'menuButton', class: 'fa fa-bars fa-2x'})
            },
            copyright   : function( ){
                var span = function( cl){
                        return $('<span/>',{ class:cl})
                    },
                    copy    = $('<i/>',{ class:'fa fa-copyright' }),
                    chk     = $('<input/>',{ type:'checkbox' }).prop( "checked", config.menuState ),
                    span1   = span('checkbox').text('Always show menu').prepend(chk),
                    span2   = span('copyright').text(' 2015 Magnus Fohlström').prepend(copy);

                $('<div/>',{ class:'foot'}).append( span1 ).append( span2 ).appendTo('.wrapperTM');
            //    $('<div class="copyright">@2015 Magnus Fohlström</div>').appendTo('.wrapperTM');
            },

            StartTM     : function( ){
                var el = '<a class="monkeySettings openCloseTM" href="javascript:;">' +
                    '<li><img src="http://www.vporn.com/images/new_images/my-settings.png" width="16" height="16" alt="">' +
                    'MonkeyScript Setting</li></a><hr>',
                    button = '<i class="btn btn-default btn-sm openCloseTM" href="#"><i class=""></i>TM</i>';
                setTimeout(function() {
                    config.inMenu ?
                        $(el).insertBefore('#open-small-log .pcl') :
                        $(button).insertBefore('.authsection');
                },125);
            },
            holderTM    : function( ){
                $( '<span/>', { id: 'holderTM' }).appendTo('body');
            },
            wrapperTM   : function( ){
                $( '<div/>', { class: 'wrapperTM' })
                    .prepend( this.menuButton() )
                    .append( this.closeButton() )
                    .appendTo('#holderTM');
            },

            contHeadTM  : function( text ){
                return $( '<div/>', { class: 'contHeadTM', text: text });
            },
            contBodyTM  : function( html ){
                return $( '<div/>', { class: 'contBodyTM', html: html });
            },
            contentTM   : function( id, cl ){
                return $( '<div/>', { id:id, class: 'contentTM ' + cl });
            },

            sideTM      : function( ){
                var elem = html.contentTM(),
                    firstLine       = 'Menu',
                    render          = function(){
                        return  p(firstLine,'firstLine');
                    };
                elem.attr('id','menuTM')
                    .css({'width':'175px'})
                    .append( this.contBodyTM( render() ))
                    .append( this.menuTM() );

                config.menuState ? elem.css('display','block') :elem.css('display','none');
                elem.prependTo('.wrapperTM');
                listeners.menuTM();
            },
            menuTM      : function( ){
                var elul = $( '<ul>', { class: 'myMenu' });
                return elul
                    .append( this.li_Item('About','menuTM','about') )
                    .append( this.li_Item('Welcome','menuTM','firstIntro') )
                    .append( this.li_Item('Settings','menuTM','config',1) )
                    .append( this.li_Item('Instruction/Help','menuTM','help', 1) )
                //    .append( this.li_Item('Other Scripts','menuTM','similarScripts') )
                //    .append( this.li_Item('My Home Page','external','www.myDom.com') )
                    .append( this.li_Item('Contact','menuTM','contact') );
            },

            aboutTM     : function( ){
                var elem = this.contentTM(),
                    table = $('<div/>',{ id: 'table' }),
                    head            = 'About',
                    firstLine       = 'Script Details.',
                    presentation    = '',
                    render          = function(){
                        return  p( firstLine, 'firstLine')
                            +   p( presentation, 'normPresentation');
                    };

                table.append( html.singleRow('Name','VPorn.com - A New Layout II') )
                    .append( html.singleRow('Description','A unique great site got A new layout, with som added functionality and lost some. This script adds browser full video, bigger thumbnails, key and mouse navigation and interaction.') )
                    .append( html.singleRow('Version','0.40') )
                    .append( html.singleRow('Site','www.vporn.com') )
                    .append( html.singleRow('Runs at','document start') )
                    .append( html.singleRow('Created','2015-01-28') )
            //        .append( html.singleRow('Updated','2015-04-18') )
                    .append( html.singleRow('History v0.25','First Public release: 2015-02-11') )
                    .append( html.singleRow('History v0.40','Second Public release: 2015-04-16') )
                    .append( html.singleRow('Compatible','Greasemonkey, Tampermonkey') )
                    .append( html.singleRow('License','GNU GPL v3 (http://www.gnu.org/copyleft/gpl.html)') )
                    .append( html.singleRow('Copyright','2014+, Magnus Fohlström') );
            //        .append( html.singleRow('','') )

                elem.attr('id','aboutTM')
                    .addClass('switchAble')
                    .css({'width':'450px'})
                    .prepend( this.contHeadTM( head ) )
                    .append( this.contBodyTM( render() ) )
                    .append( table );

                this.wrapWidth(450);
                this.switcher(elem);
            },
            welcomeTM   : function( ){
                var elem = this.contentTM(),
                    head            = 'Welcome',
                    firstLine       = 'Hi THANKS for using this fabulous script.',
                    presentation    = 'Now you are part of something bigger. A New way to use this great site VPorn.com.\
                        \rThis is my first in line of series of scripts that will work with unique library of my functions. And this \
                        script will also inform you about whats '+cl('new','black')+' if there was an update. Also tells the news about other scripts that you \
                        may also be interested in.\rBefore you '+ em('start') +' using this script read the '+ l('instructions','menuTM','help',1) +' and listen ' +
                        'to my '+( v("video. ","1080","810","https://www.youtube-nocookie.com/embed/9chDANQxF2M","My First Test Embeded" ) ) +
                        ' about this script.\rAlso Take a look at the '+ l('settings','menuTM','config',1) + ' that this user-script has.',
                    render          = function(){

                        return   p( firstLine.toString(), 'firstLine')+p( presentation.toString(), 'normPresentation');

                    };

                elem.attr('id','welcomeTM')
                    .addClass('switchAble')
                    .css({'width':'400px'})
                    .prepend( this.contHeadTM( head ) )
                    .append( this.contBodyTM( render() ) );

                this.wrapWidth(400);
                this.switcher(elem);
            },
            configTM    : function( page ){
                var elem = this.contentTM( page ),
                    head            = 'Set your settings',
                    firstLine       = 'We all have our own preferences, choice is yours.',
                    part1           = '',
                    form            = function( ){
                        var objForm = function( name ){
                                return $('<form/>',{ id:name, name:name })
                            },
                            rad = function( value, no_Info ){
                                var Info    = value.length < 2 ? value : no_Info === undefined ? config[ value ]+ ' pixels.' : '',
                                    name    = value.length < 2 ? 'col'+ ' col' + value : 'size'+ ' ' + value,
                                    wrap    = $('<span/>',{ text: Info }),
                                    input   = $('<input/>',{ type:'radio', name:name, class:name, value:value });
                                return wrap.prepend( input );
                            },
                            chbox = function( value ){
                                var name    = 'cMore'+ ' ' + value,
                                    wrap    = $('<span/>',{ text: ' ' }),
                                    input   = $('<input/>',{ type:'checkbox', name:name, class:name, value:value });
                                return wrap.prepend( input );
                            },
                            pageTmp = $('<span/>'),
                            button  = $( '<ul>', { class: 'myMenu' });

                        switch ( page ) {
                            case 1:
                                var size = objForm('pageSize'), col = objForm('columns');
                                size.append( html.wrapTag('These fixed sizes can you choice', 'div', 'description') )
                                    .append( html.singleRow('Orginal', rad('orgWidth')) )
                                    .append( html.singleRow('Normal', rad('normWidth')) )
                                    .append( html.singleRow('Wide', rad('wideWidth')) )
                                    .append( html.singleRow('Extreme', rad('extraWidth')) );
                                    //.append( html.wrapTag('Dynamically changes when browser width size changes', 'div', 'description'))
                                    //.append( html.singleRow('Full', rad('fullWidth', 1)) )
                                    //.append( html.singleRow('80%', rad('d80Width', 1)) );

                                col.append( html.wrapTag('Number of columns video thumb nails are shown.', 'h4') )
                                    .append(
                                        html.singleRow('Columns',
                                            $('<span/>').append(rad('1')).append(rad('2')).append(rad('3')).append(rad('4')).append($('<br>'))
                                                .append(rad('5')).append(rad('6')).append(rad('7')).append(rad('8')).html()
                                        ));
                                pageTmp  = $('<span/>').append(size).append(col);
                                break;
                            case 2:
                                var more = objForm('more');
                                more.append(html.wrapTag('These fixed sizes can you choice', 'div', 'description'));
                                $.each( sharedData.settings2(), function(i,val){
                                    more.append( html.singleRow( val.title, chbox( val.name ) ) );
                                    c.i('nr: ' + i +', ' + val.name + ', ' + val.title+'.');
                                });
                                pageTmp  = $('<span/>').append(more);
                                break;
                        }
                        c.i('button','----------------==================--------------');
                        c.i('configTM page ',page);

                        button.attr('id','setColSize').attr('data-page',page ).append( html.li_Item('Save Settings','menuTM','setColSize') );
                        return pageTmp.append(button);//.append( html.pager( 'config', page, 2 ) );
                    },
                    render          = function(){
                        return  p( firstLine, 'firstLine')
                            +   p( part1, 'normPresentation')
                            +   '\n '
                            +   w('Page Width:', 'h4')
                            +   fn.obj2Str( form() );
                    };

                elem.attr('id','configTM')
                    .data('page',page)
                    .addClass('switchAble')
                    .css({'width':'400px'})
                    .prepend( this.contHeadTM( head ) )
                    .append( this.contBodyTM( render() ) );

                this.wrapWidth(400);
                this.switcher(elem);

                $('#pageSize').find('input.size.'+config.pageWidth).attr('checked', true);
                $('#columns').find('input.col'+config.thumbCol).attr('checked', true);

            },
            helpTM      : function( page, width ){
                var elem = this.contentTM(),
                    head         = 'Instructions - ' + page,
                    firstLine    = 'How to operate this special script',
                    page1        = function(){
                        return w('Choice what do you want help with:', 'h3')
                        +   '\r If you want to know about the Keyboard navigation and interaction then you click '+l('here','menuTM','help', 2)+'.'
                        +   '\r Where do you click with the mouse pointer to get something to react, find out '+l('here','menuTM','help', 3)+'.'
                        +   '\r A instruction video coming soon to you. The show coming '+v('here','title','videoLink','help', 3)+'.';
                    },
                    page2        = function(){
                        return w('Keyboard interaction navigation:', 'h3')
                            +   w('Video page:', 'h4')
                            +   fn.obj2Str( html.singleRow('N','Normal') )
                            +   fn.obj2Str( html.singleRow('W','Wide') )
                            +   fn.obj2Str( html.singleRow('O','Orginal') )
                            +   fn.obj2Str( html.singleRow('B','Enter Full Browser Player Mode') )
                            +   fn.obj2Str( html.singleRow('ESC','Exit Full Browser Player Mode') )
                            +   w('Thumb page:', 'h4')
                            +   fn.obj2Str( html.singleRow('Left arrow','Prev Page') )
                            +   fn.obj2Str( html.singleRow('Light arrow','Next Page') );
                    },
                    page3        = function(){
                        return w('Mouse Navigation:', 'h3')
                            +   w('You can click right side of page', 'div', 'mouseNav')
                            +   '\n '
                            +   w('Thumb page:', 'h4')
                            +   fn.obj2Str( html.singleRow('Left','Prev Page') )
                            +   fn.obj2Str( html.singleRow('Right','Next Page') )
                            +   '\n '
                            +   w('Video page:', 'h4')
                            +   fn.obj2Str( html.singleRow('Left or Right','Enter Full Browser Player Mode') );
                    },
                    render       = function(page){
                        var r = p( firstLine, 'firstLine'), cl = 'normPresentation';
                        switch ( page) {
                            case 1: r += p(page1(), cl); break;
                            case 2: r += p(page2(), cl); break;
                            case 3: r += p(page3(), cl); break;
                        }
                        return r;
                    };

                elem.attr('id','helpTM')
                    .addClass('switchAble ')
                    .data('page',page)
                    .css({'width': width+'px'})
                    .prepend( this.contHeadTM( head ) )
                    .append( this.contBodyTM( render(page) ).append( html.pager('help',page,3 ) ) );

                this.wrapWidth(width);
                this.switcher(elem);
            },
            updatedTM   : function( ){

            },
            videoTM   : function( height,width,src, firstLine ){
                var elem = this.contentTM( 'videoTM','switchAble' );

                elem.append( html.wrapTag( firstLine, 'p', 'firstLine') )
                    .append( this.contBodyTM( this.embeded(height,width,src) ) );

                config.menuState = false;
                $('#menuTM').hide();
                this.wrapWidth( parseInt( width ) + 40 );
                this.switcher(elem);
            },

            contactForm : function( id ){
                var elul = $( '<ul>', { class: 'myMenu' }),
                    form = $( '<div/>',{ id:id }),
                    formObj = function(type,name,txt,size,cl,min){
                        var typeVal = type == 'input' ? '<input/>' : '<textarea/>',
                            obj = $('<p/>',{ class: 'obj' })
                                .append( $('<label/>',{ for: 'c'+name, text: txt }) )
                                .append( type == 'input' ?
                                    $(typeVal,{ id: 'c'+name, name:name, size:size, minlength: min }) :
                                    $(typeVal,{ id: 'c'+name, name:name, col:size, minlength: min })
                                    );
                        return obj;
                    };
                return form
                    .append( formObj('input','name','Your Name:',30,'required',2) )
                    .append( formObj('input','email','Your E-Mail:',30,'required',5) )
                    .append( formObj('input','subject','Enter Subject:',30,'required',5) )
                    .append( formObj('text','comment','Enter Message:',30,'required',5) )
                    .append( elul.append( this.li_Item('Submit','menuTM','submit') ) );
            },
            contactTM   : function( ){

                var elem = this.contentTM('contactTM','switchAble'),
                    head            = 'Contact Me',
                    firstLine       = 'Here you have a simple form to contact me.',
                    presentation    = 'If you want to use your web e-mail or program click '
                        + a('here','mailto:[email protected]?subject=Tag:%20vporn.com:%20Enter%20Your%20Here') + '.',
                    render          = function(){
                        return  p( presentation, 'normPresentation');
                    };

                elem.attr('id','contactTM')
                    .addClass('switchAble')
                    .css({'width':'400px'})
                    .prepend( this.contHeadTM( head ) )
                    .append( p( firstLine, 'firstLine') )
                    .append( this.contactForm('myForm') )
                    .append( this.contBodyTM( render() ) );

                this.wrapWidth(400);
                this.switcher(elem);
            },

            preSortMenu : function( ){
                $( '<div/>', { class: 'grayarea wline', text: 'Sort Menu is loading' }).insertAfter('.catsmenu');
            }
        },
        render      = {
            main        : function( ){
                GM.manager('get');
                config.startWidth();
                css.head();
                css.basicCss();
            },
            tm          : function( ){
                css.fontsCss();
                css.tmCss();
                html.holderTM();
                html.wrapperTM();
                html.welcomeTM();
                html.sideTM();
                listeners.setColSize();
                listeners.menuButtonTM();
                html.copyright()
            }
        },
        observer    = new MutationObserver( function( mutations /*, observer */) {
            mutations.forEach( function( mutation ) {
                var newNodes = mutation.addedNodes; // DOM NodeList
                newNodes !== null &&
                    $( newNodes ).each( function( i, e ){
                        var $e = $(e);
                        $e.hasClass('bx')                   && fn.heightTime();
                        $e.attr('id') === 'as3_js'          && listeners.navVideo();
                        $e.hasClass('minititle')            && listeners.navThumb('.cholder');
                        $e.hasClass('left-account-menu')    && ( listeners.navThumb('.warapper-menu'), fn.sortMenu() );
                        $e.hasClass('warapper-menu')        && html.preSortMenu();
                        $e.hasClass('authsection')          && html.StartTM();
                        $e.hasClass('pagerwrap')            && fn.chkPager();
                    });
            });
        });

    GM_getValue('firstRun') === undefined && GM.first();

    //noinspection JSCheckFunctionSignatures
    observer.observe( document, { subtree: true, childList: true });

    render.main();
    c.i('VPorn ANewLayout');

    $(document).ready(function(){
        fn.heightTime();
        listeners.openCloseTM();
    });
}(jQuery));