(function($) {
    var params = {
        names: [],
        values: {},
        get: function(name, defValue) {
            return params.values[name] || defValue || '';
        }
    };
    var temp = (location.search||'?').substr(1).split('&');
    for (var i=0; i<temp.length; i++) {
        var parts = temp[i].split('=');
        var name  = unescape(parts[0]);
        var value = unescape(parts.slice(1).join('='));
        if (params.values.hasOwnProperty(name)) {
            if (params.values[name] instanceof Array) {
                params.values[name].push(value);
            } else {
                params.values[name] = [params.values[name], value];
            }
        } else {
            params.names.push(name);
            params.values[name] = value;
        }
    }
    window.AdService = new function() {
        this.startTime             = new Date();
        this.positions             = {};
        this.params                = {richmedia:'true', owner:'all/'};
        this.adserverAllowed       = true;
        this.adproxyAllowed        = true;
        this.googleadsAllowed      = true;
        this.statistics            = {requested:[], ignored:[]};
        this.googleParams          = {ad_output:'js', ad_type:'text', ad_client:'ca-gmx', adtest:'off'};
        this.lastRequestedType     = null;
        this.lastRequestedPosition = null;
        this.lastAdMoveToPosition  = null;
        this.currentIndex          = 0;
        this.advContainerId        = 'adv-current-container';
        this.advContainerClass     = 'adv-generic-container';
        this.advPromotionContent   = '<p class="adv-promotion-headline"><span>Promotion</span></p>';
        this.stylesheet            = {};
        
        this.baseAdserverUrl = '//adclient.uimserv.net/js.ng/';
        this.baseRefreshUrl  = '//adclient.uimserv.net/html.ng/';
        this.baseIframeUrl   = this.baseRefreshUrl;
        this.baseAdproxyUrl  = '//creativeproxy.uimserv.net/?LogoutAdProxy.service=pageuniteaser';
        //this.baseAdproxyUrl  = '//qsadproxyfe02.vdlan.cinetic.de?LogoutAdProxy.service=pageuniteaser&Params.styles=multiuniteaser_html,multiuniteaser_img';
        this.paramOrder      = {begin:['site', 'section', 'category', 'categorytype', 'pa', 'pg', 'pp', 'bandwidth', 'viewwidth', 'viewheight', 'region', 'cc', 'owner', 'posIndex', 'richmedia', 'posName', 'special', 'tagID'], end:['tile', 'transactionID']};
        
        this.gadpClassPrefix = 'adproxy';
        this.gadpModules     = [];
        this.gadpState       = 0;
        
        this.init = function(site, section, category, categoryType, params) {
            this.params.site          = site;
            this.params.section       = section;
            this.params.category      = category;
            this.params.categorytype  = categoryType;
            this.params.tile          = (Math.random().toString().substr(2) + Math.random().toString().substr(2)).substr(0, 30);
            this.params.transactionID = this.params.tile;
            params = params || {};
            for (var param in params) {
                if (!params.hasOwnProperty(param)) { continue; }
                this.params[param] = params[param];
            }
            this._appendUrlParams();
            this._initPositions();
            this._getViewport();
            document.write('<style type="text/css">#'+this.advContainerId+' { display: none; }<\/style>');
            this.stylesheet = document.styleSheets[Math.max(document.styleSheets.length-1, 0)];
        };
        this._appendUrlParams = function() {
            for (var i=0; i<params.names.length; i++) {
                var name = params.names[i];
                if (name.substring(0, 4) != '_ad.') { continue; }
                this.params[name.substr(4)] = params.get(name).split('|');
            }
        };
        this._initPositions = function() {
            this.positions = {
                top:         {                     adsize:['728x90', '468x60', '234x60', '778x90', '810x250']},
                rectangle:   {                     adsize:['300x250', '300x600']},
                content:     {special:'rectangle', adsize:['300x250', '600x250'], tagID:'contentad', _isPromotion:true},
                sky:         {                     adsize:['120x600', '160x600', '300x600', '320x600', '120x835', '160x835'], tagID:'sky_right'},
                popup:       {                     adsize:['1x1'], tagID:'ambient'},
                delight:     {special:'sky',       adsize:['120x600', '160x600', '300x600', '320x600', '120x835', '160x835'], tagID:'sky_lightbox', richmedia:'false'},
                '_gadproxy': {owner:null}
            };
        };
        this._getViewport = function() {
            this.viewport = {
                width:  $(window).width()  || -1,
                height: $(window).height() || -1
            };
            switch (true) {
                case this.viewport.width < 1000: this.params.viewwidth = '0'; break;
                case this.viewport.width < 1101: this.params.viewwidth = '1'; break;
                case this.viewport.width < 1221: this.params.viewwidth = '2'; break;
                case this.viewport.width < 1251: this.params.viewwidth = '3'; break;
                default:                         this.params.viewwidth = '4'; break;
            }
            this.params.viewheight = '0';
        };
        
        this.setPositions = function(positions) {
            this.clearPositions();
            for (var i in positions) {
                if (!positions.hasOwnProperty(i)) { continue; }
                this.positions[i] = positions[i];
            }
        };
        this.clearPositions = function() {
            this.positions = {};
        };
        this.addPosition = function(pos, special, sizes, params) {
            params = params || {};
            params.special = special;
            params.adsize  = sizes;
            this._initPosition(pos, params._disabled);
            params._disabled = this.positions[pos]._disabled;
            this.positions[pos] = params;
        };
        this.disablePosition = function(pos) {
            this._initPosition(pos, true);
        };
        this.enablePosition = function(pos) {
            this._initPosition(pos, false);
        };
        this.moveAdToPosition = function(pos) {
            this.lastAdMoveToPosition = pos;
        };
        this._initPosition = function(pos, isDisabled) {
            if (!this.positions[pos])     { this.positions[pos]           = {}; }
            if (isDisabled !== undefined) { this.positions[pos]._disabled = isDisabled; }
        };
        
        this.stopAdserverAds = function() {
            this.adserverAllowed = false;
        };
        this.stopAdproxyAds = function() {
            this.adproxyAllowed = false;
        };
        this.stopGoogleAds = function() {
            this.googleadsAllowed = false;
        };
        
        this.setParam = function(name, value) {
            this.params[name] = value;
        };
        this.setPositionParam = function(pos, name, value) {
            this._initPosition(pos);
            this.positions[pos][name] = value;
        };
        this.getParamString = function(ad) {
            var result = [];
            var params = {};
            var paramOrder = [];
            for (var param in this.params) {
                if (!this.params.hasOwnProperty(param) || param.substr(0, 1)=='_' || this.params[param]===null) { continue; }
                params[param] = this.params[param];
            }
            for (var param in ad) {
                if (!ad.hasOwnProperty(param) || param.substr(0, 1)=='_') { continue; }
                params[param] = ad[param];
            }
            for (var i=0; i<this.paramOrder.begin.length; i++) {
                var param = this.paramOrder.begin[i];
                if (!params[param]) { continue; }
                paramOrder.push(param);
            }
            var beginEnd = [].concat(this.paramOrder.begin, this.paramOrder.end);
            middleParams: for (var param in params) {
                if (!params.hasOwnProperty(param)) { continue middleParams; }
                for (var j=0; j<beginEnd.length; j++) {
                    if (param == beginEnd[j]) { continue middleParams; }
                }
                paramOrder.push(param);
            }
            for (var i=0; i<this.paramOrder.end.length; i++) {
                var param = this.paramOrder.end[i];
                if (!params[param]) { continue; }
                paramOrder.push(param);
            }
            var p = 0;
            for (var i=0; i<paramOrder.length; i++) {
                if (!params[paramOrder[i]]) { continue; }
                result[p] = [paramOrder[i], params[paramOrder[i]]];
                if (result[p][1] instanceof Array) {
                    var value = [];
                    for (var j=0; j<result[p][1].length; j++) {
                        value.push(this._escapeValue(result[p][0]) + '=' + this._escapeValue(result[p][1][j]));
                    }
                    result[p] = value.join('&');
                } else {
                    result[p] = this._escapeValue(result[p][0]) + '=' + this._escapeValue(result[p][1]);
                }
                p++;
            }
            return result.join('&');
        };
        this._escapeValue = function(val) {
            return encodeURIComponent(val).replace(/%2F/gi, '/');
        };
        this._inc = function(counter) {
            return (counter||0)+1;
        };
        this.getAdUrl = function(pos, baseUrl, params) {
            var ad = this.positions[pos];
            if (params) {
                for (var i in params) {
                    if (params[i]===false || !params.hasOwnProperty(i)) { continue; }
                    ad[i] = params[i];
                }
            }
            if (               pos.substr(0, 1)!='_') { ad.posName = pos; ad.posIndex = ++this.currentIndex; }
            if (!ad.special && pos.substr(0, 1)!='_') { ad.special = pos; }
            if (!ad.tagID   && pos.substr(0, 1)!='_') { ad.tagID   = ad.special; }
            return baseUrl+this.getParamString(ad);
        };
        
        this.ad = function(pos, target) {
            var ad = this.positions[pos];
            if (!ad)                   { return this.statIgnored(pos); }
            if (ad._type != 'iframe' && !target) {
                document.writeln('<div id="'+this.advContainerId+'">');
            }
            if (ad._disabled)          { return this.statIgnored(pos); }
            if (!this.adserverAllowed) { return this.statIgnored(pos); }
            this.lastRequestedType = 'ad';
            this.lastRequestedPosition = pos;
            if (ad._content) {
                $('script').last().before(ad._content).parent().show();
                ad._content = null;
                return this.statIgnored(pos);
            }
            var html = '';
            if (ad._type == 'iframe' || target) {
                var url = this.getAdUrl(pos, this.baseIframeUrl, {richmedia: 'false'});
                if (!ad._width || !ad._height) {
                    ad.adsize = ad.adsize instanceof Array ? ad.adsize : [ad.adsize];
                    ad._width = ad._height = 0;
                    for (var i=0; i<ad.adsize.length; i++) {
                        var size = (''+ad.adsize[i]).split('x');
                        ad._width  = Math.max(ad._width,  parseInt(size[0]));
                        ad._height = Math.max(ad._height, parseInt(size[1]));
                    }
                }
                html = '<iframe src="'+(url.replace(/&/g, '&amp;'))+'" width="'+ad._width+'" height="'+ad._height+'" frameborder="0" border="0" scrolling="no" marginwidth="0" marginheight="0"><\/iframe>';
            } else {
                var url = this.getAdUrl(pos, this.baseAdserverUrl);
                html = '<script type="text/javascript" src="'+(url.replace(/&/g, '&amp;'))+'"><\/script>';
            }
            if (target) {
                ad._container = $(target);
                ad._container.html(html);
            } else {
                document.writeln(html);
            }
            return this.statRequested(pos);
        };
        this.fly = function(special, sizes, params, target) {
            this.positions['_fly'] = {};
            this.addPosition('_fly', special, sizes, params);
            this.ad('_fly', target);
        };
        this.refresh = function(pos, width, height, params) {
            var ad = this.positions[pos];
            if (!ad)                   { return this.statIgnored(pos); }
            if (!ad._container)        { return this.statIgnored(pos); }
            if (ad._disabled)          { return this.statIgnored(pos); }
            if (!this.adserverAllowed) { return this.statIgnored(pos); }
            params = params || {};
            if (!params.adsize && params.adsize !== false) {
                params.adsize = width+'x'+height;
            }
            params.richmedia = 'false';
            var url = this.getAdUrl(pos, this.baseRefreshUrl, params);
            /* hotfix - to be improved */
            $('#advBanderole').hide();
            /* end of hotfix */
            var iframe = $('<iframe src="'+(url.replace(/&/g, '&amp;'))+'" frameborder="0" border="0" scrolling="no" marginwidth="0" marginheight="0"><\/iframe>');
            iframe.css({width: width, height: height});
            ad._container.html(iframe);
            return this.statRequested(pos);
        };
        
        this.gadproxy = function() {
            if (!$ || this.gadpState) { return; }
            if (!this.adproxyAllowed) { return; }
            var prefix = this.gadpClassPrefix;
            $('.'+prefix+'[class*="'+prefix+'-tagID-rcbox_"]:last:not(.'+prefix+'-tagID-rcbox_last)')
                .each(function() { this.className = this.className.replace(new RegExp(prefix+'-tagID-rcbox_\\d+\\s*'), ''); })
                .addClass(prefix+'-tagID-rcbox_last');
            var els = $('.'+prefix);
            if (!els.length) { return; }
            var url = this.getAdUrl('_gadproxy', this.baseAdproxyUrl+'&');
            var ads = [];
            var self = this;
            els.each(function() {
                self.gadpModules.push($(this));
                ads.push('ad='+self.getGadpAdParams($(this)));
            });
            document.writeln('<script type="text/javascript" src="'+url+'&'+ads.join('&')+'"><\/script>');
            $(function() { AdService.gadpInsertAll(); });
            this.lastRequestedType = 'gadproxy';
            this.gadpState = 'requested';
        };
        this.getGadpAdParams = function(el) {
            var re = new RegExp('\\s+'+this.gadpClassPrefix+'-([^\\s\\-]+)-(\\S+)', 'g');
            var cn = el.attr('class');
            var className;
            var result = [];
            while (className = re.exec(cn)) {
                result.push(this.gadpEscape(className[1])+':'+this.gadpEscape(className[2]));
            }
            return result.join(';');
        };
        this.gadpEscape = function(value) {
            value = unescape(value.replace(/=/g, '%'));
            return escape(value.toString()).replace(/:/g, '%3A').replace(/;/g, '%3B'); 
        };
        this.gadpInsertAll = function() {
            if (!window.adProxyModules.length) { return window.setTimeout(function() { AdService.gadpInsertAll(); }, 100); }
            if (this.gadpModules.length > window.adProxyModules.length) { return; }
            for (var i=0; i<this.gadpModules.length; i++) {
                var el = document.getElementById(window.adProxyModules[i]);
                if (!el || $(el).children().children().length==0) {
                    $(this.gadpModules[i]).parent('.wrapper').hide();
                    continue;
                }
                $(this.gadpModules[i]).parent('.wrapper').show();
                this.gadpModules[i].html($(el).remove('script'));
            }
            this.gadpState = 'finished';
        };
        
        this.cleanup = function() {
            var el = $('#'+this.advContainerId);
            if (!el.length) { return; }
            document.writeln('<\/div>');
            if (this.lastRequestedPosition) {
                this.positions[this.lastRequestedPosition]._container = el;
            }
            if (el.length) {
                el.removeAttr('id');
                el.addClass(this.advContainerClass);
                var p = el.parent();
                if (this.lastAdMoveToPosition) {
                    $('script', el).remove();
                    this._initPosition(this.lastAdMoveToPosition);
                    this.positions[this.lastAdMoveToPosition]._content = el;
                    el.remove();
                }
                var isempty = false;
                if (!$('>div.'+this.advContainerClass+'>*:not(script)', p).length) {
                    isempty = true;
                    if ($('>*:not(script)', p).length<=1) {
                        p.hide();
                    }
                } else {
                    p.show();
                }
                if ((this.positions[this.lastRequestedPosition]||{})._isPromotion && !isempty) {
                    el.before(this.advPromotionContent);
                }
            }
            this.lastRequestedType = null;
            this.lastRequestedPosition = null;
            this.lastAdMoveToPosition = null;
        };
        
        this.googleAd = function(conf) {
            if (!this.googleadsAllowed) { return; }
            for (var i in this.googleParams) {
                if (!this.googleParams.hasOwnProperty(i)) { continue; }
                if (conf[i]) { continue; }
                conf[i] = this.googleParams[i];
            }
            for (var i in conf) {
                if (!conf.hasOwnProperty(i)) { continue; }
                window['google_'+i] = conf[i];
            }
            this.lastRequestedType = 'google';
            document.writeln('<script type="text/javascript" src="//pagead2.googlesyndication.com/pagead/show_ads.js"><\/script>');
        };
        
        this.statIgnored = function(pos) {
            this._initPosition(pos);
            this.statistics.ignored.push(pos);
            this.positions[pos]._ignored = this._inc(this.positions[pos]._ignored);
        };
        this.statRequested = function(pos) {
            this._initPosition(pos);
            this.statistics.requested.push(pos);
            this.positions[pos]._requested = this._inc(this.positions[pos]._requested);
        };
        this.getStatistics = function() {
            var missing   = [];
            for (var i in this.positions) {
                if (!this.positions.hasOwnProperty(i)) { continue; }
                if (this.positions[i]._requested)      { continue; }
                if (this.positions[i]._ignored)        { continue; }
                if (i.substr(0, 1) == '_')             { continue; }
                missing.push(i);
            }
            return {
                requested: this.statistics.requested,
                ignored:   this.statistics.ignored,
                missing:   missing,
                duration:  new Date()*1 - this.startTime*1
            };
        };
    };
    window.adProxyModules = [];
})(jQuery);

