/*
 * Name: simad.js
 * Version: 2.6.4
 * Autor: Joachim Kuban, Gleb Kotov, Benedikt Weiner, Paul Krion
 * ############### WARNING ###############
 * DON'T EDIT THIS FILE, IT WAS GENERATED BY SPROCKETS
 * #####################################
 *
*/
/**
 * @namespace Main namespave of the SIMAD. All functionality must be placed here.
 */

var SIMAD = {
	/**
	 * @memberOf SIMAD
	 * @description Version of the SIMAD
	 */
	VERSION: '2.6.4',


	config: function(params) {
		var result = this.CmsAdapter.config(params);
		return result;
	},

	init: function() {
		return this.CmsAdapter.init();
	},

	preInit: function() {
		return this.CmsAdapter.preInit();
	},

	postInit: function() {
		return this.CmsAdapter.postInit();
	},


	doAd: function(adId, state) {
		return this.CmsAdapter.doAd(adId, state);
	},

	finalize: function() {
		return this.CmsAdapter.finalize();
	},

	reloadAds: function(adIds) {
		return this.CmsAdapter.reloadAds(adIds);
	},

	getVideoAdRequest: function(args) {
		return this.CmsAdapter.getVideoAdRequest(args);
	},

	getAd: function(adId) {
		return this.CmsAdapter.getAd(adId);
	},

	getAds: function(filter) {
		return this.CmsAdapter.getAds(filter);
	},

	addAd: function(params) {
		return this.CmsAdapter.addAd(params);
	},

	updateConfig: function(params) {
		return this.CmsAdapter.updateConfig(params);
	},

	getConfig: function() {
		return this.CmsAdapter.getConfig();
	},

	hideAds: function() {
		return this.CmsAdapter.hideAds();
	},

	showAds: function() {
		return this.CmsAdapter.showAds();
	},

	newSession: function(json) {
		return SIMAD.CmsAdapter.newSession(json);
	},

	closeSession: function(doNotClear) {
		return SIMAD.CmsAdapter.closeSession(doNotClear);
	},

	bindEvent: function(eventName, eventId, eventFunc) {
		return SIMAD.CmsAdapter.bindEvent(eventName, eventId, eventFunc);
	},

	unbindEvent: function(eventName, eventId) {
		return SIMAD.CmsAdapter.unbindEvent(eventName, eventId);
	},

	/**
	 * External interface for debug method.
	 * This function is provided for the compability to SIMAD 1G
	 *
	 * @memberOf SIMAD
	 */
	debug: function(type, message) {
		switch (type) {
			case "warn":
				SIMAD.Log.warn(message);
			break;
			case "error":
				SIMAD.Log.error(message);
			break;

			case "log":
			default:
				SIMAD.Log.log("log", message);
			break;
		}
	},


	/**
	 * External interface for error method.
	 * This function is provided for the compability to SIMAD 1G
	 *
	 * @memberOf SIMAD
	 */
	error: function(message) {
		this.debug("error", message);
	},


	/**
	 * External interface for getAdInIFrame method.
	 * This function is provided for the compability to SIMAD 1G
	 *
	 * @memberOf SIMAD
	 */
	getAdInIFrame: function() {
		return SIMAD.CmsAdapter.getAdInIFrame();
	},


	/**
	 * External interface for pre method.
	 * Dispatches the call to the init-funciton of the cms adapter
	 *
	 * @memberOf SIMAD
	 */
	pre: function() {
		return this.preInit();
	},


	/**
	 * External interface for post method.
	 * Dispatches the calls to init or poststream doAd-calls of the cms adapter
	 *
	 * @memberOf SIMAD
	 */
	post: function() {
		if (!this.__postSteps) { // Init all post steps / scenario
			this.__postSteps = [];
			this.__postStepCounter = 0;

			var $s = SIMAD.Core.$s;
			var maxInits = 0;
			for (var i in $s.adServerAdapters) {
				if ($s.adServerAdapters[i].settings.initFunctions) {
					var initsAmounts = [];
					for (var j in $s.adServerAdapters[i].settings.initFunctions) {
						initsAmounts.push($s.adServerAdapters[i].settings.initFunctions[j].length);
					}
					maxInits = maxInits + SIMAD.Util.max(initsAmounts);
				}
			}
			for (var l = 0; l < maxInits; l++) {
				this.__postSteps.push({"func": this.postInit});
			}

			var ads = SIMAD.Core.getAds();
			ads = SIMAD.Core.sortAds(ads);


			for (var k = 0; k < ads.length; k++) {

				this.__postSteps.push({
					"func": SIMAD.doAd,
					"args": [ads[k].getId(), SIMAD.Rendering.OUTOFSLOT_BEGIN]
				});
				this.__postSteps.push({
					"func": SIMAD.doAd,
					"args": [ads[k].getId(), SIMAD.Rendering.OUTOFSLOT_END]
				});
			}

			this.__postSteps.push({"func": this.finalize});
		}

		if (typeof(this.__postSteps[this.__postStepCounter]) !== 'undefined') {
			var step = this.__postSteps[this.__postStepCounter];
			var args = step.args || [];
			if (typeof(step.func) === 'function') {
				step.func.apply(this, args);
			}
			this.__postStepCounter++;
		}
	}
};
if (typeof SIMAD === 'undefined') { SIMAD = {}; }

SIMAD.Util = {
	/**
	*
	* extend
	*
	* Merges 2 JSONs, objects or arrays together. If the first parameter is true, the objects will be merges for all levels (deep-mode)
	*
	* @param [{boolean} deepmode], {Object} source, {Object} update
	* @returns Object
	*/
	extend: function () {
		var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;

		if (typeof target === "boolean") {
			deep = target;
			target = arguments[1] || {};
			i = 2;
		}

		if ( typeof target !== "object" && typeof target !== "function" )
			target = {};

		if (length == i) {
			target = this;
			--i;
		}

		for ( ; i < length; i++) {
			if ((options = arguments[i]) != null) {
				for ( var name in options ) {
					var src = target[name], copy = options[name];

					if (target === copy) {
						continue;
					}

					if (deep && copy && typeof copy === "object" && !copy.nodeType) {
						target[name] = SIMAD.Util.extend( deep,
							src || ( copy.length != null ? [] : {} )
						, copy );
					} else if (copy !== undefined) {
						target[name] = copy;
					}
				}
			}
		}
		return target;
	},


	/**
	* unique
	*
	* Removes all duplicate elements from an array of elements.
	*
	* @param array
	* @returns array
	*/
	unique: function(array) {
		var ret = [], done = {};
		try {
			for (var i = 0, length = array.length; i < length; i++) {
				if (!done[array[i]]) {
					done[array[ i ]] = true;
					ret.push(array[i]);
				}
			}
		} catch(e) {
			ret = array;
		}
		return ret;
	},


	/**
	* max
	*
	* Calculates the maximum value in the array
	*
	* @param array
	* @returns *
	*/
	max: function(array) {
		var m;
		for (var i = 0; i < array.length; i++) {
			if (m === undefined || array[i] > m) {
				m = array[i];
			}
		}
		return m;
	},


	/**
	* filter
	*
	* Returns the elements of the  array passed througth the filter function. The filter function get the array element as parameter and must return true or false.
	*
	* @params {array} [array], {Function} [filter]
	* @returns array
	*/
	filter: function(obj, filter) {
		var result = [];
		for (var i in obj) {
			if (obj.hasOwnProperty(i)) {
				if (typeof(filter) === "function") {
					if (filter(obj[i])) { result.push(obj[i]); }
				} else {
					result.push(obj[i]);
				}
			}
		}

		return result;
	},

	/**
	*
	* includeJS
	*
	*
	* Includes an JavaScript-file to the source. If the option lazy is true, it only returns the render string without writing it to the page.
	*
	* @param {string} url, {boolean} lazy
	* @returns string
	*
	*/
	includeJS: function (url, lazy) {
		var output = '<sc' + 'ript src="' + url + '" type="text/java'+'script"></scr' + 'ipt>';
		if (!lazy) { document.write(output); }
		return output;
	},


	/**
	*
	* inArray
	*
	*
	* Checks if a value exists in an array
	*
	* @param {Array} array, {*} value
	* @returns boolean
	*
	*/
	inArray: function (array, item) {
		for (var i = 0; i < array.length; i++) {
			if (item == array[i]) { return true; }
		}
		return false;
	},


	/**
	*
	* indexInArray
	*
	*
	* Returns the index of the element in an array
	*
	* @param {Array} array, {*} value
	* @returns number
	*
	*/
	indexInArray : function(array, item) {
		for (var i = 0; i < array.length; i++) {
			if (item === array[i]) { return i; }
		}
		return -1;
	},


	/**
	*
	* wrapScript
	*
	* Returns the passed Javascript code with <script> tag wrapped.
	*
	* @param {String} code.
	* @returns String
	*
	*/
	wrapScript: function (code) {
		return	'<scr'+'ipt language="Java'+'Script" type="text/java'+'script">'+ code + '</scr'+'ipt>';
	},


	/**
	* getLength
	*
	* Returns the number of (own) members in an object
	*
	* @param {Object} obj.
	* @returns number
	*/
	getLength: function(obj) {
		var b = 0;
		for (var a in obj) {
			if (obj.hasOwnProperty(a)) { b++; }
		}
		return b;
	},



	/**
	* joinObjects
	*
	* Torns the values of property for passed objects into string with the separator. The values could be processed/formatted with the formator funciton
	*
	* @param {Object} objArray, {String} prop, {String} separator, [{Function} formatFunc]
	* @returns String
	*/
	joinObjects: function(objArray, prop, separator, formatFunc) {
		var firstRun = true;
		var output = [];
		if (objArray && prop) {
			for (var i = 0; i < objArray.length; i++) {
				var el;
				if(typeof objArray[i][prop] === "function"){
					el = objArray[i][prop]();
				}else{
					el = objArray[i][prop];
				}
				if (typeof formatFunc === 'function') { el = formatFunc(el); }
				if(el){
					output.push(el);
				}
			}
		}
		return output.join(separator);
	},


	/**
	* browser
	*
	* Browser recognizing object. SIMAD.Util.browser.msie retrurns true for Internet Explorer
	*
	*/
	browser: {
		version: (navigator.userAgent.toLowerCase().match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],
		safari: /webkit/.test( navigator.userAgent.toLowerCase() ),
		opera: /opera/.test( navigator.userAgent.toLowerCase() ),
		msie: /msie/.test( navigator.userAgent.toLowerCase() ) && !/opera/.test( navigator.userAgent.toLowerCase() ),
		mozilla: /mozilla/.test( navigator.userAgent.toLowerCase() ) && !/(compatible|webkit)/.test( navigator.userAgent.toLowerCase() )
	},


	/**
	* htmlEntities
	*
	* Encodes all Tags of the passed HTML into entities
	*
	* @param {String} str
	* @returns String
	*/
	htmlEntities: function (str) {
		if (typeof str === "string") {
			return str.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
		}
		return str;
	},


	/*
		TODO Benedikt wants to comment this
	*/
	toJSON: function(o){

        var type = typeof(o);

        if (o === null){return "null";}
        if (type == "undefined"){return undefined;}
        if (type == "number" || type == "boolean"){return o + "";}
        if (type == "string"){return this.quoteString(o);}
        if (type == 'object')
        {
            if (o.constructor === Date)
            {
                var month = o.getUTCMonth() + 1;
                if (month < 10){ month = '0' + month;}

                var day = o.getUTCDate();
                if (day < 10){ day = '0' + day;}

                var year = o.getUTCFullYear();

                var hours = o.getUTCHours();
                if (hours < 10){ hours = '0' + hours;}

                var minutes = o.getUTCMinutes();
                if (minutes < 10){ minutes = '0' + minutes;}

                var seconds = o.getUTCSeconds();
                if (seconds < 10){ seconds = '0' + seconds;}

                var milli = o.getUTCMilliseconds();
                if (milli < 100){ milli = '0' + milli;}
                if (milli < 10){ milli = '0' + milli;}

                return '"' + year + '-' + month + '-' + day + 'T' +
                             hours + ':' + minutes + ':' + seconds +
                             '.' + milli + 'Z"';
            }

            if (o.constructor === Array)
            {
                var ret = [];
                for (var i = 0; i < o.length; i++){
                    ret.push( this.toJSON(o[i]) || "null" );
                }
                return "[" + ret.join(",") + "]";
            }

            var pairs = [];
            for (var k in o) {
                var name;
                var type = typeof k;

                if (type == "number"){name = '"' + k + '"';}
                else if (type == "string"){name = this.quoteString(k);}
                else{ continue; } //skip non-string or number keys

                if (typeof o[k] == "function") {  continue; } //skip pairs where the value is a function.

                var val = this.toJSON(o[k]);

                pairs.push(name + ":" + val);
            }

            return "{" + pairs.join(", ") + "}";
        }

   	},

	/*
		TODO Benedikt wants to comment this
	*/
   	 quoteString : function(string){
   	 	 var __meta = {
	        '\b': '\\b',
	        '\t': '\\t',
	        '\n': '\\n',
	        '\f': '\\f',
	        '\r': '\\r',
	        '"' : '\\"',
	        '\\': '\\\\'
	    };
	    var __escapeable = /["\\\x00-\x1f\x7f-\x9f]/g;
	    if (string.match(this.__escapeable))
        {
            return '"' + string.replace(__escapeable, function (a){
                var c = __meta[a];
                if (typeof c === 'string'){ return c;}
                c = a.charCodeAt();
                return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16);
            }) + '"';
        }
        return '"' + string + '"';
   	 },


	strToBool: function(str){

        switch(str.toLowerCase()){

                case "true": return true;

                case "false": return false;

                default: return Boolean(str);

        }
	},


	getLocationParams: function() {
		var locationString = window.location.search;
		var locationParamsObj = {};

		if (locationString) {
			locationString = locationString.substring(1);
			locationString.replace( /(?:^|&)([^&=]*)=?([^&]*)/g, function ($0, $1, $2) {
				if ($1) { locationParamsObj[$1] = $2; }
			});
		}

		return locationParamsObj;
	}

};
if (typeof SIMAD !== "undefined") {
	SIMAD.Loading = {
		/**
		 *
		 * set Instream rendering
		 * the AdTag is rendered immediatly in place
		 *
		 * @constant INSTREAM
		 */
		INSTREAM: "INSTREAM",

		/**
		 *
		 * set Poststream rendering
		 * the AdTag is rendered postoned after all tags are handled
		 *
		 * @constant POSTSTREAM
		 */
		POSTSTREAM: "POSTSTREAM",

		/**
		 *
		 * set OnEvent rendering
		 * the AdTag is not rendered, until an according event is triggered.
		 * e.g. Flash-Intro
		 *
		 * @constant ONEVENT
		 */
		ONEVENT: "ONEVENT",

		/**
		 *
		 * this value is only used for the global 'loading' setting.
		 * this is the default value for the global setting
		 * <p/>TODO: more specific explanation
		 *
		 * @constant INDIVIDUAL
		 */
		INDIVIDUAL: "INDIVIDUAL"
	};


	/**
	 * @namespace  Format
	 *
	 * defines predefined AdId
	 *
	 *
	 * @type JSON
	 */
	SIMAD.Format = {
		/**
		 *
		 * Static predefined AdId for a FULLBANNER AdTag
		 *
		 * @constant FULLBANNER
		 */
		FULLBANNER: "FULLBANNER",
		/**
		 *
		 * Static predefined AdId for a SKYSCRAPER AdTag
		 *
		 * @constant SKYSCRAPER
		 */
		SKYSCRAPER: "SKYSCRAPER",
		/**
		 *
		 * Static predefined AdId for a MEDIUMRECTANGLE AdTag
		 *
		 * @constant MEDIUMRECTANGLE
		 */
		MEDIUMRECTANGLE: "RECTANGLE",
 		RECTANGLE: "RECTANGLE",
		/**
		 *
		 * Static predefined AdId for a POPUP AdTag
		 *
		 * @constant POPUP
		 */
		POPUP: "POPUP",
		/**
		 *
		 * Static predefined AdId for a PERFORMANCEBOX1 AdTag
		 *
		 * @constant PERFORMANCEBOX1
		 */
		PERFORMANCEBOX1: "PERFORMANCEBOX1",
		/**
		 *
		 * Static predefined AdId for a PERFORMANCE1 AdTag
		 *
		 * @constant PERFORMANCE1
		 */
		PERFORMANCE1: "PERFORMANCE1",
		/**
		 *
		 * Static predefined AdId for a PERFORMANCE2 AdTag
		 *
		 * @constant PERFORMANCE2
		 */
		PERFORMANCE2: "PERFORMANCE2",
		/**
		 *
		 * Static predefined AdId for a ADSENSETEXT AdTag
		 *
		 * @constant ADSENSETEXT
		 */
		ADSENSETEXT: "ADSENSETEXT",

		/**
		 * MAXIAD is used for community Logout page
		 */
		MAXIAD: "MAXIAD",
		WALLPAPER: "WALLPAPER",
		POWERLAYER: "POWERLAYER",
		POWERBANNER: "POWERBANNER",
		POWERRECTANGLE: "POWERRECTANGLE",
		POPUP_WINDOW: "POPUP_WINDOW",
		BILLBOARD: "BILLBOARD",
		FIREPLACE: "FIREPLACE",
		SIDEBAR: "SIDEBAR",
		PUSHDOWN: "PUSHDOWN",
		HALFPAGE: "HALFPAGE"

	};

	SIMAD.AdTag = SIMAD.Format;

	SIMAD.ContentType = {
		DEFAULT: 		"DEFAULT",
		HOME: 			"HOME",
		PAGE: 			"PAGE",
		VIDEO_OVERVIEW: "VIDEO_OVERVIEW",
		VIDEO: 			"VIDEO",
		RICH_VIDEO: 	"RICH_VIDEO",
		LIVE_VIDEO:		"LIVE_VIDEO",
		GALLERY: 		"GALLERY",
		GALLERY_IMAGE: 	"GALLERY_IMAGE",
		GAME: 			"GAME",
		SHOP: 			"SHOP",
		RAFFLE: 		"RAFFLE",
		COMMUNITY:		"COMMUNITY",
		ERROR:			"ERROR",

		MCCONTENT:		"VIDEO_OVERVIEW",
		MCPLAYER:		"RICH_VIDEO",
		CPPLAYER:		"VIDEO"
	};


	SIMAD.Rendering = {
		INSLOT_BEGIN: "inSlotBegin",
		INSLOT_END: "inSlotEnd",
		OUTOFSLOT_BEGIN: "outOfSlotBegin",
		OUTOFSLOT_END: "outOfSlotEnd"
	};

	SIMAD.Event = {
		ADRELOAD: "onAdReloadFinished",
		BEFORE_RELOAD: "beforeReload",
		RELOAD: "afterReload",
		RENDERED: "onRendered",
		LOAD: "onLoad",
		BEFORE_IFRAMEAD: "onIFrameAdStarted",
		IFRAMEAD: "onIFrameAdFinished"
	}
}
/**
 * @fileoverview
 * SIMAD is the implementation of the SevenOneIntermedia AdAbstractionLayer
 *
 * This layer provides the functionality to process metadata mainly given by the CMS
 * to a AdServer request.
 *
 * @author Benedikt Weiner, Gleb Kotov, Joachim Kuban
 *  <p>ALL FUNCTIONS OF THIS 'CLASS' ARE PRIVATE!</p>
 */

/**
 * @ignore This comment is used as code pool for jsdoc
 *
 * test: (demo for the (at) symbol <code>&#64;extends</code> tag)
 * <br>Text in <b>bold</b> and <i>italic</i> and a
 * link to <a href="http://sf.net">SourceForge</a>
 * @constant NAME / hint write comment BEFORE this identifier
 *
 */


if (typeof(SIMAD) !== 'undefined') {

/**
 *
 * @namespace SIMAD.Core
 * @class SIMAD.Core
 *
 * The core of the abstraction layer. Responsable for:
 * <ul>
 * <li>Configuration</li>
 * <li>Initialisation</li>
 * <li>Ad rendering routing</li>
 * <li>Data Storage</li>
 * <li>Data Store manipulation</li>
 * <li>Session handling</li>
 * <li>Ad reload rotation</li>
 * <li>Ad monipulation</li>
 * <li>Event handling</li>
 * <li>Common functions</li>
 * </ul>
 *
 */
	SIMAD.Core = {
		/**
		 * Pointer to the current session (sugar code)
		 *
		 * @memberOf SIMAD.Core
		 * @public
		 * @type Object
		 */
		$s: null,

		/**
		 * Default settings JSON
		 *
		 * @memberOf SIMAD.Core
		 * @public
		 * @type Object
		 */
		defaults: {
			"adServers": [],
			"adServerAdapters": {},
			"adFree": false,
			"brand": "",
			"subchannel1": "",
			"subchannel2": "",
			"subchannel3": "",
			"subchannel4": "",
			"subchannel5": "",
			"breadcrumb": "",
			"adServerSpecific": {},
			"cmsSpecific": {},
			"ads": {},
			"dynamicAds": {},
			"isSingleAdSession": false,
			"debug": {"all": false}
		},


		/**
		 * Data Store object
		 *
		 * @memberOf SIMAD.Core
		 * @public
		 * @type Object
		 */
		data: {
			sessions: []
		},


		/**
		 * Indocates if the SIMAD is in a iFrame or not (needed for iFrame ads)
		 *
		 * @memberOf SIMAD.Core
		 * @public
		 * @type Boolean
		 * @default false
		 */
		inIFrame: false,


		/**
		 * Pointer to the ad, what will be processed in an iFrame of this SIMAD instance.
		 *
		 * @memberOf SIMAD.Core
		 * @public
		 * @type SIMAD.Ad
		 * @default null
		 */
		adInIFrame: null,

		/**
		 * JSON object with all GET parameters.
		 *
		 * @memberOf SIMAD.Core
		 * @private
		 * @type Object
		 * @default null
		 */
		__locationParams: null,


		/**
		 * Array of the ads in the order of initialisation.
		 * Used for Adreload to reload ads in the same order as they were initial rendered.
		 *
		 * @memberOf SIMAD.Core
		 * @private
		 * @type Array
		 */
		__loadingOrder: [],

		__initializingOrder: [],


		/**
		 * Indicates, if the initialisation block is processed.
		 * Used to separate instream and poststream initialisation blocks.
		 *
		 * @memberOf SIMAD.Core
		 * @private
		 * @type Boolean
		 */
		__initBlockCompleted: false,


		/**
		 * Informaton object for Adreoad rotation.
		 * Stores information about ads to reload, if Adreload if is currently running and the iterator for the Adreload rotation.
		 *
		 * @memberOf SIMAD.Core
		 * @private
		 * @type Object
		 */
		__reloadAdsRotation: {
			ads: [],
			running: false,
			currentIndex: -1
		},


		/**
		 * This object stores information about the DOM check. DOM check identificates, if the DOM is ready for modifications.
		 * Used for IE DOM check.
		 *
		 * @memberOf SIMAD.Core
		 * @private
		 * @type Object
		 */
		__domCheck: {
			containerId: 'SIMAD_domSafe',
			containerRendered: false
		},


		/**
		 * Event listener of the SIMAD.Core. Stores events and corresponding function to be called on those events.
		 *
		 * @memberOf SIMAD.Core
		 * @private
		 * @type Object
		 */
		__eventListener: {
			'onAdReloadFinished': [],
			'onConfigFinished': []
		},

		/**
		 * Object stores the original config given be the CMS
		 */
		__originalConfig: {},


		/**
		 * Inits JSON object and maps it to the internal variables / data store.
		 *
		 * @memberOf SIMAD.Core
		 * @public
		 * @param {Object} params JSON with the SIMAAD setting.
		 * @returns {Boolean} True for succeeded initialisation, false for errors
		 */
		config: function(params) {

			this.newSession(params);

			if (this.getLocationParams().simad_debug_all !== undefined) {
				this.$s.debug.all = SIMAD.Util.strToBool(this.getLocationParams().simad_debug_all);
			}

			if (this.getLocationParams().simad_adfree !== undefined){
				this.$s.adFree = this.getLocationParams().simad_adfree;
			}

			if (this.$s.adServers === undefined) { this.$s.adServers = []; }
			var adServers = this.getUsedAdServersFor(this.getAds());
			this.$s.adServers = SIMAD.Util.unique(adServers.concat(this.$s.adServers));

			for (var i = 0; i < this.$s.adServers.length; i++) {
				if (SIMAD.AdServerAdapter[this.$s.adServers[i]]) {
					this.$s.adServerAdapters[this.$s.adServers[i]] = SIMAD.AdServerAdapter[this.$s.adServers[i]].config();
				} else {
					SIMAD.Log.error('The adserver adapter ' + this.$s.adServers[i] + ' is not available');
				}
			}
			this.triggerEvent("onConfigFinished");
			return true;
		},


		/**
		 * Alternative config, in case the SIMAD is placed in an iFrame ad.
		 *
		 * @memberOf SIMAD.Core
		 * @public
		 */
		configInIFrame: function() {
			if (parent.SIMAD) {
				this.data = parent.SIMAD.Core.data;
				this.$s = parent.SIMAD.Core.$s;

				this.inIFrame = true;
				this.adInIFrame = this.getAd(this.getLocationParams().ad_id);

				if (this.adInIFrame) {
					var adServerAdapter = this.getAdServerAdapterFor(this.adInIFrame);
					if (adServerAdapter) {
						adServerAdapter.config();
					} else {
						SIMAD.Log.error('The adserver adapter for the ad ' + this.adInIFrame.getId() + ' is not available');
					}
				} else {
					SIMAD.Log.error("The ad in iframe can't be found. ad_id in location is " + this.getLocationParams().ad_id);
				}


			} else {
				SIMAD.Log.error("The configInIFrame was called but the master in undefined...");
			}
		},




		/**
		 * Calles the internal adserver initialisaton functions in the instream init block
		 *
		 * @memberOf SIMAD.Core
		 * @public
		 */
		preInit: function() {
			this.init('pre');
		},


		/**
		 * Calles the internal adserver initialisaton functions in the poststream init block
		 *
		 * @memberOf SIMAD.Core
		 * @public
		 */
		postInit: function() {
			this.init('post');
		},


		/**
		 * Calls the internal adserver initialisaton functions
		 *
		 * @memberOf SIMAD.Core
		 * @public
		 * @param {String} state The position in markup where the init function was called. 'pre' and 'post' are allowed.
		 */
		init: function(state) {
			if (SIMAD.Util.browser.msie && !this.__domCheck.containerRendered) {
				if (!document.getElementById(this.__domCheck.containerId)) {
					document.write('<div id="' + this.__domCheck.containerId + '" style="display:none"></div>');
				}
				this.__domCheck.containerRendered = true;
			}

			if (!this.$s.adFree) {
				if (!this.inIFrame) {

					for (var i in this.$s.adServerAdapters) {
						this.$s.adServerAdapters[i].init(state);
					}
				} else {

					var adServerAdapter = this.getAdServerAdapterFor(this.adInIFrame);
					if (adServerAdapter) { adServerAdapter.init(state); }
				}
			}
		},







		/**
		 * Starts the Adreload rotation.
		 *
		 * @memberOf SIMAD.Core
		 * @public
		 */
		reloadAds: function(params) {
			params = SIMAD.Util.extend({
				ads: [],
				force: true
			}, params);

			if (!this.$s.adFree) {
				if (!(params.ads.length > 0 && this.__reloadAdsRotation.running) && !(this.__reloadAdsRotation.running && !params.force)) {
					SIMAD.Log.log("Adreload", "Start the reload rotation");
					var domCheck = this.isDOMSafe();
					var self = this;
					if (domCheck === -1) {
						SIMAD.Log.error("Impossible to reload the ads. The DOM is not ready.");
						return;
					} else if (domCheck === 0) {
						setTimeout(function() { self.reloadAds(params); }, 50);
						return;
					}
					SIMAD.Log.log("Adreload", "DOM is ready");

					var adsToReload = [];
					if (params.ads.length > 0) {
						var newSessionAds = [];
						for (var a = 0; a < params.ads.length; a++) {
							if (this.getAd(params.ads[a])) {
								newSessionAds.push(this.getAd(params.ads[a]));
							} else {
								SIMAD.Log.warn("Ad with the id " + params.ads[a] + " doesn't exist.");
							}
						}
						this.newSession();
						for (var i = 0; i < newSessionAds.length; i++) {
							this.addAd(newSessionAds[i]);
						}
						var self = this;
						this.bindEvent("onAdReloadFinished", "groupAdReload", function(event) {
							SIMAD.closeSession(true);
							SIMAD.unbindEvent("onAdReloadFinished", "groupAdReload");
						});
					}

					adsToReload = this.getAds( function(ad) { return ad.isActive(); } );
					adsToReload = this.sortAds(adsToReload);

					this.$s.sessionId = this.getSessionId(true);
					SIMAD.Log.log("Adreload", "Set new session");

					var usedAdServers = this.getUsedAdServersFor(adsToReload);
					for (var i = 0; i < usedAdServers.length; i++) {
						if (this.$s.adServerAdapters[usedAdServers[i]] && typeof(this.$s.adServerAdapters[usedAdServers[i]].reloadAds) === "function") {
							adsToReload = this.$s.adServerAdapters[usedAdServers[i]].reloadAds(adsToReload);
						}
					}
					SIMAD.Log.log("Adreload", "Reload following ads", adsToReload);

					for (var j = 0; j < adsToReload.length; j++) {
						var reloader = this.getReloaderFor(adsToReload[j]);
						if (reloader) {
							reloader.clean(adsToReload[j]);
						} else {
							SIMAD.Log.warn("Can't find the reloader for the ad", adsToReload[j].getId());
						}
					}

					if (this.__reloadAdsRotation.running) { SIMAD.Log.warn("reloadAd() is called while one reload rotation is still running."); }
					this.__reloadAdsRotation = {
						ads: adsToReload,
						running: true,
						currentIndex: -1
					};

					this.reloadNextAd();
				}

			} else {
				this.triggerEvent("onAdReloadFinished");
			}
		},


		/**
		* Find the nest ad to reload and put it to the corresponding reloader
		*
		* @memberOf SIMAD.Core
		* @public
		* @returns {Boolean} True for processed ad, false for no action or complition of the reload rotation
		*/
		reloadNextAd: function() {
			if (!this.$s.adFree) {
				if (this.__reloadAdsRotation.running && this.__reloadAdsRotation.ads[this.__reloadAdsRotation.currentIndex + 1]) {
					this.__reloadAdsRotation.currentIndex++;
					var adToReload = this.__reloadAdsRotation.ads[this.__reloadAdsRotation.currentIndex];

					var reloader = this.getReloaderFor(adToReload);
					reloader.reloadAd(adToReload);
					return true;
				} else {
					this.__finishAdReload();
				}
				return false;
			}
		},



		/**
		* Adds an ad object to the current session. If the ad with the passed ID is already exists, the existed ad will be deliveried
		*
		* @memberOf SIMAD.Core
		* @public
		* @param {SIMAD.Ad} ad Ad to add
		* @returns {SIMAD.Ad} The added ad or the existed ad with the same ID
		*/
		addAd: function(ad) {
			if (!this.$s.ads){ this.$s.ads = {};}

			if (ad) {
				if (this.getAd(ad.getId()) !== undefined) { // proof if as with the same id is already exists
					SIMAD.Log.warn("The ad with id " + ad.getId() + " is already exists.");

					return this.getAd(ad.getId());
				} else {
					this.$s.ads[ad.getId()] = ad;

					this.__initializingOrder.push(ad);
					SIMAD.Util.unique(this.__initializingOrder);

					var self = this;
					ad.bindEvent('onRendered', 'core', function(event) {
						self.__completeAd(event.calledFromAd);
					});

					return ad;
				}
			}

			return undefined;
		},


		/**
		* Returns the ad object with the passed Id. Returns undefined if the ad wasn't found.
		*
		* @memberOf SIMAD.Core
		* @public
		* @param {String} adId ID of the ad to find
		* @returns {SIMAD.Ad | undefined} Ad with the ID or undefined
		*/
		getAd: function(adId) {
			try {
				if (this.$s.ads) {
					if (adId !== undefined) {
						return this.$s.ads[adId];
					} else {
						SIMAD.Log.error("The id passed to function getAd() is not valid.");
					}
				} else {
					SIMAD.Log.warn("Trying to rich the ad with the id " + adId + ", but the ads array is not yet initialized. How can it be?");
				}
			} catch (err ) {
				SIMAD.Log.error("simad.Core:getAd Exception:" + err);
			}
			return undefined;
		},


		/**
		* Returns an array of all ads passed througth the filter function. The filter function get the ad as parameter and must return true or false
		*
		* @memberOf SIMAD.Core
		* @public
		* @param {Function} filter Filer function
		* @returns {Array} Array of matched ads
		*/
		getAds: function(filter) {
			return SIMAD.Util.filter(this.$s.ads, filter);
		},


		sortAds: function(adsToSort) {
			if (adsToSort && adsToSort.length > 0) {
				var self = this;
				adsToSort.sort(function(a, b) {
					return SIMAD.Util.indexInArray(self.__initializingOrder, a) - SIMAD.Util.indexInArray(self.__initializingOrder, b);
				});

				adsToSort.sort(function(a, b) {
					return SIMAD.Util.indexInArray(self.__loadingOrder, a) - SIMAD.Util.indexInArray(self.__loadingOrder, b);
				});

				for (var i in this.$s.adServerAdapters) {
					adsToSort = this.$s.adServerAdapters[i].sortAds(adsToSort);
				}
			}
			return adsToSort;
		},



		/**
		* Returns a JSON object with all public configs from the current session. All internal values will be removed.
		*
		* @memberOf SIMAD.Core
		* @public
		* @returns {Object} Copy of the config JSON from the data store.
		*/
		getConfig: function() {
			var configJSON = SIMAD.Util.extend({}, this.$s);

			delete configJSON.adServerAdapters;
			delete configJSON.ads; // the public interface to the ads is SIMAD.Core.getAds();
			delete configJSON.sessionId; // the public interfave to the session is SIMAD.Core.getSessionId();
			delete configJSON.isSingleAdSession;  // hide internal information

			return configJSON;
		},

		/**
		 * retrun original config given be the CMS
		 */
		getOriginalConfig:function(){
			return SIMAD.Util.extend(true, {}, this.__originalConfig);
		},

		/**
		 * set original config given be the CMS, please only call once
		 */
		setOriginalConfig:function(config){

			this.__originalConfig = SIMAD.Util.extend(true,{},config);
		},

		/**
		* Updates/Extends the internal configs JSON to the passed values.
		*
		* @memberOf SIMAD.Core
		* @public
		* @param {Object} configJSON JSON with configs to extend
		* @returns {SIMAD.Core} The core itself
		*/
		updateConfig: function(configJSON) {
			if (configJSON) {
				if (configJSON.adServerAdapters) 	{ delete configJSON.adServerAdapters; }
				if (configJSON.ads) 				{ delete configJSON.ads; }
				if (configJSON.sessionId) 			{ delete configJSON.sessionId; }
				if (configJSON.isSingleAdSession)		{ delete configJSON.isSingleAdSession; }



				if (this.$s) {
					if (configJSON.video) { delete this.$s.video; }
					if (configJSON.dynamicAds && configJSON.dynamicAds.exceptOf){ delete this.$s.dynamicAds.exceptOf };

					if(configJSON.channel){
						var channelArray = ["channel", "subchannel1", "subchannel2", "subchannel3", "subchannel4", "subchannel5"];
						for (var iPath = 0 ;  iPath < channelArray.length ; iPath ++) {
							if(configJSON[channelArray[iPath]]){
								this.$s[channelArray[iPath]] = configJSON[channelArray[iPath]];
							}else{
								this.$s[channelArray[iPath]] = undefined;
							}
						}
					}

					SIMAD.Util.extend(true, this.$s, configJSON);
				} else {
					SIMAD.Log.error("The updateConfig() function can't be called until the SIMAD is initializied with config() call.");
				}
			}
			return SIMAD;
		},


		/**
		 * Retruns the video ad request string.
		 *
		 * @memberOf SIMAD.Core
		 * @public
		 * @param {Object} args Video settings object
		 * @returns {String} Video ad request string
		 */
		getVideoAdRequest: function(args) {
			var result;
			if (this.$s.video.__adServer !== undefined && this.$s.adServerAdapters[this.$s.video.__adServer]) {
				result = this.$s.adServerAdapters[this.$s.video.__adServer].getVideoAdRequest(args);
			} else {
				result = '';
			}
			return result;
		},


		/**
		* Hides the ad in DOM if it's presented where
		*
		* @memberOf SIMAD.Core
		* @public
		* @param {SIMAD.Ad} ad Ad to hide
		* @returns {Boolean} True if the Ad was successful hidden, false if it wasn't found or not resented in DOM
		*/
		hideAd: function(ad) {
			if (ad && ad.getWrapper() && ad.getWrapper() !== null && typeof(ad.getWrapper()) === "object") {
				ad.getWrapper().style.display = "none";
			}
			ad.setVisibility(false);
			return ad;
		},


		/**
		* Shows the ad in DOM if it's presented where
		*
		* @memberOf SIMAD.Core
		* @public
		* @param {SIMAD.Ad} ad Ad to show
		* @returns {Boolean} True if the Ad was successful shown, false if it wasn't found or not resented in DOM
		*/
		showAd: function(ad) {
			if (ad && ad.getWrapper() && ad.getWrapper() !== null && typeof(ad.getWrapper()) === "object") {
				if(ad.getWrapperElementName() === "div"){
					ad.getWrapper().style.display = "block";
				}else{
					ad.getWrapper().style.display = "inline";
				}
			}
			ad.setVisibility(true);
			return ad;
		},


		/**
		* Hides all active ads in the current session.
		*
		* @memberOf SIMAD.Core
		* @public
		* @returns {SIMAD.Core} SIMAD.Core itself
		*/
		hideAds: function() {
			var ads = this.getAds();
			for (var i = 0; i < ads.length; i++) {
				ads[i].hide();
			}
			return SIMAD;
		},


		/**
		* Shows all active ads in the current session.
		*
		* @memberOf SIMAD.Core
		* @public
		* @returns {SIMAD.Core} SIMAD.Core itself
		*/
		showAds: function() {
			var ads = this.getAds();
			for (var i = 0; i < ads.length; i++) {
				ads[i].show();
			}
			return SIMAD;
		},


		/**
		* Removes the passed ad representation from the DOM (if exists)
		*
		* @memberOf SIMAD.Core
		* @public
		* @param {SIMAD.Ad} ad Ad to clear
		* @returns {SIMAD.Core} SIMAD.Core itself
		*/
		clearAd: function(ad) {
			if (ad) {
				if (ad.isReloaded()) {
					var reloader = this.getReloaderFor(ad);
					if (reloader) {
						reloader.clean(ad);
					} else {
						SIMAD.Log.warn("Can't find the reloader for the ad ", ad.getId());
					}
				} else {
					var wrapper = ad.getWrapper();
					if (wrapper) { wrapper.innerHTML = ""; }
					if (ad.getFormat() === SIMAD.Format.FULLBANNER) {
						SIMAD.Core.clearBillboard(ad);
					}
				}
			}
			return this;
		},



		clearBillboard: function(ad) {
			try {
				var billboardId = ad.getWrapper().id + "-billboard";
				var billboardContainer = document.getElementById(billboardId);
				billboardContainer.innerHTML = "";
				billboardContainer.style.display = "none";
			} catch (err) {}
		},


		/**
		* Deletes the ad from the DOM and DataStore completely
		*
		* @memberOf SIMAD.Core
		* @public
		* @param {SIMAD.Ad} ad Ad to delete
		* @returns {SIMAD.Core} SIMAD.Core itself
		*/
		deleteAd: function(inputAd, doNotClear) {
			doNotClear = doNotClear || false;
			var ad = this.getAd(inputAd.getId());
			if (ad) {
				var adId = ad.getId();
				if (!doNotClear) {
					this.clearAd(ad);
				}
				if (this.$s.ads[adId]) { delete this.$s.ads[adId]; }

				if (this.$s.isSingleAdSession) {

					this.$s.isSingleAdSession = false;
					this.closeSession();

					if (this.getAd(adId)) {
						this.deleteAd(this.getAd(adId));
					}
				}
			}
			return this;
		},


		/**
		* Creates a new session with the passed configs. All other configs will be copied from the current session.
		*
		* @memberOf SIMAD.Core
		* @public
		* @param {Object} configJSON Config JSON, identical to JSON for {@link SIMAD.Core#config config()} function
		* @returns {SIMAD.Core} SIMAD.Core itself
		*/
		newSession: function(configJson) {
			var config = {};
			var adServerAdapters = {}; // Cache adserver adapters, because they won't be extended by the Util.extend function
			if (this.$s !== null) {
				config = this.getConfig();
				adServerAdapters = this.$s.adServerAdapters;
			}

			config = SIMAD.Util.extend(true, config, configJson);

			var ads = (typeof(config.ads) !== 'undefined' && typeof(config.ads.length) === 'number') ? config.ads.slice() : [];
			delete config.ads;

			if (this.__abortAdReload()) { SIMAD.Log.warn("Adreload was aborded by the new session"); }

			this.data.sessions.push(SIMAD.Util.extend(true, {}, this.defaults, config));
			this.$s = this.data.sessions[this.data.sessions.length - 1];

			if (ads) {
				for (var i = 0; i < ads.length; i++) {
					this.addAd(new SIMAD.Ad(ads[i]));
				}
			}

			this.$s.sessionId = this.getSessionId(true);

			this.$s.adServerAdapters = adServerAdapters;

			return this;
		},


		/**
		 * Close the current session. All ads of this session will be deleted with {@link SIMAD.Core#deleteAd SIMAD.Core.deleteAd} function. The previous session will be set as current.
		 * If the data store contains only one session, this function will ignored.
		 *
		 * @memberOf SIMAD.Core
		 * @public
		 * @returns {SIMAD.Core} SIMAD.Core itself
		 */
		closeSession: function(doNotClear) {
			SIMAD.Log.log("Core", "close the session with ID" + this.getSessionId());

			if (this.data.sessions.length > 1) {
				var ads = this.getAds();
				if (!doNotClear) {
					for (var i = 0; i < ads.length; i++) {
						ads[i].del();
					}
				}

				if (this.__abortAdReload()) { SIMAD.Log.warn("Aborting the Adreload before closing the session"); }

				this.data.sessions.pop();
				this.$s = this.data.sessions[this.data.sessions.length - 1];
			}
			return this;
		},


		/**
		* Support for the 1G interface SIMAD.Ad.load().
		* Creates new session with the selected ad and set this to "isSingleAdSession".
		* The SingleAdSession must be delete when the only ad will deleted.
		*
		* @memberOf SIMAD.Core
		* @public
		* @param {SIMAD.Ad} inputAd Ad to load
		* @returns {SIMAD.Core} SIMAD.Core itself
		*/
		loadAd: function(inputAd) {
			var cachedAd;
			var ad = this.getAd(inputAd.getId());
			if (ad) {
				cachedAd = ad;
				this.newSession();
				this.addAd(cachedAd);
				this.$s.isSingleAdSession = true;
				this.reloadAds();
			}
			return this;
		},


		/**
		 * Add a function to the core event
		 *
		 * @memberOf SIMAD.Core
		 * @public
		 * @param {String} eventName Name of the event the function should binded with.
		 * @param {String} eventId ID of the binding. Needed for unbinding.
		 * @param {Function|String} eventFunc Function (name) to bind.
		 */
		bindEvent: function(eventName, eventId, eventFunc) {
			SIMAD.Log.log("Core Event", "binding event " + eventName + " with id=" + eventId + " to the core");

			if (typeof(this.__eventListener[eventName]) !== 'undefined') {
				if (typeof(eventFunc) === "function" && typeof(eventId) === "string") {
					var existedEvent = SIMAD.Util.filter(this.__eventListener[eventName], function(event) { event.eventId === eventId; });

					var newEvent = {
						"eventId": eventId,
						"eventFunction": eventFunc,
						"caller": SIMAD
					};

					if (existedEvent.length > 0) {
						var index = 0;
						for (var i = 0; i < this.__eventListener[eventName].length; i++) {
							if (this.__eventListener[eventName][i].eventId === eventId) { index = i; }
						}
						this.__eventListener[eventName][index] = newEvent;
					} else {
						this.__eventListener[eventName].push(newEvent);
					}

				} else {
					SIMAD.Log.warn("Core Event: to bind event function: " + eventFunc + " with the eventId=" + eventId + "   is impossible. Please Check datatypes.");
				}
			} else {
				SIMAD.Log.warn("Core Event: the event  " + eventName + " is not supported in core.");
			}
		},


		/**
		 * Unbind a function from the event (if the binding exists)
		 *
		 * @memberOf SIMAD.Core
		 * @private
		 * @param {String} eventName Name of the event.
		 * @param {String} eventId ID of the event binding
		 */
		unbindEvent: function(eventName, eventId) {
			SIMAD.Log.log("Core Event","unbind event " + eventName +" with eventId=" + eventId + " from the core" );
			if (typeof(this.__eventListener[eventName]) !== "undefined" && typeof(eventId) === "string"){
				var eventIndex = -1;
				for (var i = 0; i < this.__eventListener[eventName].length; i++) {
					if (this.__eventListener[eventName][i].eventId === eventId) { eventIndex = i; }
				}
				if (eventIndex >= 0) {
					this.__eventListener[eventName].splice(eventIndex, 1);
				} else {
					SIMAD.Log.info("Core Event","event " + eventName + " with the eventId=" + eventId +" dosn't exist and cannot be unbinded");
					return false;
				}
			} else {
				SIMAD.Log.warn("Core Event: unbinding the event " + eventName + " with the eventId: " + eventId + " in core is not possible. Please check datatypes.");
				return false;
			}
			return true;
		},


		/**
		 * Triggers an event.
		 *
		 * @memberOf SIMAD.Core
		 * @public
		 * @param {String} eventName Name of the event to trigger.
		 */
		triggerEvent: function(eventName){
			SIMAD.Log.log("Core Event","triggerEvent " + eventName + " for the core");
			if (typeof this.__eventListener[eventName] !== "undefined") {
				var eventObjs = this.__eventListener[eventName].slice();
				for (var i=0; i < eventObjs.length; i++) {
					if (typeof(eventObjs[i].eventFunction) === 'function') {
						eventObjs[i].eventFunction(eventObjs[i]);
					}
				}
			} else {
				SIMAD.Log.warn("the event " + eventName + " in core is not supported");
				return false;
			}
			return true;
		},



		/**
		* Returns the ID of the current session. If this id is not yet set -> it creates and stores one.
		*
		* @memberOf SIMAD.Core
		* @public
		* @param {Boolean} [generateNew] If true, the session ID will be reset.
		* @returns {Number} Session ID
		*/
		getSessionId: function(generateNew) {
			if (!this.$s.sessionId || generateNew) {
				this.$s.sessionId = String(Math.random()).substring(2, 11);
				SIMAD.Log.log("Core", "Generated new session id", this.$s.sessionId);
			}
			return this.$s.sessionId;
		},


		 /**
	     * Returns the top level domain for the page. It is extracted from the JSON configuration.
	     *
	     * @memberOf SIMAD.Core
	     * @public
	     * @returns {String | undefined} Top Level domain or undefined if can't be calculated
	     */
		getTLD: function() {
			if (typeof(this.$s.domain === "string")) {
				var arr = this.$s.domain.split(".");
				return arr[arr.length - 1];
			}
			return undefined;
		},


		/**
		* Returns a pointer to the current session.
		*
		* @memberOf SIMAD.Core
		* @returns {Object} Pointer to the current session
		*/
		getCurrentSession: function() {
			return this.$s;
		},


		/**
		* getLocationParams
		*
		* Returns an obejct containing all GET parameters. If no parameters available -> return an empty object.
		*
		* @params void
		* @returns Object
		*/
		getLocationParams: function() {
			if (!this.__locationParams) {
				this.__locationParams = SIMAD.Util.getLocationParams();
			}

			return this.__locationParams;
		},


		/**
		 * Returns a pointer to the responsible renderer for the passed ad.
		 *
		 * @memberOf SIMAD.Core
		 * @public
		 * @param {type} ad Ad, the renderer is responsible for.
		 * @returns {Object} Renderer or undifined if not found
		 */
		getRendererFor: function(ad) {
			var renderer = undefined;
			if (ad) {
				var mapping = {};
				mapping[SIMAD.Loading.POSTSTREAM] = SIMAD.Renderer.PoststreamRenderer;
				mapping[SIMAD.Loading.INSTREAM] = SIMAD.Renderer.InstreamRenderer;

				if (this.inIFrame) {
					if (!ad.isActive()) { SIMAD.Log.warn("Trying to render inactive ad in the frame. The inactive ads must be ignored at the ad reload."); }
					renderer = SIMAD.Renderer.IFrameRenderer;
				} else if (!ad.isActive()) {
					renderer = SIMAD.Renderer.OnEventRenderer;
				} else {
					renderer = mapping[ad.getLoading()];
				}


				if (!renderer) { SIMAD.Log.error("The render for the method " + ad.getLoading() + " in the mapping of the function getRendererFor() (in the Core) is not defined"); }
			}
			return renderer;
		},


		/**
		* Finds the right reloader for the passed ad. Hook the corresponding adserver adapter.
		*
		* @memberOf SIMAD.Core
		* @public
		* @param {SIMAD.Ad} ad Ad, the reloader is responsible for.
		* @returns {Object | undefined} A pointer to the corresponding reloader or undefined, if the reloader wasn't found.
		*/
		getReloaderFor: function(ad) {
			var reloader;

			var adServerAdapter = this.getAdServerAdapterFor(ad);
			if (adServerAdapter && typeof(adServerAdapter.getReloaderFor) === "function") { reloader = adServerAdapter.getReloaderFor(ad); }

			if (reloader === undefined) { return SIMAD.Reloader.ReplacementFrameReloader; }

			return reloader;
		},


		/**
		 * Finds the responsible adserver adapter for the passed ad.
		 *
		 * @memberOf SIMAD.Core
		 * @public
		 * @param {SIMAD.Ad} ad Ad, the adserver adapter is responsible for.
		 * @returns {Object | undefined} A pointer to the corresponding adserver adaper or undefined, if the adserver adapter wasn't found.
		 */
		getAdServerAdapterFor: function(ad) {
			var adServerAdapter;
			if (this.inIFrame && ad === this.adInIFrame && ad) {
				adServerAdapter = SIMAD.AdServerAdapter[ad.getAdServer()];
			} else if (ad) {
				adServerAdapter = this.$s.adServerAdapters[ad.getAdServer()];
				if (!adServerAdapter) { SIMAD.Log.warn("The adserver " + ad.getAdServer() + " for the ad " + ad.getId() + " is not initialized."); }
			}
			return adServerAdapter;
		},


		/**
		 * Returns an array of adservers (names), which are required for the passed list of ads.
		 *
		 * @memberOf SIMAD.Core
		 * @public
		 * @param {Array} ads Array of ads
		 * @returns {Array} Array of adserver names
		 */
		getUsedAdServersFor: function(ads) {
			var adServers = [];

			if (ads) {
				for (var i = 0; i < ads.length; i++) { adServers.push(ads[i].getAdServer()); }
				adServers = SIMAD.Util.unique(adServers);
			}

			return adServers;
		},


		/**
		 * Returns the stadart ID of the wrapper for the passed ad.
		 *
		 * @memberOf SIMAD.Core
		 * @public
		 * @param {SIMAD.Ad} ad Ad, wrapper ID is getting for.
		 * @returns {String} ID of the wrapper
		 */
		getWrapperId: function(ad) {
			return "SIMAD_wrapper_" + ad.getId();
		},


		/**
		* This function check if the DOM can be manipulated in IE at the moment. It returns 1 for "safe", 0 for "not yet safe" and -1 for "error"
		*
		* @memberOf SIMAD.Core
		* @public
		* @returns {Number} Check result as number
		*/
		isDOMSafe: function() {
			if (SIMAD.Util.browser.msie) {
				if (!this.__domCheck.counter) {
					this.__domCheck.container = document.getElementById(this.__domCheck.containerId);
					this.__domCheck.counter = 0;
				}

				if (this.__domCheck.container && this.__domCheck.container.doScroll) {
					try {
						this.__domCheck.container.doScroll('right');
						return 1;
					} catch(e) {
						this.__domCheck.counter++;
						return (this.__domCheck.counter > 40) ? -1 : 0;
					}
				} else {
					SIMAD.Log.error("The dom check is impossible.");
					return -1;
				}
			}
			return 1;
		},



		allowDynamicAd: function(format) {
			var allow = false;

			if (this.$s.dynamicAds) {
				allow = (this.$s.dynamicAds.include === "all");
				if (this.$s.dynamicAds.exceptOf) {
					if (format === undefined && this.$s.dynamicAds.include === "none" && this.$s.dynamicAds.exceptOf.length > 0) {
						allow = true;
					} else if (format !== undefined) {
						for (var i = 0; i < this.$s.dynamicAds.exceptOf.length; i++) {
							if (this.$s.dynamicAds.exceptOf[i] === format) {
								allow = !allow;
								break;
							}
						}
					}
				}
			}
			return allow;
		},



		/**
		* Renders the Ad at the passed state.
		* (The Ad will be passed to the right Renderer and AdServerAdapter.renderAd())
		*
		* @memberOf SIMAD.Core
		* @private
		* @param {String} adId ID of the ad to render
		* @param {String} state Name of the state. "inSlotBegin", "inSlotEnd", "outOfSlotBegin", "outOfSlotEnd" are allowed.
		*/
		__doAd: function(adId, state) {
			if (!this.__initBlockCompleted) { this.__onInitBlockCompleted(); }

			if (!this.$s.adFree) {
				var ad = this.getAd(adId);
				if (ad) {
					var adServerAdapter = this.getAdServerAdapterFor(ad);
					if (adServerAdapter) { // Do not render the ad if adserver is undefined
						var renderer = undefined;
						if (typeof(adServerAdapter.getRendererFor) === "function") { renderer = adServerAdapter.getRendererFor(ad); }
						if (renderer === undefined) { renderer = this.getRendererFor(ad); }

						if (renderer) {
							if (state === "inSlotBegin") { this.__loadingOrder.push(ad); }

							var requiredRenderStatus = {
								"inSlotBegin" : 	0,
								"inSlotEnd" : 		1,
								"outOfSlotBegin" : 	2,
								"outOfSlotEnd" : 	3
							};

							if (ad.getRenderStatus() === requiredRenderStatus[state] || ad.getPlaceholder() !== null) { // do not check for status if placeholder is defined. No instream doAd called are requered then.
								if (typeof(renderer[state]) === "function") {
									ad.incRenderStatus();
									renderer[state](ad);
								} else {
									SIMAD.Log.error("The render function " + state + "is not defined in renderer " + renderer.getName());
								}

							} else {
								SIMAD.Log.warn("doAd() at " + state + " is called not in place for the ad " + ad.getId());
							}
						} else {
							SIMAD.Log.error("The render for the ad " + ad.getId() + " isn't found.");
						}
					} else {
						SIMAD.Log.error("The ad " + ad.getId() + " can't be rendered, because the corresponding adserver is not initialized.");
					}
				} else {
					SIMAD.Log.warn("Ad with the id " + adId + " does not exist.");
				}
			}
		},


		/**
		 * Triggers the finalisation proccess (drop 'onFinalize' events)
		 *
		 * @memberOf SIMAD.Core
		 * @private
		 */
		__finalize: function() {
			if (this.inIFrame) {
				if (this.adInIFrame) { this.adInIFrame.triggerEvent('onIFrameAdFinished'); }
			}

			for (var i in this.$s.adServerAdapters) {
				if (typeof this.$s.adServerAdapters[i].finalize === 'function'){ this.$s.adServerAdapters[i].finalize(this.inIFrame)};
			}

			if (this.$s.onFinished !== undefined) {
				if (typeof(this.$s.onFinished) === 'string' && typeof(window[this.$s.onFinished]) === 'function') {
					window[this.$s.onFinished]();
				} else if (typeof(this.$s.onFinished) === 'function') {
					this.$s.onFinished();
				}
			}
		},


		/**
		* This function will be called if the instream init block is finished (completed)
		*
		* @memberOf SIMAD.Core
		* @private
		*/
		__onInitBlockCompleted: function() {
			this.__initBlockCompleted = true;
			for (var i in this.$s.adServerAdapters) {
				this.$s.adServerAdapters[i].onInitBlockCompleted();
			}
		},


		/**
		 * This functions will be called 'onRendered' evenf of the ad. Additionaly the reloader used directly (because of iFrame SIMAD must be adressed).
		 * Last step of the ad rendering: set dimentions, set ad delivered and triggers the onLoadCallback event of the ad.
		 *
		 * @memberOf SIMAD.Core
		 * @private
		 * @param {SIMAD.Ad} ad Ad to complete
		 */
		__completeAd: function(ad) {
			if (ad) {
				var adServerAdapter = this.getAdServerAdapterFor(ad);
				if (adServerAdapter) {
					var dimensions = adServerAdapter.getDimensions(ad);
					if (dimensions && dimensions.length >= 2) {
						ad.setDimensions(dimensions);
					} else {
						SIMAD.Log.warn("Can't set dimensions for the ad " + ad.getId());
					}

					if (typeof(adServerAdapter.isDelivered) === "function") {
						ad.setDelivered(adServerAdapter.isDelivered(ad));
					}
				}

				ad.triggerEvent("onLoad");
			}
		},


		__finishAdReload: function() {
			if (this.__reloadAdsRotation.running) {
				this.__reloadAdsRotation = {
					ads: [],
					running: false,
					currentIndex: -1
				};

				this.triggerEvent("onAdReloadFinished");
			}
		},


		__abortAdReload: function() {
			if (this.__reloadAdsRotation.running) {
				this.__finishAdReload();
				return true;
			}
			return false;
		}


	};


	if (SIMAD.Renderer === undefined) { SIMAD.Renderer = {}; }

	/**
	 * @namespace SIMAD.Renderer
	 * @class SIMAD.Renderer.Base
	 *
	 * Base class for the renderers. Contains default rendering functions.
	 */
	SIMAD.Renderer.Base = {
		__name: "Base",

		getName: function() {
			return this.__name;
		},

		inSlotBegin: function(ad) {},

		inSlotEnd: function(ad) {},

		outOfSlotBegin: function(ad) {},

		outOfSlotEnd: function(ad) {}
	};


	/**
	 * @class SIMAD.Renderer.InstreamRenderer
	 */
	SIMAD.Renderer.InstreamRenderer = SIMAD.Util.extend({}, SIMAD.Renderer.Base, {
		__name: "InstreamRenderer",

		inSlotBegin: function(ad) {
			document.write('<'+ad.getWrapperElementName()+' id="' + SIMAD.Core.getWrapperId(ad) + '">');

			var adServerAdapter = SIMAD.Core.getAdServerAdapterFor(ad);
			if (adServerAdapter) { adServerAdapter.renderAd(ad); }

		},

		inSlotEnd: function(ad) {
			var adServerAdapter = SIMAD.Core.getAdServerAdapterFor(ad);
			if (adServerAdapter){
				document.write(adServerAdapter.styleAd(ad));
			}
			document.write('</'+ad.getWrapperElementName()+'>');

			ad.setWrapper(document.getElementById(SIMAD.Core.getWrapperId(ad)));

			if (ad.getPlaceholder()) {
				var emptyDiv = document.createElement("div");
				ad.getPlaceholder().appendChild(emptyDiv);

				var scripts = ad.getWrapper().getElementsByTagName('script');
				for (var i = 0; i < scripts.length; i++) {
					if (scripts[i].src) { scripts[i].removeAttribute('src'); }
				}

				emptyDiv.parentNode.replaceChild(ad.getWrapper(), emptyDiv);
			}

			ad.triggerEvent('onRendered');
		}
	});



	/**
	 * @class SIMAD.Renderer.PoststreamRenderer
	 */
	SIMAD.Renderer.PoststreamRenderer = SIMAD.Util.extend({}, SIMAD.Renderer.Base, {
		__name: "PoststreamRenderer",

		inSlotBegin: function(ad) {

			document.write('<'+ad.getWrapperElementName()+' id="' + SIMAD.Core.getWrapperId(ad) + '_target"></'+ad.getWrapperElementName()+'>');
		},

		outOfSlotBegin: function(ad) {

			document.write('<'+ad.getWrapperElementName()+' id="' + SIMAD.Core.getWrapperId(ad) + '" style="display: none">');
			var adServerAdapter = SIMAD.Core.getAdServerAdapterFor(ad);
			if (adServerAdapter) { adServerAdapter.renderAd(ad); }
		},

		outOfSlotEnd: function(ad) {
			var adServerAdapter = SIMAD.Core.getAdServerAdapterFor(ad);
			if (adServerAdapter) {
				document.write(adServerAdapter.styleAd(ad));
			}

			document.write('</'+ad.getWrapperElementName()+'>');

			var source_id = SIMAD.Core.getWrapperId(ad);
			var target_id = source_id + "_target";

			if (ad.getFormat() === SIMAD.Format.FULLBANNER && window.SoiAd && SoiAd.isBillboard(ad.getAdServerFormat())) {
			SoiAd.moveAd(ad.getAdServerFormat(), source_id, source_id, "-billboard");
			var container = document.getElementById(source_id + "-billboard");
			if (container) {
				container.style.display = 'block';
			}
			var target = document.getElementById(target_id);
			if (target) {
				target.id = source_id;
				ad.setWrapper(target);
			}
			} else {
				var source = document.getElementById(source_id);
				var target = document.getElementById(target_id);
				if (!target) { // Target fallback
					if (ad.getPlaceholder()) {
						document.write('<'+ad.getWrapperElementName()+' id="' + SIMAD.Core.getWrapperId(ad) + '_target"></'+ad.getWrapperElementName()+'>');
						target = document.getElementById(target_id);
					} else {
						SIMAD.Log.error("No wrapper/target was rendered for " + ad.getId() + " and no placeholder is defined. Dont't know where to render the ad...");
						return;
					}
				}
				if (!source || !target) { return; }

				var scripts = source.getElementsByTagName('script');
				for (var i = 0; i < scripts.length; i++) {
					if (scripts[i].src) { scripts[i].removeAttribute('src'); }
				}

				target.parentNode.replaceChild(source, target);
				if(ad.getWrapperElementName() === "div"){
					source.style.display = "block";
				}else{
					source.style.display = "inline";
				}
				ad.setWrapper(source);

				if (ad.getPlaceholder()) {
					var emptyDiv = document.createElement("div");
					ad.getPlaceholder().appendChild(emptyDiv);

					emptyDiv.parentNode.replaceChild(ad.getWrapper(), emptyDiv);
				}
			}

			ad.triggerEvent('onRendered');
		}
	});


	/**
	 * @class SIMAD.Renderer.OnEventRenderer
	 */
	SIMAD.Renderer.OnEventRenderer = SIMAD.Util.extend({}, SIMAD.Renderer.Base, {
		__name: "OnEventRenderer",

		inSlotBegin: function(ad) {


			document.write('<'+ad.getWrapperElementName()+' id="' + SIMAD.Core.getWrapperId(ad) + '"></'+ad.getWrapperElementName()+'>');
			ad.setWrapper(document.getElementById(SIMAD.Core.getWrapperId(ad)));
		}
	});


	/**
	 * @class SIMAD.Renderer.IFrameRenderer
	 */
	SIMAD.Renderer.IFrameRenderer = SIMAD.Util.extend({}, SIMAD.Renderer.InstreamRenderer, {
		__name: "IFrameRenderer",

		inSlotEnd: function(ad) {


			document.write('</'+ad.getWrapperElementName()+'>')

			ad.setWrapper(parent.document.getElementById(SIMAD.Core.getWrapperId(ad)));

			SIMAD.Core.__completeAd(ad);
		}
	});




	/**
	 * @namespace SIMAD.Reloader
	 */
	if (SIMAD.Reloader === undefined) { SIMAD.Reloader = {}; }


	/**
	 * @class SIMAD.Reloader.Reloader
	 */
	SIMAD.Reloader.ReplacementFrameReloader = {
		__name: "ReplacementFrameReloader",
		__syncVarsUpdated: {},

		getName: function() {
			return this.__name;
		},


		/**
		 * Renders the ad in an iFrame.
		 *
		 * @memberOf SIMAD.Reloader.ReplacementFrameReloader
		 * @public
		 * @param {SIMAD.Ad} ad Ad to write iFrame for.
		 * @returns {SIMAD.Ad} The passed ad
		 */
		reloadAd: function(ad) {
			if (ad) {
				SIMAD.Log.log("Adreload", this.getName() + " gets the ad " + ad.getId() + " to reload", ad);

				ad.triggerEvent('beforeReload');

				if (SIMAD.Core.__reloadAdsRotation.currentIndex === 0) {
					this.__syncVarsUpdated = {};
				}

				var adServerAdapter = SIMAD.Core.getAdServerAdapterFor(ad);
				if (this.__syncVarsUpdated[ad.getAdServer()] !== true) {
					adServerAdapter.resetSyncVars();
				}

				ad.reset();

				var url = this.__getURL(ad);
				var iframe = this.__getIFrame(ad);

				if (ad.getWrapper() === null && ad.getPlaceholder() !== null) {
					var placeholder = ad.getPlaceholder();
					if (placeholder && placeholder.nodeName) {
						var wrapperDiv = document.createElement('div');
						wrapperDiv.id = SIMAD.Core.getWrapperId(ad);
						placeholder.appendChild(wrapperDiv);
						ad.setWrapper(wrapperDiv);
					}
				}

				var wrapper = ad.getWrapper() || ad.getPlaceholder();
				if (iframe && url && wrapper) {
					wrapper.innerHTML = "";
					wrapper.appendChild(iframe);
					if(ad.getWrapperElementName() === "div"){
						wrapper.style.display = "block";
					}else{
						wrapper.style.display = "inline";
					}

					ad.bindEvent('onIFrameAdStarted', '__onIFrameInitCompleted', this.__onIFrameInitCompleted);

					ad.bindEvent('onIFrameAdFinished', '__onIFrameAdRendered', this.__onIFrameAdRendered);

					var iframeWin = this.__getIFrameWindow(iframe);
					try {
						iframeWin.location.replace(url);
					} catch(e) {
						iframe.src = url;
					}
				} else {
					SIMAD.Log.warn("Trying to reload the ad " + ad.getId() + " which is not yet presented in DOM (has neither wrapper nor placeholder)");
					SIMAD.Core.reloadNextAd();
				}
			} else {
				SIMAD.Log.error("A SIMAD.Ad object must be passed to the reloadAd function of the " + this.getName());
			}
			return ad;
		},


		/**
		 * Hides the ad representation in the DOM.
		 *
		 * @memberOf SIMAD.Reloader.ReplacementReloader
		 * @private
		 * @param {SIMAD.Ad} ad Ad to clean
		 */
		clean: function(ad) {
			try {
				ad.getWrapper().innerHTML = '';
				if (ad.getFormat() === SIMAD.Format.FULLBANNER) {
					SIMAD.Core.clearBillboard(ad);
				}
			} catch(e) {}
		},

		/**
		 * This function will be called from slave iFrame after the init block is done, but ad rendering is not yet started.
		 * Syncs adserver vars from the master to the slave document for the first ad of each adserver.
		 *
		 * @memberOf SIMAD.Reloader.ReplacementFrameReloader
		 * @private
		 * @param {Object} event Event object of the core
		 */
		__onIFrameInitCompleted: function(event) {
			var ad = event.calledFromAd;
			if (ad) {
				ad.unbindEvent('onIFrameAdStarted', '__onIFrameInitCompleted');

				var adServerAdapter = SIMAD.Core.getAdServerAdapterFor(ad);
				if (adServerAdapter && SIMAD.Reloader.ReplacementFrameReloader.__syncVarsUpdated[ad.getAdServer()] === true) {
					var iFrameWin = SIMAD.Reloader.ReplacementFrameReloader.__getIFrameWindow(SIMAD.Reloader.ReplacementFrameReloader.__getIFrame(ad));
					if (iFrameWin) {
						adServerAdapter.syncVars(window, iFrameWin);
					}
				}

			}
		},

		/**
		 * This function will be called from slave iFrame after the ad rendering is done.
		 * Syncs the adserver global vars from the iframe to the master window, finishes the iframe ad and continues the ad reload rotation.
		 *
		 * @memberOf SIMAD.Reloader.ReplacementFrameReloader
		 * @private
		 * @param {Object} event Event object of the core
		 */
		__onIFrameAdRendered: function(event) {
			var ad = event.calledFromAd;
			SIMAD.Log.log("AdReload", "__onIFrameAdRendered() called for " + ad.getId());
			if (ad) {
				ad.unbindEvent('onIFrameAdFinished', '__onIFrameAdRendered');

				var adServerAdapter = SIMAD.Core.getAdServerAdapterFor(ad);
				var iFrameWin = SIMAD.Reloader.ReplacementFrameReloader.__getIFrameWindow(SIMAD.Reloader.ReplacementFrameReloader.__getIFrame(ad));
				if (adServerAdapter && iFrameWin) {
					adServerAdapter.syncVars(iFrameWin, window);
					SIMAD.Reloader.ReplacementFrameReloader.__syncVarsUpdated[ad.getAdServer()] = true;
				}

				SIMAD.Reloader.ReplacementFrameReloader.__resizeIFrame(ad);


				ad.setReloaded(true);

				ad.triggerEvent("afterReload");

				SIMAD.Core.reloadNextAd();
			}
		},


		/**
		 * Returns the URL for the iframe ad.
		 *
		 * @memberOf SIMAD.Reloader.ReplacementFrameReloader
		 * @private
		 * @param {SIMAD.Ad} ad The ad the URL is generated for.
		 */
		__getURL: function(ad) {
			return SIMAD.Core.$s.staticIFrameLocation + "?ad_id=" + ad.getId();
		},


		/**
		 * Returns the iFrame DOM element for the ad. If it doesn't exists, it will create one.
		 *
		 * @memberOf SIMAD.Reloader.ReplacementFrameReloader
		 * @private
		 * @param {SIMAD.Ad} ad The ad the iFrame is for.
		 * @returns {DOM} iFrame DOM element
		 */
		__getIFrame: function(ad) {
			var iframe = document.getElementById(this.__getIFrameId(ad));
			if (!iframe) {
				iframe = document.createElement('iframe');
				iframe.id = this.__getIFrameId(ad);
				iframe.style.width = iframe.style.height = "0px";
				iframe.width = iframe.height = 0;
				iframe.frameBorder = iframe.border = 0;
				iframe.scrolling = "no";
				iframe.src = "about:blank";
			}
			return iframe;
		},


		/**
		 * Returns the default iFrame ID for the ad.
		 *
		 * @memberOf SIMAD.Reloader.ReplacementFrameReloader
		 * @private
		 * @param {SIMAD.Ad} ad The ad the iframe is for.
		 * @returns {String} ID of the iFrame
		 */
		__getIFrameId: function(ad) {
			return "SIMAD_iframe_" + ad.getId();
		},


		/**
		 * Returns the window pointer of the passed iframe (Browser dependence)
		 *
		 * @memberOf SIMAD.Reloader.ReplacementFrameReloader
		 * @private
		 * @param {DOM} iframe The iFrame the window is for.
		 * @returns {DOM} Window pointer
		 */
		__getIFrameWindow: function(iframe) {
			var iframeWin;
			if (iframe) {
				try {
					iframeWin = iframe.contentWindow;
					if (!iframeWin) {
						try {
							iframeWin = iframe.contentDocument.defaultView;
						} catch(e) {
							try { iframeWin = window.frames[iframe.id]; } catch(exept) {}
						}
					}
				} catch(e) {}
			}
			return iframeWin;
		},


		/**
		 * Resize the passed ad iframe to the passed size.
		 *
		 * @memberOf SIMAD.Relaoder.ReplacementFrameReloader
		 * @private
		 * @param {SIMAD.Ad} ad The ad the iframe is of.
		 * @param {Array} toSize Array in format [width, height]
		 */
		__resizeIFrame: function(ad, toSize) {
			var iframe = this.__getIFrame(ad);
			var dimensions = toSize || ad.getDimensions();
			if (iframe && dimensions) {
				SIMAD.Log.log("Reloader", "Resizing the ad " + ad.getId() + " to", dimensions);
				if (dimensions[0] !== undefined && dimensions[1] !== undefined) {
					iframe.style.width = dimensions[0] + "px";
					iframe.style.height = dimensions[1] + "px";
				}
			}
		}

	};
}
if (typeof SIMAD !== 'undefined') {

	/**
	 * @class Represent an ad in the SIMAD core
	 * @param {Object} params JSON object with all the settings for new ad object.
	 */
	SIMAD.Ad = function(params) {
		this.__init(params);
	};

	/**
	 * @constructor
	 */
	SIMAD.Ad.prototype = {
		/**
		 * ID of the SIMAD.Ad object
		 *
		 * @memberOf SIMAD.Ad
		 * @private
		 * @type String
		 */
		__id: undefined,


		/**
		 * Format of the SIMAD.Ad object
		 *
		 * @memberOf SIMAD.Ad
		 * @private
		 * @type String
		 */
		__format: undefined,


		/**
		 * ID of the SIMAD.Ad object
		 *
		 * @memberOf SIMAD.Ad
		 * @private
		 * @type String
		 */
		__adServerFormat: undefined,


		/**
		 * Loading property of the SIMAD.Ad object
		 *
		 * @memberOf SIMAD.Ad
		 * @private
		 * @type String
		 */
		__loading: SIMAD.Loading.POSTSTREAM,


		/**
		 * onLoadCallback function for the SIMAD.Ad object
		 *
		 * @memberOf SIMAD.Ad
		 * @private
		 * @type Function
		 * @default null
		 */
		__onLoadCallback: null,


		/**
		 * onRenderCallback function for the SIMAD.Ad object
		 *
		 * @memberOf SIMAD.Ad
		 * @private
		 * @type Function
		 * @default null
		 */
		__onRenderCallback: null,


		/**
		 * adServer property of the SIMAD.Ad object
		 *
		 * @memberOf SIMAD.Ad
		 * @private
		 * @type String
		 */
		__adServer: undefined,


		/**
		 * placeholder object o of the SIMAD.Ad object
		 *
		 * @memberOf SIMAD.Ad
		 * @private
		 * @type DOM
		 * @default null
		 */
		__placeholder: null,


		/**
		 * wrapper object o of the SIMAD.Ad object
		 *
		 * @memberOf SIMAD.Ad
		 * @private
		 * @type DOM
		 * @default null
		 */
		__wrapper: null,


		/**
		 * renderStatus of the SIMAD.Ad object. Needed to track initial rendering of the ad.
		 * Will be increased on each doAd call. Protect rendering of doAd postream with no instream rendering.
		 *
		 * @memberOf SIMAD.Ad
		 * @private
		 * @type Number
		 * @default 0
		 */
		__renderStatus: 0,


		/**
		 * Actice property of the SIMAD.Ad object. Deactivated ads will not be rendered initial.
		 *
		 * @memberOf SIMAD.Ad
		 * @private
		 * @type Boolean
		 * @default true
		 */
		__active: true,


		/**
		 * Visible property of the SIMAD.Ad object. Ad will be set to visible after it was rendered on the page.
		 * This property also will be modified by {@link SIMAD.Ad#hide hide} and {@link SIMAD.Ad show} functions.
		 *
		 * @memberOf SIMAD.Ad
		 * @private
		 * @type boolean
		 * @default false
		 */
		__visible: false,


		/**
		 * Dimensions of the Ad. This information will be delivered by the adserver.
		 * Dimensions in format [width, height]. Some ad formats might have more values (i.e. wallpaper).
		 *
		 * @memberOf SIMAD.Ad
		 * @private
		 * @type Array
		 * @default [0, 0]
		 */
		__dimensions: [0, 0],


		/**
		 * Delivered property of the SIMAD.Ad. This information will be set be adserver.
		 *
		 * @memberOf SIMAD.Ad
		 * @private
		 * @type Boolean
		 * @default false
		 */
		__delivered: false,


		/**
		 * Reloaded property of the SIMAD.Ad. Will be set to true after the first Adreload.
		 *
		 * @memberOf SIMAD.Ad
		 * @private
		 * @type Boolean
		 * @default false
		 */
		__reloaded: false,

		/**
		 * Ad server specific parameters. Allows any data in JSON format.
		 *
		 * @memberOf SIMAD.Ad
		 * @private
		 * @type Object
		 * @default undefined
		 */
		__adServerSpecific: undefined,


		/**
		 * Init the SIAMD.Ad object.
		 *
		 * @memberOf SIMAD.Ad
		 * @private
		 * @param {Object} params JSON with the init setting for the Ad
		 * @returns {SIMAD.Ad} Ad object itself
		 */
		__init: function(params) {
			SIMAD.Log.log("Ads", "new Ad with", params);
			if (params) {
				params = SIMAD.Util.extend({
					"loading": SIMAD.Loading.POSTSTREAM,
					"active": true
				}, params);

				if (params.id && params.id !== "") {
					this.__id = params.id;
				} else {
					SIMAD.Log.error("The parameter 'id' must be defined for a new SIMAD.Ad creation.");
					return;
				}

				this.__eventListener = {
					"beforeReload": [],
					"afterReload": [],
					"onRendered": [],
					"onLoad": [],
					"onIFrameAdStarted": [],
					"onIFrameAdFinished": []
				};

				if (params.format) {
					this.setFormat(params.format);
					if (!this.getFormat()) { SIMAD.Log.error("The format " + params.format + " does not exists."); }

				} else {
					SIMAD.Log.error("The parameter 'format' must be defined for a new SIMAD.Ad creation.");
					return;
				}

				if (params.loading) { this.setLoading(params.loading); }
				if (params.onLoadCallback) { this.setOnLoadCallback(params.onLoadCallback); }
				if (params.onRenderCallback) { this.setOnRenderCallback(params.onRenderCallback);}
				if (params.placeholder) { this.setPlaceholder(params.placeholder); }
				if (params.active) {
					this.activate();
				} else {
					this.deactivate();
				}
				this.__adServer = params.adServer || SIMAD.Core.getConfig().adServers[0] || undefined;
				this.__adServerSpecific = params.adServerSpecific || undefined;
			} else {
				SIMAD.Log.error("Trying to create a new SIMAD.Ad object without passing the arguments");
				return;
			}
			return this;
		},


		/**
		 * Add a function to the ad event
		 *
		 * @memberOf SIMAD.Ad
		 * @public
		 * @param {String} eventName Name of the event the function should binded with.
		 * @param {String} eventIdentifier ID of the binding. Needed for unbinding.
		 * @param {Function|String} eventFunction Function (name) to bind.
		 */
		bindEvent: function(eventName, eventIdentifier, eventFunction) {
			SIMAD.Log.log("Ad Event", "bindEvent " + eventName + " with Identifier: " + eventIdentifier + " to Ad: "+ this.__id );
			if (typeof(this.__eventListener[eventName]) !== "undefined") {
				if (typeof(eventFunction) === "string" && typeof(window[eventFunction]) === "function") {

					eventFunction = window[eventFunction];
				}
				if (typeof(eventFunction) === "function" && typeof(eventIdentifier) === "string"){
					var newEvent = true;
					for (var i = 0; i < this.__eventListener[eventName].length; i++) {
						if (this.__eventListener[eventName][i].eventIdentifier === eventIdentifier) {
							newEvent = false;
						}
					}
					if (newEvent){
						this.__eventListener[eventName].push({
							"eventIdentifier":eventIdentifier,
							"eventFunction":eventFunction,
							"calledFromAd": this
						});
					}
				} else {
					SIMAD.Log.warn("bindEvent: the function: " + eventFunction + " with the Identifier: " + eventIdentifier + "  to Ad: " + this.__id + " is not possible, check datatypes");
				}
			} else {
				SIMAD.Log.warn("bindEvent: the Event: " + eventName + "  from Ad: " + this.__id + " is not supported");
			}
		},

		/**
		 * Triggers an event.
		 *
		 * @memberOf SIMAD.Ad
		 * @public
		 * @param {String} eventName Name of the event to trigger.
		 */
		triggerEvent: function(eventName) {
			SIMAD.Log.log("Ad Event","triggerEvent: " +eventName + " for Ad " + this.__id);
			if (typeof this.__eventListener[eventName] !== "undefined") {
				var eventObjs = this.__eventListener[eventName].slice();
				for (var i = 0; i < eventObjs.length; i++) {
					if (typeof(eventObjs[i].eventFunction) === 'function') {
						eventObjs[i].eventFunction(eventObjs[i]);
					}
				}
			} else {
				SIMAD.Log.warn("triggerEvent: the Event " + eventName + "  on Ad: " + this.__id + " is not supported");
			}
		},


		/**
		 * Unbind a function from the event (if the binding exists)
		 *
		 * @memberOf SIMAD.Ad
		 * @private
		 * @param {String} eventName Name of the event.
		 * @param {String} eventIdentifier ID of the event binding
		 */
		unbindEvent: function(eventName,eventIdentifier){
			SIMAD.Log.log("Ad Event","unbindEvent: " + eventName +" with Identifier: "+eventIdentifier +" from Ad: "+ this.__id );
			if(typeof(this.__eventListener[eventName]) !=="undefined"  && typeof eventIdentifier === "string"){
				var eventIndex = -1;
				for(var i=0; i<this.__eventListener[eventName].length; i++) {
					if (this.__eventListener[eventName][i].eventIdentifier === eventIdentifier){
						 eventIndex = i;
					}
				}
				if(eventIndex >=0){
					this.__eventListener[eventName].splice(eventIndex,1);
				}else{
					SIMAD.Log.info("Ad Event","unbindEvent: Event: " +eventName+ " with the eventIdentifier:" + eventIdentifier +" dosen't exist and cannot be unbinded");
				}
			}else{
					SIMAD.Log.warn("unbindEvent: unbinding the Event "+eventName+" with the Identifier: " +eventIdentifier +" from Ad: "+ this.__id +" is not possible, check datatypes");
			}
		},


		/**
		 * Getter for the ID of the ad.
		 *
		 * @memberOf SIMAD.Ad
		 * @public
		 * @returns {String} ID of the ad.
		 */
		getId: function() {
			return this.__id;
		},


		/**
		 * Getter for the loading property of the ad. The value of the loading is constant defined in {@link SIMAD.Loading}
		 *
		 * @memberOf SIMAD.Ad
		 * @public
		 * @returns {String} Loading property of the ad.
		 */
		getLoading: function() {
			return this.__loading;
		},


		/**
		 * Setter for the loading property of the ad. The value of the loading is constant defined in {@link SIMAD.Loading}
		 *
		 * @memberOf SIMAD.Ad
		 * @public
		 * @param {String} loading Loading property of the SIAMAD.Ad object
		 * @returns {SIMAD.Ad} The Ad object itself
		 */
		setLoading: function(loading) {
			if (this.__loading !== loading) {
				var loadingExists = false;
				for (var i in SIMAD.Loading) {
					if (SIMAD.Loading[i] === loading) { loadingExists = true; }
				}
				if (loadingExists) { this.__loading = loading; }
			}
			return this;
		},


		/**
		 * Getter for the format property of the SIMAD.Ad object. The value of the format is constant defined in {@link SIMAD.Format}
		 *
		 * @memberOf SIMAD.Ad
		 * @public
		 * @returns {String} Fortam property of the SIMAD.Ad
		 */
		getFormat: function() {
			return this.__format;
		},


		/**
		 * Setter for the format property of the SIMAD.Ad object. The value of the format is constant defined in {@link SIMAD.Format}
		 *
		 * @memberOf SIMAD.Ad
		 * @public
		 * @param {String} format Format property of the SIMAD.Ad object
		 * @returns {SIMAD.Ad} The Ad object itself
		 */
		setFormat: function(format) {
			if (this.__format !== format) {
				var formatExists = false;
				for (var i in SIMAD.Format) {
					if (SIMAD.Format[i] === format) { formatExists = true; }
				}
				if (formatExists) { this.__format = format; }
			}
			return this;
		},


		/**
		 * Returns the adserver specific format value (mapped) for the ad object, if defined in adserver adapter.
		 *
		 * @memberOf SIMAD.Ad
		 * @public
		 * @returns {String} Value of adserver mapped format property of the ad object
		 */
		getAdServerFormat: function() {
			if (!this.__adServerFormat) {
				var adAdserver = SIMAD.Core.getAdServerAdapterFor(this);
				if (adAdserver) {
					this.__adServerFormat = adAdserver.getMappedAdFormat(this.getFormat());
				}
			}
			return this.__adServerFormat;
		},


		/**
		 * Getter for the onLoadCallback function of the ad object.
		 *
		 * @memberOf SIMAD.Ad
		 * @public
		 * @returns {Function | null} onLoadCallback function of the ad, null if the function not defined
		 */
		getOnLoadCallback: function() {
			return this.__onLoadCallback;
		},


		/**
		 * Setter for the onLoadCallback function of the ad object.
		 *
		 * @memberOf SIMAD.Ad
		 * @public
		 * @param {Function | String} callback function or function name which must be called on load
		 * @returns {SIMAD.Ad} The Ad object itself
		 */
		setOnLoadCallback: function(callback) {
			if (callback === null) {
				this.__onLoadCallback = callback;
			} else if (typeof(callback) === 'string' && typeof(window[callback]) === 'function') {
				this.__onLoadCallback =	window[callback];
			} else if (typeof(callback) === "function") {
				this.__onLoadCallback = callback;
			}
			return this;
		},


		/**
		 * Getter for the onRenderCallback function of the ad object.
		 *
		 * @memberOf SIMAD.Ad
		 * @public
		 * @returns {Function | null} onRenderCallback function of the ad, null if the function not defined
		 */
		getOnRenderCallback: function() {
			return this.__onRenderCallback;
		},


		/**
		 * Setter for the onRenderCallback function of the ad object.
		 *
		 * @memberOf SIMAD.Ad
		 * @public
		 * @param {Function | String} callback function or function name which must be called on rendering
		 * @returns {SIMAD.Ad} The Ad object itself
		 */
		setOnRenderCallback: function(callback) {
			if (callback === null) {
				this.__onRenderCallback = callback;
			} else if (typeof(callback) === 'string' && typeof(window[callback]) === 'function') {
				this.__onRenderCallback =	window[callback];
			} else if (typeof(callback) === "function") {
				this.__onRenderCallback = callback;
			}
			return this;
		},


		/**
		 * Getter for the adServer property of the ad object.
		 *
		 * @memberOf SIMAD.Ad
		 * @public
		 * @returns {String} adServer property of the ad object
		 */
		getAdServer: function() {
			return this.__adServer;
		},


		/**
		 * Getter for the renderStatus property of the ad object.
		 * Render status is a number 0 to 3. On each doAd() call the render status will be increased to track the doAd() call order.
		 *
		 * @memberOf SIMAD.Ad
		 * @private
		 * @returns {Number} Render status of the ad object.
		 */
		getRenderStatus: function() {
			return this.__renderStatus;
		},


		/**
		 * Increase the current render status of the ad to 1
		 *
		 * @memberOf SIMAD.Ad
		 * @private
		 * @returns {SIMAD.Ad} Ad object itself
		 */
		incRenderStatus: function() {
			this.__renderStatus++;
			return this;
		},


		/**
		* Returns the placeholder DOM element of the ad if defined. Otherwise returns null.
		*
		* @memberOf SIMAD.Ad
		* @public
		* @returns {DOM | null} Placeholder DOM element or null
		*/
		getPlaceholder: function() {
			var placeholder;
			if (typeof(this.__placeholder) === "object") {
				placeholder = this.__placeholder;
			} else if (typeof(this.__placeholder) === "string") {
				var placeholderObj = document.getElementById(this.__placeholder);
				if (placeholderObj) {
					placeholder = placeholderObj;
				} else {
					SIMAD.Log.warn("The placeholder with id " + this.__placeholder + " for the ad " + this.getId() + " is not found.");
				}
			}
			return placeholder;
		},


		/**
		* Setter for the placeholder property of the ad object.
		*
		* @memberOf SIMAD.Ad
		* @public
		* @param {DOM} placeholder Placeholder DOM element
		* @returns {SIMAD.Ad} Ad object itself
		*/
		setPlaceholder: function(placeholder) {
			if (placeholder !== undefined) {
				this.__placeholder = placeholder;
			}
			return this;
		},


		/**
		* Returns the wrapper DOM element of the ad if exists. Otherwise returns null.
		*
		* @memberOf SIMAD.Ad
		* @public
		* @returns {DOM | null} Wrapper DOM element
		*/
		getWrapper: function() {
			return this.__wrapper;
		},


		/**
		* Setter for wrapper property of the ad object.
		*
		* @memberOf SIMAD.Ad
		* @public
		* @param {DOM} wrapper Wrapper DOM element
		* @returns {SIMAD.Ad} Ad object itself
		*/
		setWrapper: function(wrapper) {
			if (typeof(wrapper) === "object") {
				this.__wrapper = wrapper;
			}
			return this;
		},
		/**
		* return the warper html element name which should be used for this ad.
		* the popup ad requires a div element
		*/
		getWrapperElementName: function(){
			if(this.getFormat() === SIMAD.Format.POPUP){
				return "div";
			}else {
				return "span";
			}
		},


		/**
		 * Sets the ad to active.
		 *
		 * @see SIMAD.Ad#deactivate
		 * @memberOf SIMAD.Ad
		 * @public
		 * @returns {SIMAD.Ad} Ad object itself
		 */
		activate: function() {
			this.__active = true;
			return this;
		},


		/**
		 * Sets the ad to deactive.
		 * Deactive ads will not modified or reloaded.
		 *
		 * @memberOf SIMAD.Ad
		 * @public
		 * @returns {SIMAD.Ad} Ad object itself
		 */
		deactivate: function() {
			this.__active = false;
			return this;
		},


		/**
		 * Returns true if the ad is active, false if not
		 *
		 * @memberOf SIMAD.Ad
		 * @public
		 * @returns {Boolean} Value of the active property of the ad object.
		 */
		isActive: function() {
			return this.__active;
		},


		/**
		* Hides the ad in the DOM if it's presented where
		*
		* @memberOf SIMAD.Ad
		* @public
		* @returns {SIMAD.Ad} Ad object itself
		*/
		hide: function() {
			SIMAD.Core.hideAd(this);
			return this;
		},


		/**
		* Shows (turns it visible) the ad in the DOM if it's presented where
		*
		* @memberOf SIMAD.Ad
		* @public
		* @returns {SIMAD.Ad} Ad object itself
		*/
		show: function() {
			SIMAD.Core.showAd(this);
			return this;
		},


		/**
		* Sets the visible property of the ad object.
		*
		* @memberOf SIMAD.Ad
		* @private
		* @param {Boolean} param True for visible, false for unvisible
		* @returns {SIMAD.Ad} Ad object itself
		*/
		setVisibility: function(param) {
			if (typeof(param) !== "undefined") { this.__visible = param; }
			return this;
		},


		/**
		* Getter for the visible property of the ad object
		*
		* @memberOf SIMAD.Ad
		* @public
		* @returns {Boolean} True if the ad is visible
 		*/
		isVisible: function() {
			return this.__visible;
		},


		/**
		* Reset all status parameters to the defaults (called before the ad will reloaded)
		*
		* @memberOf SIMAD.Ad
		* @private
		* @returns {SIMAD.Ad} Ad object itself
		*/
		reset: function() {
			this.__renderStatus = 0;
			this.__visible = false;
			this.__dimensions = [0, 0];
			this.__delivered = false;
			this.__reloaded = false;

			return this;
		},


		/**
		 * Setter for the dimensions property of the ad object.
		 *
		 * @memberOf SIMAD.Ad
		 * @private
		 * @param {Array} dimensions Array in format [width, height]
		 * @returns {SIMAD.Ad} Ad object itself
		 */
		setDimensions: function(dimensions) {
			if (dimensions && typeof(dimensions) !== 'string' && dimensions.length > 1) {
				this.__dimensions = dimensions;
			}
			return this;
		},


		/**
		 * Getter for the dimensions property of the ad object.
		 * Dimention array has 2 elements (width and height). For some special ad format it might have more elements (i.e. wallpeper)
		 *
		 * @memberOf SIMAD.Ad
		 * @public
		 * @returns {type} Dimentions array in format [width, height, ...]
		 */
		getDimensions: function() {
			return this.__dimensions;
		},


		/**
		 * Setter for the delivered property of the ad object.
		 *
		 * @memberOf SIMAD.Ad
		 * @private
		 * @param {type} delivered Value of the delivered property
		 */
		setDelivered: function(delivered) {
			this.__delivered = delivered;
			return this;
		},


		/**
		 * Returns true if the ad is delivered, false if not
		 *
		 * @memberOf SIMAD.Ad
		 * @public
		 * @returns {Boolean} Delivered or not
		 */
		isDelivered: function() {
			return this.__delivered;
		},


		/**
		* Removes the ad representation from the DOM (if exists)
		* Facade for the {@link SIMAD.Core#clearAd SIMAD.Core.clearAd()}
		*
		* @memberOf SIMAD.Ad
		* @public
		* @returns {SIMAD.Ad} Ad object itself
		*/
		clear: function() {
			SIMAD.Core.clearAd(this);
			return this;
		},


		/**
		 * Removes the ad completely from the DOM and DataStore.
		 * Facade for the {@link SIMAD.Core#deleteAd SIMAD.Core.deleteAd()}
		 *
		 * @memberOf SIMAD.Ad
		 * @public
		 * @returns {SIMAD.Ad} Ad object itself
		 */
		del: function(doNotClear) {
			SIMAD.Core.deleteAd(this, doNotClear);
			return this;
		},


		/**
		* Getter for the __reloaded property. Reloaded property identificates if the was reloaded once.
		*
		* @memberOf SIMAD.Ad
		* @private
		* @returns {Boolean} Ad was reloaded or not
		*/
		isReloaded: function() {
			return this.__reloaded;
		},


		/**
		* Setter for the __reloaded property of the ad object.
		*
		* @private
		* @param {boolean} val True for reloaded, false for not
		* @returns {SIMAD.Ad} ad Ad itself
		*/
		setReloaded: function(val) {
			if (typeof(val) === 'boolean') { this.__reloaded = val; }
			return this;
		},


		/**
		* Sugar interface for {@link SIMAD.Core#loadAd SIMAD.Core.loadAd()}
		*
		* @memberOf SIMAD.Ad
		* @public
		* @returns {SIMAD.Ad} Ad object itself
		*/
		load: function() {
			SIMAD.Core.loadAd(this);
			return this;
		},


		/**
		* Sugar interface for {@link SIMAD.Core#reloadAds SIMAD.Core.reloadAds()} from the ad object (used for the gallery zoom Usecase)
		*
		* @memberOf SIMAD.Ad
		* @public
		* @returns {SIMAD.Ad} Ad object itself
		*/
		reload: function() {
			SIMAD.reloadAds();
			return this;
		},


		/**
		* Compatibility function, which is no more supported. Exists only to avoid JavaScript error when it's called
		*
		* @memberOf SIMAD.Ad
		* @private
		*/
		swap: function() {
			return;
		},


		/**
		 * Returns the value of adServerSpecific property
		 *
		 * @memberOf SIMAD.Ad
		 * @public
		 * @returns {Object || undefined} Value of the adServerSpecific property or undefined if it's not set.
		 */
		getAdServerSpecific: function() {
			return this.__adServerSpecific;
		},


		/**
		 * Sets the value of the adServerSpecific property. Replace the existed value.
		 *
		 * @memberOf SIMAD.Ad
		 * @public
		 * @param {Object} param JSON object with the parameters
		 * @returns {SIMAD.Ad} SIMAD itselfs
		 */
		setAdServerSpecific: function(param) {
			if (param) {
				this.__adServerSpecific = param;
			}
			return this;
		},


		/**
		 * Sets the value of the adServerSpecific property. Extends the existed value.
		 *
		 * @memberOf SIMAD.Ad
		 * @public
		 * @param {Object} param JSON object with the parameters
		 * @returns {SIMAD.Ad} SIMAD itselfs
		 */
		addAdServerSpecific: function(param) {
			if (param) {
				this.__adServerSpecific = SIMAD.Util.extend(true, this.__adServerSpecific, param);
			}
			return this;
		}

	};

}
/**
 * @fileoverview SIMAD.Log implements logging to with diffrent logging targets appendes
 *
 * @author Benedikt Weiner
 *
 * <code>
var o= { "data":"bal", "time": new Date(), "number": 212, "object": {"bal":"bla"}};
SIMAD.Log.log("prefix","log message", o);
SIMAD.Log.info("prefix","info message",  o);
SIMAD.Log.warn("info message",  o);
SIMAD.Log.error("info message",  o);
 * </code>
 *  prefix: "input" | "output" | "internal" | "debug" |
 */



if (typeof SIMAD === 'undefined') {
	SIMAD = {};
}
/**
 * @namespace SIMAD.Log combines all Logging releated functions
 * @class SIMAD.Log
 */
SIMAD.Log = {
	__loggers: [],
	__startTime: new Date(),
	__log: [],

	 /**
     * gets the Array of LogItems
     * @return {Array} of LogItems <code> logItem ={
				"level": level,
				"message": message,
				"time": __timeSinceStart / 1000,
				"prefix": __prefix,
				"object": object
			};</code>
     */
	getLogList: function(){
		return this.__log;
	},

	register: function(logger){
		SIMAD.Log.__loggers.push(logger);
	},

	 /**
     * wirtes as log message with loglevel = log
     * @param {String} message The log message.
     * @param {String} prefix The logging Namespace / Prefix of the Logmessage
     * @param {Object} [object] An JS Object which gets logged
     * @return -
     */
	log: function(prefix, message , object){
		this.__doLog("log",prefix, message , object)
	},

	/**
    * wirtes as log message with loglevel = info
    * @param {String} message The log message.
    * @param {String} [prefix] The logging Namespace / Prefix of the Logmessage
    * @param {Object} [object] An JS Object which gets logged
    * @return -
    */
    info: function(prefix, message , object){
		this.__doLog("info", prefix, message , object)
	},
	/**
    * wirtes as log message with loglevel = warn
    * @param {String} message The log message.
    * @param {String} [prefix] The logging Namespace / Prefix of the Logmessage
    * @param {Object} [object] An JS Object which gets logged
    * @return -
    */
	warn: function(message , object){
		this.__doLog("warn", "warn", message , object)
	},
	/**
    * wirtes as log message with loglevel = error
    * @param {String} message The log message.
    * @param {String} [prefix] The logging Namespace / Prefix of the Logmessage
    * @param {Object} [object] An JS Object which gets logged
    * @return -
    */
	error: function(message , object){
		this.__doLog("error", "error", message , object)
	},

	/**
	* @private
    *  __doLog function build up a internal logger array and dispatches the log to registered logger
    * @param {String} level The log level of the message
    * @param {String} message The log message.
    * @param {String} [prefix] The logging Namespace / Prefix of the Logmessage
    * @param {Object} [object] An JS Object which gets logged
    * @return -
    */
	__doLog: function(level, prefix, message , object){
		var currentSession = SIMAD.Core.getCurrentSession();
		if(currentSession !== null &&  typeof currentSession !== "undefined" && currentSession.debug.all){ //don't log if debug.all === false
			var notInIframe = true;
			if(typeof SIMAD.Core === "object"){
				notInIframe =! SIMAD.Core.inIFrame;
			}else {
				notInIframe = (window === parent)
			}
			if (notInIframe){
				if (!message && message !== "") {
					SIMAD.Log.warn("missuse","the Functoin SIMAD.Log."+level+"() muss be used with tow parameter, ..(prefix,message)")
				}
				var __now = new Date();
				var __timeSinceStart = __now.getTime() - this.__startTime.getTime();
				if (!level) {
					level = "log";
				}
				var __logItem ={
						"level": level,
						"message": message,
						"time": (__timeSinceStart / 1000).toFixed(3),
						"prefix": prefix,
						"object": object
					};
				this.__log.push(__logItem);

				for (var index = 0; index < this.__loggers.length; index++) {
					this.__loggers[index].log(__logItem);
				}

			}else{
				parent.SIMAD.Log.__doLog(level,"         IFrame: "+ prefix, message , object);
			}
		}

	},
	getUsedPrefixes: function(){
		var prefixes = [];
		for( var i=0 ; i < this.__log.length ; i++){
			if(!SIMAD.Util.inArray(prefixes,this.__log[i].prefix)){
				prefixes.push(this.__log[i].prefix);
			}
		}
		return prefixes;

	},

	getUsedLogLevels: function(){
		var loglevels = [];
		for( var i=0 ; i < this.__log.length ; i++){
			if(!SIMAD.Util.inArray(loglevels,this.__log[i].level)){
				loglevels.push(this.__log[i].level);
			}
		}
		return loglevels;

	},



	getLastError: function() {
		var errors = SIMAD.Util.filter(this.__log, function(log) { return log.level === "error" });
		if (errors.length > 0) { return errors[errors.length - 1]; }
		return undefined;
	},


	clear: function() {
		this.__log = [];
	},



	 /**
	 * @namespace SIMAD.Log.ConsoleLogger Logges into JS console if it exists (FireBug)
	 * @class SIMAD.Log
	 */
	ConsoleLogger: {
		log: function(logItem){
			if (window.console) {
				var message =logItem.time +": " + "SIMAD: ";

				switch (logItem.level) {
					default:
					case "log":
						console.log(message + logItem.prefix + ": " + logItem.message, logItem.object ? logItem.object : "");
						break;
					case "info":
						console.info(message + logItem.message, logItem.object ? logItem.object :"");
						break;
					case "warn":
						console.warn(message + logItem.message, logItem.object ? logItem.object :"");

						break;
					case "error":
						console.error(message + logItem.message, logItem.object ? logItem.object :"");
						break;
				}
			}
		}
	},


	 /**
	 * @namespace SIMAD.Log.OperaLogger Logges into opera logger
	 * @class SIMAD.Log
	 */
	OperaLogger: {
		log: function(logItem){
			if ("object" === typeof(window.opera)) {
				if ("function" === typeof(window.opera.postError)) {
					var message = logItem.time + ": " +"SIAMD: " + logItem.prefix + ": " + logItem. message +  (logItem.object ? ": "+SIMAD.Util.toJSON(logItem.object) : "");

					window.opera.postError(logItem.level +"| " +message);
				}
			}
		}
	}


}
SIMAD.Log.register(SIMAD.Log.ConsoleLogger);
SIMAD.Log.register(SIMAD.Log.OperaLogger);

/**
* @namespace SIMAD.AdServerAdapter
* @class SIMAD.AdServerAdapter.Base
*/

if (typeof SIMAD !== 'undefined') {
	if (typeof SIMAD.AdServerAdapter === 'undefined'){ SIMAD.AdServerAdapter = {};}
	SIMAD.AdServerAdapter.Base = {
		/**
		 * Name of the adserver adapter
		 *
		 * @memberOf SIMAD.AdServerAdapter.Base
		 * @private
		 * @type String
		 */
		__name: "Base",


		/**
		 * Identificates if initialization is already started. Needed to catch the first init call.
		 *
		 * @memberOf SIMAD.AdServerAdapter.Base
		 * @private
		 * @type Boolean
		 */
		__initStarted: false,


		/**
		 * Stores calculated initialization mode. Poststream or instream
		 *
		 * @memberOf SIMAD.AdServerAdapter.Base
		 * @private
		 * @type String
		 */
		__initMode: SIMAD.Loading.POSTSTREAM,


		/**
		 * Identificates if the instream init block is completed.
		 *
		 * @memberOf SIMAD.AdServerAdapter.Base
		 * @private
		 * @type Boolean
		 */
		__initInstreamCompleted: false,


		/**
		 * Internal counter of init calls
		 *
		 * @memberOf SIMAD.AdServerAdapter.Base
		 * @private
		 * @type Number
		 */
		__initCounter: 0,


		/**
		 * Settings object for the adserver adapter.
		 * Following setting are possible: initFunctions, MapAdserverBaseUrl, VideoFormat
		 *
		 * @memberOf SIMAD.AdServerAdapter.Base
		 * @private
		 * @type Object
		 * @default {}
		 */
		settings: {},


		/**
		 * Sets the pointer to DataStore and current session of the core.
		 *
		 * @memberOf SIMAD.AdServerAdapter.Base
		 * @public
		 * @returns {SIMAD.AdServerAdapter.Base} Adserver adapter itself
		 */
		config: function() {
			this.data = SIMAD.Core.data;
			this.$s = SIMAD.Core.$s;
			return this;
		},


		/**
		 * Calculate initialization mode and dispatches the init calls to the corresponding function definded in the settings.initFunctions
		 * This function will be called several times per page load. The calls will be tracked in the __initCounter variable.
		 *
		 * @memberOf SIMAD.AdServerAdapter.Base
		 * @public
		 * @returns {SIMAD.AdServerAdapter.Base} Adserver adapter itself
		 */
		init: function(state) {

			if (!this.__initStarted) {
				if (!SIMAD.Core.inIFrame) {
					for (var i in this.$s.ads) {
						if (this.$s.ads[i].getLoading() === SIMAD.Loading.INSTREAM && this.$s.ads[i].isActive()){
							this.__initMode = SIMAD.Loading.INSTREAM;
						}
					}
				} else {
					this.__initMode = SIMAD.Loading.INSTREAM;
				}
				this.__initStarted = true;
			}




			if (state === undefined) { state = (this.__initInstreamCompleted) ? 'post' : 'pre'; }

			if (this.__initMode === SIMAD.Loading.INSTREAM && state === 'pre' || // top of the page
				this.__initMode === SIMAD.Loading.POSTSTREAM && state === 'post') { // bottom of the page
				if (this.settings.initFunctions) {
					var initFunctionsArray = (SIMAD.Core.inIFrame) ? this.settings.initFunctions.iFrameInit : this.settings.initFunctions.defaultInit;
					if (initFunctionsArray && typeof(initFunctionsArray[this.__initCounter]) === 'function') {
						initFunctionsArray[this.__initCounter].call(this);
						this.__initCounter++;
					}
				}
			}

			return this;
		},


		/**
		 * Fallback function. Does nothing.
		 * The renderAd function of the adserver is responsable for rendering the actual ad. It will be called in the rendering queue inside the wrapper.
		 *
		 * @memberOf SIMAD.AdServerAdapter.Base
		 * @public
		 * @param {SIMAD.Ad} ad Ad to render
		 * @returns {SIMAD.AdServerAdapter.Base} Adserver adapter itself
		 */
		renderAd: function(ad) {
			return this;
		},



		/**
		 * Fallback function. Does nothing.
		 *
		 * @memberOf SIMAD.AdServerAdapter.Base
		 * @public
		 * @returns {SIMAD.AdServerAdapter.Base} Adserver adapter itself
		 */
		finalize: function() {
			return this;
		},


		/**
		 * Registers the the completion of the instream init blocks.
		 * This function will be called by the core on the first instream doAd call.
		 *
		 * @memberOf SIMAD.AdServerAdapter.Base
		 * @public
		 * @returns {SIMAd.AdServerAdapter.Base} Adserver adapter itself
		 */
		onInitBlockCompleted: function() {
			this.__initInstreamCompleted = true;
			return this;
		},


		/**
		 * Getter for the Adserver adapter property "name"
		 *
		 * @memberOf SIMAD.AdServerAdapter.Base
		 * @public
		 * @returns {Striing} Name of the Adserver adapter
		 */
		getName: function() {
			return this.__name;
		},


		/**
		 * Returns the dimensions of the ad as array of [widht, height].
		 * Default implementation. Returns [0, 0].
		 *
		 * @memberOf SIMAD.AdServerAdapter.Base
		 * @public
		 * @param {SIMAD.Ad} ad SIMAD ad
		 * @returns {Array} Array of [width, height]
		 */
		getDimensions: function(ad) {
			if (ad) { return [0, 0]; }
			return undefined;
		},


		/**
		 * Indicates if an ad was delivered or not.
		 * Default implementation. Indicated the delivery status be the ad dimensions.
		 *
		 * @memberOf SIMAD.AdServerAdapter.Base
		 * @public
		 * @param {SIMAD.Ad} ad SIMAD Ad
		 * @returns {Boolean} Delivered or not
		 */
		isDelivered: function(ad) {
			var dimensions = ad.getDimensions();
			return (dimensions[0] > 1 && dimensions[1] > 1);
		},


		/**
		* Hook function from the SIMAD.Core.reloadAds(). Gets the array of all ads to reload. Expects this array back (probably modified)
		*
		* @memberOf SIMAD.AdServerAdapter.Base
		* @public
		* @param {Array} adsToReload Array of all ads to reload
		* @returns {Array} Array of all ads to reload
		*/
		reloadAds: function(adsToReload) {
			return adsToReload;
		},


		/**
		 * Hook function from the SIMAD.Core.sortAds().
		 * Gets the array of ad objects and sort them in adserver spezific needed order.
		 * Default implementation does nothing.
		 *
		 * @memberOf SIMAD.AdServerAdapter.Base
		 * @public
		 * @param {Array} adsToSort Array of ad objects to sort
		 * @returns {Array} Sorted array of ads
		 */
		sortAds: function(adsToSort) {
			return adsToSort;
		},


		/**
		 * Gets the ad and return the styled markup of the ad.
		 * Used for Adserver adapter what do nor render ads directly with renderAd()
		 * function by request an javscript object and generate markup for it itselfs.
		 * Default implementation or styleAd return am empty string.
		 *
		 * @memberOf SIMAD.AdServerAdapter.Base
		 * @public
		 * @param {SIMAD.Ad} ad Ad to style
		 * @returns {String} Styled markup
		 */
		styleAd: function(ad){
			return "";
		},


		/**
		 * Returns the adserver specific name of ad format.
		 * Default implementation returns the SIMAD format names.
		 *
		 * @memberOf SIMAD.AdServerAdapter.Base
		 * @public
		 * @param {String} format SIMAD format constant
		 * @returns {String} Adserver specific format
		 */
		getMappedAdFormat: function(format) {
			return format;
		},


		/**
		 * Returns an array of global variable names what must be synced between master and iframe on the adreload.
		 * Default implementation returns an empty array.
		 *
		 * @memberOf SIMAD.AdServerAdapter.Base
		 * @public
		 * @returns {Array} Empty array
		 */
		getSyncVars: function() {
			return [];
		},


		resetSyncVars: function() {
			SIMAD.Log.log("SIMAD.AdServerAdapter." + this.getName(), "Reset global sync variables");
			var sVars = this.getSyncVars();
			for (var i = 0; i < sVars.length; i++) {
				window[sVars[i]] = undefined;
			}
		},


		syncVars: function(from, to) {
			SIMAD.Log.log("SIMAD.AdServerAdapter." + this.getName(), "Sync global variables");
			var sVars = this.getSyncVars();
			if (sVars && from && to) {
				SIMAD.Log.log("SIMAD.AdServerAdapter." + this.getName(), "Syncing global variables from " + from.toString() + " to " + to.toString());
				for (var i = 0; i < sVars.length; i++) {
					to[sVars[i]] = from[sVars[i]];
				}
			}
		}
	};
}


/*
	TODO Benedikt wants to write inline comments to this file
*/

/**
*
* SIMAD.AdServerAdapter
*
* @namespace SIMAD.AdServerAdapter
* @class SIMAD.AdServerAdapter.OAS
*/

if (typeof SIMAD !== 'undefined' &&
	typeof SIMAD.AdServerAdapter !== 'undefined' &&
	typeof SIMAD.AdServerAdapter.Base !== 'undefined') {

	SIMAD.AdServerAdapter.OAS = SIMAD.Util.extend({}, SIMAD.AdServerAdapter.Base, {
		/**
		 * Name of the AdServerAdapter
		 *
		 * @memberOf SIMAD.AdServerAdapter.OAS
		 * @private
		 * @type String
		 */
		__name: "OAS",


		/**
		 * Loads OAS script file
		 *
		 * @memberOf SIMAD.AdServerAdapter.OAS
		 * @private
		 */
		__initFunctionLoadScripts: function() {
			SIMAD.Log.log("init OAS", "OAS AdServerAdapter initialisation: LoadScripts");
			if(this.$s.video){
			}else{
				var self = this;
				var areAdsActive = SIMAD.getAds( function(ad) {
					return ad.getAdServer() === self.getName() && ad.isActive();
				});

				if(areAdsActive.length > 0){
					var loadScirptArgs ={
						method: 'mjx',
						taxonomie: this.__getTaxonomyString(),
						info: {
							content_type: this.__mapContentType(this.$s.contentType),
							no_sowefo: this.__checkNoSowefoFlag(),
							agofid: this.$s.agofCode || ''
						}
					};
					var oasScriptsToLoad = this.__getOasScriptList(loadScirptArgs);
					SIMAD.Log.log("init OAS","load script with URLs", oasScriptsToLoad);
					for(var i=0; i<oasScriptsToLoad.length; i++) {
						SIMAD.Util.includeJS(oasScriptsToLoad[i]);
					}
				}
			}
		},


		/**
		 * Loads JMX Video Ads
		 *
		 * @memberOf SIMAD.AdServerAdapter.OAS
		 * @private
		 */


		__init_inIFrameAfter: function() {
			SIMAD.Core.adInIFrame.triggerEvent('onIFrameAdStarted');
		},

		/**
		 * __getTaxonomyString returns the Taxonomy string of the page extrected from the channel and subchannle values in the session
		 * It allso consider /home handling.
		 */
		__getTaxonomyString: function() {
			var taxonomyString = this.$s.adServerSpecific.OAS.domainId; //is set in cms adapter for each domain
			if (typeof this.$s.cmsSpecific !== "undefined" && this.$s.cmsSpecific.marketingCluster) {
				taxonomyString += "/" + this.$s.cmsSpecific.marketingCluster;
			}
			var channels = [this.$s.channel, this.$s.subchannel1, this.$s.subchannel2, this.$s.subchannel3, this.$s.subchannel4, this.$s.subchannel5];
			var taxonomyEnd = false;
			for (var i=0; i < channels.length; i++) {
				if (!taxonomyEnd) {
					if (typeof channels[i] !== "undefined" && channels[i] !== "") {
						taxonomyString += "/" + channels[i];
					} else {
						if(i === 0){ //channel value
							taxonomyString += "/" + "home";
						}
						taxonomyEnd = true;
					}
				}
			}
			if (typeof SIMAD.CmsAdapter.__getOASTaxonomyString === "function") {
				taxonomyString = SIMAD.CmsAdapter.__getOASTaxonomyString(taxonomyString);
			}
			return taxonomyString;
		},

		/**
		 * OAS requres the url flag no_sowefo =1 for no sowefo and no_sowefo = 0 for sowefo allowed
		 * This function capsels the logic for identifying this values
		 */
		__checkNoSowefoFlag: function(){
			var no_sowefo = 1; // default no sowefo allowed
			if(SIMAD.Core.adInIFrame){
				 no_sowefo = 1;//no sowefo in iframe
			}else{
				if (this.$s.dynamicAds) {
					if (this.$s.dynamicAds.include === "all" && this.$s.dynamicAds.exceptOf.length === 0){
						no_sowefo = 0; // if all sowefos are allowerd and not are exluded then are sowefos allowed
					}
				}
			}
			return no_sowefo;
		},



		/**
		* renderAd
		*
		* Renders the ad tag.
		*
		* @params {SIMAD.Ad} ad The ad to render
		* @returns {SIMAD.AdServerAdapter} The AdServerAdapter itself
		*/
		renderAd: function(ad) {
			if(ad.getFormat() !== SIMAD.Format.PERFORMANCEBOX1){
				if(this.$s.video || SIMAD.Core.adInIFrame){
					var loadScirptArgs ={
						method: 'jx',
						taxonomie: this.__getTaxonomyString(),
						info: {
							content_type: this.__mapContentType(this.$s.contentType),
							no_sowefo: this.__checkNoSowefoFlag(), // 1,
							agofid: this.$s.agofCode || ''
						},
						"ad":ad
					};
					var oasScriptsToLoad = this.__getOasScriptList(loadScirptArgs);
					SIMAD.Log.log("output OAS", "rendering the ad "+ ad.getId()+ " load url ", oasScriptsToLoad);
					for(var i=0; i<oasScriptsToLoad.length; i++) {
						SIMAD.Util.includeJS(oasScriptsToLoad[i]);
					}
				}else{
					if (typeof(window.OAS_RICH) === "function") {
						window.OAS_RICH(ad.getAdServerFormat());
					}
				}
			}

			return this;
		},


		/**
		* reloadAds
		*
		* Hook function. Will be called on Core action "reloadAds"
		*
		* @params {Array} adsToReload An array of SIMAD.Ad objects to reload
		* @returns {Array} adsToReload An array of SIMAD.Ad objects to reload
		*/
		reloadAds: function(adsToReload) {
			var self = this;

			adsToReload = SIMAD.Util.filter(adsToReload, function(ad) {
				return !(SIMAD.Format.PERFORMANCEBOX1 === ad.getFormat() && ad.getAdServer() === self.getName());
			});

			if (adsToReload.length > 0 && adsToReload[0].getFormat() !== SIMAD.Format.POPUP) {
				var popups = SIMAD.Util.filter(adsToReload, function(ad) { return ad.getFormat() === SIMAD.Format.POPUP && ad.getAdServer() === self.getName() } );
				if (popups.length === 0) {
					var popupFromDS = this.__getPopupFromDS();
					if (!popupFromDS) {
						var newPopup = this.__createPopupAd();
						SIMAD.Core.addAd(newPopup);
						adsToReload.unshift(newPopup);
					} else {
						popupFromDS.activate();
						adsToReload.unshift(popupFromDS);
					}
				} else {
					var popupIndex = -1;
					for (var i = 0; i < adsToReload.length; i++) {
						if (adsToReload[i].getFormat() === SIMAD.Format.POPUP && adsToReload[i].getAdServer() === self.getName()) { popupIndex = i; }
					}
					if (popupIndex > -1) {
						var popup = adsToReload[popupIndex];
						adsToReload.splice(popupIndex, 1);
						adsToReload.unshift(popup);
					} else {
						SIMAD.Log.warn("Can't find popup in the list to reload");
					}
				}
			}

			return adsToReload;
		},


		/**
		 * Searches for a popup ad across all sessions in the datastore
		 *
		 * @memberOf SIMAD.AdServerAdapter.SOI
		 * @private
		 * @returns {SIMAD.Ad} Popup ad
		 */
		__getPopupFromDS: function() {
			for (var i = this.data.sessions.length - 1; i >= 0; i--) {
				for (var j in this.data.sessions[i].ads) {
					if (this.data.sessions[i].ads[j].getFormat() === SIMAD.Format.POPUP && this.data.sessions[i].ads[j].getAdServer() === this.getName()) {
						if (i < this.data.sessions.length - 1) {
							return SIMAD.Core.addAd(this.data.sessions[i].ads[j]);
						}
						return this.data.sessions[i].ads[j];
					}
				}
			}
			return undefined;
		},


		/**
		* __createPopupAd
		*
		* Creates a popup Ad object and placeholder for it.
		* WARNING: with function must be only called if DOM is safe (f.e. Adreload rotation)
		*
		* @returns {SIMAD.Ad} Ad Created Ad object
		*/
		__createPopupAd: function() {
			SIMAD.Log.log("output OAS","__createPopupAd");
			var body = document.getElementsByTagName('body')[0];
			var placeholder = document.createElement("div");
			var popupId = "popup" + Math.round(Math.random() * 9999);
			placeholder.id = "SIMAD_placeholder_" + popupId;
			body.appendChild(placeholder);
			var self = this;
			return new SIMAD.Ad({
				"id": popupId,
				"loading": SIMAD.Loading.INSTREAM,
				"format": SIMAD.Format.POPUP,
				"adServer": self.getName(),
				"active": true,
				"placeholder": placeholder.id
			});
		},

		/**
		 * getVideoAdRequest is called by the AdBridge and return a URL to the XML which descipbes the Video Ad.
		 * This happens for each video Ad Block:
		 	"preroll1","preroll1b","preroll1c","preroll1d","preroll1e",
			"midroll1","midroll1b","midroll1c","midroll1d","midroll1e",
			"midroll2","midroll2b","midroll2c","midroll2d","midroll2e",
			"midroll3","midroll3b","midroll3c","midroll3d","midroll3e",
			"midroll4","midroll4b","midroll4c","midroll4d","midroll4e",
			"midroll5","midroll5b","midroll5c","midroll5d","midroll5e",
			"sponsor1","sponsor1b","sponsor1c","sponsor1d","sponsor1e",
			"presplit1","presplit2","presplit3","presplit4","presplit5",
			"overlay1","overlay2","overlay3","overlay4","overlay5",
			"postroll1","postroll1b","postroll1c","postroll1d","postroll1e"

			gets only called when the vidoe ad is allowed (handled by AdBridgeadapter)
		 */
		getVideoAdRequest: function(args){

			var video_ad_id = args.video_ad_id;
			SIMAD.Log.log("output OAS"," getVideoAdRequest"+ "video_ad_id= "+video_ad_id,args);

			var videoXmlUrl = "";
			if (typeof(args) !== 'object'){ args = {};}


			var info ={
					content_type: this.__mapContentType(this.$s.contentType),
					no_sowefo: this.__checkNoSowefoFlag(),
					agofid: this.$s.agofCode || ''
				};
			var url_params = this.__getOasScriptURLParameter(info);
			if(url_params.length > 0) {
				url_params = url_params.slice(1 ); // remove the leading ?
				url_params= "&" +url_params; // ad a & to concat the parameter list
			}

			var taxonomie = this.__getTaxonomyString();

			var oasScriptBaseUrl = this.settings.AdserverBaseUrl + '/adstream_sx.ads' + '/' + taxonomie + '/1' + this.$s.sessionId + '@' ;

			var videoXmlUrl = "";

			if(video_ad_id ==="preroll1"){
				var self = this;
				var availableAdIds = SIMAD.Core.getAds( function(ad) {
					return ad.getFormat() !== SIMAD.Format.PERFORMANCEBOX1  && ad.getAdServer() === self.getName() && ad.isActive();
				});
				var availableAdIdCSV = SIMAD.Util.joinObjects(availableAdIds,"getAdServerFormat",",");
				if(availableAdIdCSV !== ""){
					availableAdIdCSV += ",";
				}

				videoXmlUrl = oasScriptBaseUrl + availableAdIdCSV  + "Video1!Video1"+ "?videotype="+ video_ad_id + url_params;

				SIMAD.Core.getSessionId(true); //generata a new Session ID which will be used with all other video adrequest
			}else{

				videoXmlUrl = oasScriptBaseUrl + "Video1"+ "?videotype="+ video_ad_id + url_params;

			}


			if(videoXmlUrl){
				if (typeof(args.industries) === 'object') {
						var ind_param = '';
						for (var key in args.industries) {
							if (args.industries[key].indtarget){

								var value = args.industries[key].industry;
								if (typeof(value) !== 'undefined' || String(value).length){

									if (ind_param) {ind_param += '&';}
									ind_param += 'ind=' + value;
								}
							}
						}
						if (ind_param) {
							videoXmlUrl += '&' + ind_param;
						}
					}
			}

			if(typeof this.$s.video.AdRequestLog === "undefined"){
				this.$s.video.AdRequestLog = {};
			}
			this.$s.video.AdRequestLog[video_ad_id] = videoXmlUrl;


			SIMAD.Log.log("OAS: Video","getVideoAdRequest for " + video_ad_id +" tools/ videoXmlUrl: "+ videoXmlUrl);
			return videoXmlUrl;
		},



		__getOasScriptURLParameter: function(info){

			var url_params = '';
			for (var key in info) {
				var value = info[key];
				if (typeof(value) === 'undefined' || !String(value).length) continue;
				if (url_params) url_params += '&';
				url_params += [escape(key), escape(info[key])].join('=');
			}
			if (url_params){ url_params = '?' + url_params;}


			var found;
			try{
				found = top.location.search.match(/(showroom)=([a-zA-Z0-9_-]*)/);
			}catch(e){
				SIMAD.Log.log("OAS Showroom","try to get the url from top went wrong");
			}
			if (found) {
				if (url_params) url_params += '&';
				url_params += [found[1], found[2] || 'standard'].join('=')
			}
			return url_params;
		},





		__getOasScriptList: function(args) {
			var oasScriptUrlList= [];
			if (typeof(args) === 'object' && args.taxonomie && args.method){

				var taxonomie = args.taxonomie;
				var method = args.method;

				var args_info = args.info;
				var jxVideoAdIdCSV ="";

				var self = this;

				var availableAdIds = SIMAD.Core.getAds( function(ad) {
					return ad.getFormat() !== SIMAD.Format.PERFORMANCEBOX1  && ad.getAdServer() === self.getName() && ad.isActive();
				});
				var availableAdIdCSV =SIMAD.Util.joinObjects(availableAdIds,"getAdServerFormat",",");

				var jxVideoAdIds = [];
				if (typeof(this.$s.video) !== "undefined" && typeof(this.$s.video.adFilter) !== "undefined") {
					if( this.$s.video.adFilter.all){
							if(this.$s.video.adFilter.preroll){
								args_info.videotype = "preroll1";
								jxVideoAdIdCSV = "Video1";

							}
					}
				}
				var url_params = this.__getOasScriptURLParameter(args_info);


				var oasScriptBaseUrl = this.settings.AdserverBaseUrl + '/adstream_'+method+'.ads' + '/' +
									taxonomie + '/1' + this.$s.sessionId + '@' ;
				switch(method){
					case "mjx":
						if (availableAdIdCSV) {

							var oasScriptmjxUrl = oasScriptBaseUrl + availableAdIdCSV+ url_params;
							oasScriptUrlList.push(oasScriptmjxUrl);
						}
						break;
					case "jx":
						if (availableAdIdCSV) {


							if(args.ad){
								var oasScriptUrl = oasScriptBaseUrl + availableAdIdCSV +","+ jxVideoAdIdCSV + '!'+ args.ad.getAdServerFormat() + url_params;

								oasScriptUrlList.push(oasScriptUrl);
							}else{
								SIMAD.Log.error("OAS __getOasScriptList: the argument.ad is not set");
							}
						}
						break;

				}
			}else{
				SIMAD.Log.warn("OAS init __getOasScriptList called with unexpected parameter set",args);
			}
			return oasScriptUrlList;
		},


		getDimensions: function(ad) {
			var oasinfo_container = document.getElementById('oasinfo_' + ad.getAdServerFormat());

			var width, height;

			if (oasinfo_container) {
				width  = parseInt(oasinfo_container.style.width);
				height = parseInt(oasinfo_container.style.height);
			}
			if (!width) width   = 0;
			if (!height) height = 0;
			if (ad.getFormat === SIMAD.Format.FULLBANNER) {
				if (width  > 728) width  = 728;
				if (height >  90) height =  90;
			}
			else if (ad.getFormat === SIMAD.Format.SKYSCRAPER) {
				if (width  > 160) width  = 160;
				if (height > 600) height = 600;
			}

			var dimensions = [width, height];

			return dimensions;
		},

		isDelivered: function(ad) {
			var oasinfo_container = document.getElementById('oasinfo_' +  ad.getAdServerFormat());
			var isDeliverd = false;

			if (oasinfo_container) {
				isDeliverd = true;
			}

			return isDeliverd;
		},


		__mapContentType: function(contentType) {
			/*
				TODO Write the invers functionality
			*/
			var map = [];
			map[SIMAD.ContentType.HOME] 				= "home";
			map[SIMAD.ContentType.VIDEO_OVERVIEW]		= "MCcontent";
			map[SIMAD.ContentType.RICH_VIDEO] 			= "MCplayer";
			map[SIMAD.ContentType.VIDEO] 				= "CPplayer";
			map[SIMAD.ContentType.COMMUNITY] 			= "ugc";
			map[SIMAD.ContentType.GALLERY] 				= "gallery";
			map[SIMAD.ContentType.GALLERY_IMAGE] 		= "gallery_zoom";
			map[SIMAD.ContentType.GAME] 				= "games";
			map[SIMAD.ContentType.SHOP] 				= "shop";
			map[SIMAD.ContentType.RAFFLE] 				= "raffle";
			map[SIMAD.ContentType.DEFAULT]	 			= "content";
			map[SIMAD.ContentType.ERROR] 				= "error";
			return (map[contentType] !== undefined) ? map[contentType] : "content";
		},
		/**
		 * was __mapAdFormat
		 * getMappedAdFormat return the name of the format used by the adserver.
		 * !!! This should only be called per ad once because SOI uses a counter of ads.
		 */
		getMappedAdFormat: function (format) {
			var formatMap = {};
			formatMap[SIMAD.Format.FULLBANNER] 			= "Top";
			formatMap[SIMAD.Format.SKYSCRAPER] 			= "Right1";
			formatMap[SIMAD.Format.MEDIUMRECTANGLE] 	= "Middle1";
			formatMap[SIMAD.Format.POPUP] 				= "Popup";
			formatMap[SIMAD.Format.MAXIAD] 				= "Middle2";
			formatMap[SIMAD.Format.PERFORMANCEBOX1] = "";

			var retval = formatMap[format];

			return retval || '';
		},

		getVideoAdInitiationAdFormat: function(ad){
			return SIMAD.Format.POPUP;
		},



		getSyncVars: function(){
			return [];
		}
	});

	SIMAD.AdServerAdapter.OAS.settings = {
		initFunctions : {
			"defaultInit": [SIMAD.AdServerAdapter.OAS.__initFunctionLoadScripts	],
			"iFrameInit" : [SIMAD.AdServerAdapter.OAS.__init_inIFrameAfter //,
							]
		},
		AdserverBaseUrl :'http://austria1.adverserve.net/RealMedia/ads'

	};
}

/**
* @namespace SIMAD.AdServerAdapter
* @class SIMAD.AdServerAdapter.GoogleAdSense
*/

if (typeof SIMAD !== 'undefined' && typeof SIMAD.AdServerAdapter !== 'undefined' && typeof SIMAD.AdServerAdapter.Base !== 'undefined') {

	SIMAD.AdServerAdapter.SOI = SIMAD.Util.extend({}, SIMAD.AdServerAdapter.Base, {
		/**
		 * Name of the AdServerAdapter
		 *
		 * @memberOf SIMAD.AdServerAdapter.SOI
		 * @private
		 * @type String
		 */
		__name: "SOI",

		/**
		 * Internal Helper to call simtracker
		 *
		 * @memberOf SIMAD.AdServerAdapter.SOI
		 * @private
		 */
		__track: function(json_param) {
		},

		/**
		 * Sets global SOI specific vars according to the SIMAD configs
		 *
		 * @memberOf SIMAD.AdServerAdapter.SOI
		 * @private
		 */
		__init_SOIVars: function() {
			SIMAD.Log.log("init SOI", "SOI AdServerAdapter initialisation: set SOI variables");

			window.SOI_GLOBALV		= "V6";
	   		window.SOI_WERBUNG  	= !this.$s.adFree;
	   		window.SOI_AGOFID		= this.$s.agofCode;
	   		window.SOI_BREADCRUMBS	= this.$s.breadcrumb;
	   		window.SOI_FRA 			= SIMAD.Core.inIFrame;
			window.SOI_SUBSITE   	= this.$s.channel;
			window.SOI_SUB2SITE  	= this.$s.subchannel1;
			window.SOI_SUB3SITE  	= this.$s.subchannel2;
			window.SOI_SUB4SITE  	= this.$s.subchannel3;
			window.SOI_SUB5SITE  	= this.$s.subchannel4;
			window.SOI_SUB6SITE  	= this.$s.subchannel5;
			window.SOI_CONTENT   	= this.__mapContentType(this.$s.contentType);

			window.SOI_SOWEFO		= SIMAD.Core.allowDynamicAd();
			window.SOI_PU 			= SIMAD.Core.allowDynamicAd(SIMAD.Format.POPUP_WINDOW);
			window.SOI_WP			= SIMAD.Core.allowDynamicAd(SIMAD.Format.WALLPAPER) && !SIMAD.Core.adInIFrame;
			window.SOI_PL			= SIMAD.Core.allowDynamicAd(SIMAD.Format.POWERLAYER) && !SIMAD.Core.adInIFrame;
			window.SOI_PB			= SIMAD.Core.allowDynamicAd(SIMAD.Format.POWERBANNER);
			window.SOI_PR			= SIMAD.Core.allowDynamicAd(SIMAD.Format.POWERRECTANGLE);
			window.SOI_SB			= SIMAD.Core.allowDynamicAd(SIMAD.Format.SIDEBAR) && !SIMAD.Core.adInIFrame;
			window.SOI_FP			= SIMAD.Core.allowDynamicAd(SIMAD.Format.FIREPLACE) && !SIMAD.Core.adInIFrame;
			window.SOI_HP     = SIMAD.Core.allowDynamicAd(SIMAD.Format.HALFPAGE) && !SIMAD.Core.adInIFrame;
			window.SOI_PD     = SIMAD.Core.allowDynamicAd(SIMAD.Format.PUSHDOWN) && !SIMAD.Core.adInIFrame;

			var self = this;
			var fullbannerAds		= SIMAD.Core.getAds(function(ad) { return ad.isActive() && ad.getAdServer() === self.getName() && ad.getFormat() === SIMAD.Format.FULLBANNER; });
			if (fullbannerAds.length > 0) {
				window.SOI_BB		= (SIMAD.Core.allowDynamicAd(SIMAD.Format.BILLBOARD)) &&
									  (fullbannerAds[0].getLoading() == SIMAD.Loading.POSTSTREAM) &&
									  (this.$s.contentType != SIMAD.ContentType.VIDEO) &&
									  (!SIMAD.Core.adInIFrame);
			} else {
				window.SOI_BB 		= false;
			}

			window.SOI_FB2			= SIMAD.Core.getAds(function(ad) { return ad.isActive() && ad.getAdServer() === self.getName() && ad.getFormat() === SIMAD.Format.FULLBANNER; }).length > 0;
			window.SOI_RT1			= SIMAD.Core.getAds(function(ad) { return ad.isActive() && ad.getAdServer() === self.getName() && ad.getFormat() === SIMAD.Format.MEDIUMRECTANGLE; }).length > 0;
			window.SOI_SC1			= SIMAD.Core.getAds(function(ad) { return ad.isActive() && ad.getAdServer() === self.getName() && ad.getFormat() === SIMAD.Format.SKYSCRAPER; }).length > 0;
			window.SOI_PU1			= SIMAD.Core.getAds(function(ad) { return ad.isActive() && ad.getAdServer() === self.getName() && ad.getFormat() === SIMAD.Format.POPUP; }).length > 0;

			window.SOI_TCLUSTER 	= "";

			if (this.$s.contentType === SIMAD.ContentType.HOME) {
				var channels = ["SOI_SUBSITE", "SOI_SUB2SITE", "SOI_SUB3SITE", "SOI_SUB4SITE", "SOI_SUB5SITE", "SOI_SUB6SITE"];
				var set = false;
				for (var i = 0; i < channels.length; i++) {
					if ((!window[channels[i]] || window[channels[i]] === "") && !set) {
						window[channels[i]] = "home";
						set = true;
					}
				}
			}

	   		if (this.$s.adServerSpecific) {
				window.SOI_SITE 	= this.$s.adServerSpecific.SOI.domainId;
		   		window.SOI_UPC 		= this.$s.adServerSpecific.SOI.UPC;
			}

			window.SOI_MARKETINGCLUSTER = (this.$s.cmsSpecific) ? this.$s.cmsSpecific.marketingCluster : "";

			if(typeof(this.$s.cmsSpecific.contentCluster) !== "undefined" ) {
				window.SOI_CLUSTER = this.$s.cmsSpecific.contentCluster;
			}
			if(typeof(this.$s.cmsSpecific.halfPageAd) !== "undefined" ) {
				if(this.$s.cmsSpecific.halfPageAd ===true || this.$s.cmsSpecific.halfPageAd === "true"){
					window.SOI_HP = true;
				}else{
					window.SOI_HP = false;
				}
			}


			if (typeof(this.$s.video) !== "undefined" && typeof(this.$s.video.adFilter) !== "undefined") {
				window.SOI_VP = this.$s.video.adFilter.all;
				window.SOI_LPY = (this.$s.video.type === "full") ? true : false;
				window.SOI_NPY = (this.$s.video.player !== "video") ? true : false ;
				window.SOI_VA1 = this.$s.video.adFilter.preroll;
				window.SOI_VA2 = this.$s.video.adFilter.postroll;
				window.SOI_VA3 = this.$s.video.adFilter.midroll;
				window.SOI_VA4 = this.$s.video.adFilter.overlay;
				window.SOI_VA5 = this.$s.video.adFilter.sponsor;
			}

			if (! SIMAD.Core.adInIFrame) {
				if(!SIMAD.Core.getAds(function(ad) { return ad.isActive() && ad.getAdServer() === self.getName()}).length > 0){
					window.SOI_INIT_DONE = true;
				}
			}
		},


		/**
		 * Sets global SOI specific vars according to the SIMAD configs in the iFrame.
		 * This init function will be called only inside the init rotation in iFrame.
		 *
		 * @memberOf SIMAD.AdServerAdapter.SOI
		 * @private
		 */
		__init_inIFrame: function() {
			window.SOI_INIT_DONE = (parent.SIMAD.Core.__reloadAdsRotation.currentIndex > 0) ? true : false;

			window.SOI_SOWEFO = false;
		},


		/**
		 * Inludes the site specific SOI scripts.
		 *
		 * @memberOf SIMAD.AdServerAdapter.SOI
		 * @private
		 */
		__init_includeSiteSpecificJS: function() {
			SIMAD.Log.log("init SOI", "SOI AdServerAdapter initialisation: include site specific JavaScript file");

			if (this.$s.adServerSpecific && this.$s.adServerSpecific.SOI && this.$s.adServerSpecific.SOI.siteSpecificJS !== undefined) {
				SIMAD.Util.includeJS(this.$s.adServerSpecific.SOI.siteSpecificJS);
			}
		},


		/**
		 * Includes the SOI script.
		 *
		 * @memberOf SIMAD.AdServerAdapter.SOI
		 * @private
		 */
		__init_includeGlobalV6: function() {
			SIMAD.Log.log("init SOI", "SOI AdServerAdapter initialisation: include the globalV6.js");

			SIMAD.AdServerAdapter.SOI.__track({	event:  'collect' ,  param: 'includeGlobalV6'});

			SIMAD.Util.includeJS("http://ad.71i.de/global_js/globalV6.js");
		},


		/**
		 * Triggers the onIFrameAdStarted event of the inited ad
		 *
		 * @memberOf SIMAD.AdServerAdapter.SOI
		 * @private
		 */
		__init_inIFrameAfter: function() {
			if (SIMAD.Core.adInIFrame) {
				SIMAD.Core.adInIFrame.triggerEvent('onIFrameAdStarted');
			}
		},


		/**
		 * Returns the URL to the XML which descibes the video ad
		 * Will be called by the AdBridge for each video Ad Block:
		 *	"preroll1","preroll1b","preroll1c","preroll1d","preroll1e",
		 *	"midroll1","midroll1b","midroll1c","midroll1d","midroll1e",
		 *	"midroll2","midroll2b","midroll2c","midroll2d","midroll2e",
		 *	"midroll3","midroll3b","midroll3c","midroll3d","midroll3e",
		 *	"midroll4","midroll4b","midroll4c","midroll4d","midroll4e",
		 *	"midroll5","midroll5b","midroll5c","midroll5d","midroll5e",
		 *	"sponsor1","sponsor1b","sponsor1c","sponsor1d","sponsor1e",
		 *	"presplit1","presplit2","presplit3","presplit4","presplit5",
		 *	"overlay1","overlay2","overlay3","overlay4","overlay5",
		 *	"postroll1","postroll1b","postroll1c","postroll1d","postroll1e"
		 *
		 * @memberOf SIMAD.AdServerAdapter.SOI
		 * @public
		 * @param {Object} args JSON object with video parameters
		 * @returns {String} URL to the XML
		 */
		getVideoAdRequest: function(args){
			var video_ad_id = args.video_ad_id;
			SIMAD.Log.log("video SOI"," getVideoAdRequest"+ "video_ad_id= "+video_ad_id,args);
			var videoXmlUrl="";
			var collect_param = "VAdReq:" + video_ad_id + ":";


			if (typeof(args) !== 'object'){ args = new Object;}


			if (typeof(window.soi_VideoAdRequest) === 'function') {
				var config_data = new Object;
				if (typeof(args.industries) === 'object') config_data.industries = args.industries;
				if (args.prefetch){ config_data.prefetch = true;}
				if (typeof(args.prefetch) === 'undefined'
					&& (this.$s.contenType === 'MCplayer' || this.$s.contenType === 'CPplayer')) {
					if (video_ad_id.match(/^midroll/)) {
						config_data.prefetch = true;
					}
				}

				videoXmlUrl = window.soi_VideoAdRequest(video_ad_id, config_data);
				collect_param =  collect_param + ",Vid:" + videoXmlUrl.length;
				collect_param =  collect_param + ",Prefetch:" + config_data.prefetch;
			} else {
				collect_param = collect_param + '(window.soi_VideoAdRequest failed)';
			}

			if(videoXmlUrl && video_ad_id.match(/(presplit|midroll)/)){
				var adsToClear = SIMAD.Core.getAds();
				for (var i = 0; i < adsToClear.length; i++) {
					adsToClear[i].clear();
				}
			}

			if(typeof this.$s.video.AdRequestLog === "undefined"){
				this.$s.video.AdRequestLog = [];
			}
			this.$s.video.AdRequestLog[video_ad_id] = videoXmlUrl;

			SIMAD.AdServerAdapter.SOI.__track({	event:  'collect' ,  param: collect_param});

			SIMAD.Log.log("video SOI","getVideoAdRequest for " + video_ad_id +" tools/ videoXmlUrl: "+ videoXmlUrl);
			return videoXmlUrl;
		},


		/**
		* Renders the ad tag
		*
		* @memberOf SIMAD.AdServerAdapter.SOI
		* @public
		* @param {SIMAD.Ad} ad The ad to render
		* @returns {SIMAD.AdServerAdapter.SOI} The AdServer adapter itself
		*/
		renderAd: function(ad) {
			SIMAD.Log.log("render Ad SOI", "rendering the ad ", ad);
			var output = "";
			if (ad.getFormat() === SIMAD.Format.PERFORMANCEBOX1) {
				window.SOI_SHOPPINGTIP = undefined;
			}
			if (typeof(window.soi_Tagwriter) === "function") {
				output = window.soi_Tagwriter(ad.getAdServerFormat());
			}
			SIMAD.Log.log("render Ad SOI", "load script ",  new Array(output));
			document.write(output);
			return this;
		},


		/**
		 * Generate markup trougth the onLoadCallback function if defined.
		 *
		 * @memberOf SIMAD.AdServerAdapter.SOI
		 * @public
		 * @param {SIMAD.Ad} ad The ad to style
		 */
		styleAd: function(ad) {
			var shoppingTipMarkup = "";

			if (ad.getFormat() === SIMAD.Format.PERFORMANCEBOX1) {
				var soiShoppingTip = window.SOI_SHOPPINGTIP;
				DEBUG_ = this.isDelivered(ad);
				if (soiShoppingTip  && this.isDelivered(ad)) {
					var onRenderCallback = ad.getOnRenderCallback();
					if (typeof(onRenderCallback) === 'function') {
						shoppingTipMarkup = onRenderCallback(ad, soiShoppingTip);
					}
				};
				window.SOI_SHOPPINGTIP = undefined;
			}
			return shoppingTipMarkup;
		},


		/**
		 * Returns the dimensions of the ad as array of [widht, height].
		 *
		 * @memberOf SIMAD.AdServerAdapter.SOI
		 * @public
		 * @param {SIMAD.Ad} ad SIMAD ad
		 * @returns {Array} Array of [width, height]
		 */
		getDimensions: function(ad) {
			var dimensions = [0, 0];



			if (window.soi_dimension) {
				dimensions = window.soi_dimension[ad.getAdServerFormat()];
			}

			if (dimensions && ad.getFormat() === SIMAD.Format.FULLBANNER && this.__isAdType(ad, "PB2")) { dimensions[1] = 180; }

			return dimensions;
		},

		/**
		 * Indicates if an ad was delivered or not.
		 *
		 * @memberOf SIMAD.AdServerAdapter.SOI
		 * @public
		 * @param {SIMAD.Ad} ad SIMAD Ad
		 * @returns {Boolean} Delivered or not
		 */
		isDelivered: function(ad) {
			return this.__isAdType(ad) && !this.__isAdType(ad, 'Fallback');
		},


		/**
		* Hook function from the SIMAD.Core.reloadAds(). Gets the array of all ads to reload. Expects this array back (probably modified)
		* Deletes all shoppingtipps, makes sure the popup tag is the first ad and is always available.
		*
		* @memberOf SIMAD.AdServerAdapter.SOI
		* @public
		* @param {Array} adsToReload An array of SIMAD.Ad objects to reload
		* @returns {Array} adsToReload An array of SIMAD.Ad objects to reload
		*/
		reloadAds: function(adsToReload) {
			var self = this;

			adsToReload = SIMAD.Util.filter(adsToReload, function(ad) {
				return !(SIMAD.Format.PERFORMANCEBOX1 === ad.getFormat() && ad.getAdServer() === self.getName());
			});

			if (adsToReload.length > 0 && adsToReload[0].getFormat() !== SIMAD.Format.POPUP) {
				var popups = SIMAD.Util.filter(adsToReload, function(ad) { return ad.getFormat() === SIMAD.Format.POPUP && ad.getAdServer() === self.getName() } );
				if (popups.length === 0) {
					var popupFromDS = this.__getPopupFromDS();
					if (!popupFromDS) {
						var newPopup = this.__createPopupAd();
						SIMAD.Core.addAd(newPopup);
						adsToReload.unshift(newPopup);
					} else {
						popupFromDS.activate();
						adsToReload.unshift(popupFromDS);
					}
				} else {
					var popupIndex = -1;
					for (var i = 0; i < adsToReload.length; i++) {
						if (adsToReload[i].getFormat() === SIMAD.Format.POPUP && adsToReload[i].getAdServer() === self.getName()) { popupIndex = i; }
					}
					if (popupIndex > -1) {
						var popup = adsToReload[popupIndex];
						adsToReload.splice(popupIndex, 1);
						adsToReload.unshift(popup);
					} else {
						SIMAD.Log.warn("Can't find popup in the list to reload");
					}
				}
			}

			return adsToReload;
		},

		finalize: function(inIFrame) {
			SIMAD.Log.log("finalize", "SOI GandTracker finalize");

			if (typeof(simTracker) !== "undefined" && typeof(simTracker.GandTracker) !== "undefined" &&typeof(simTracker.GandTracker.trackAdStatus) ===  'function') {
				var message= '';
					if (inIFrame) {
						message = "fromSOIAdapterStatic";
					} else {
						message = "fromSOIAdapter";
					}
					simTracker.GandTracker.trackAdStatus(message);
			} else {
				SIMAD.Log.warn("init SOI", "Gandtracker not available.  trackAdStatus() ommitted");
			}

			return this;
		},


		sortAds: function(adsToSort) {
			var formatOrder = [SIMAD.Format.POPUP, SIMAD.Format.FULLBANNER, SIMAD.Format.SKYSCRAPER, SIMAD.Format.MEDIUMRECTANGLE, SIMAD.Format.PERFORMANCEBOX1];
			var self = this;
			adsToSort.sort(function(a, b) {
				if (a.getAdServer() === self.getName() && b.getAdServer() === self.getName()) {
					var indexA = SIMAD.Util.indexInArray(formatOrder, a.getFormat());
					var indexB = SIMAD.Util.indexInArray(formatOrder, b.getFormat());
					if (indexA < 0 ) {
						return 1;
					} else if (indexB < 0) {
						return -1;
					}
					return indexA - indexB;
				}
				return 0;
			});
			return adsToSort;
		},



		/**
		 * Searches for a popup ad across all sessions in the datastore
		 *
		 * @memberOf SIMAD.AdServerAdapter.SOI
		 * @private
		 * @returns {SIMAD.Ad} Popup ad
		 */
		__getPopupFromDS: function() {
			for (var i = this.data.sessions.length - 1; i >= 0; i--) {
				for (var j in this.data.sessions[i].ads) {
					if (this.data.sessions[i].ads[j].getFormat() === SIMAD.Format.POPUP && this.data.sessions[i].ads[j].getAdServer() === this.getName()) {
						if (i < this.data.sessions.length - 1) {
							return SIMAD.Core.addAd(this.data.sessions[i].ads[j]);
						}
						return this.data.sessions[i].ads[j];
					}
				}
			}
			return undefined;
		},


		/**
		* Creates a popup Ad object and placeholder for it.
		* WARNING: with function must be only called if DOM is safe (f.e. Adreload rotation)
		*
		* @memberOf SIMAD.AdServerAdapter.SOI
		* @private
		* @returns {SIMAD.Ad} Ad Created Ad object
		*/
		__createPopupAd: function() {
			SIMAD.Log.log("output SOI","__createPopupAd");
			var body = document.getElementsByTagName('body')[0];
			var placeholder = document.createElement("div");
			var popupId = "popup" + Math.round(Math.random() * 9999);
			placeholder.id = "SIMAD_placeholder_" + popupId;
			body.appendChild(placeholder);
			var self = this;
			return new SIMAD.Ad({
				"id": popupId,
				"loading": SIMAD.Loading.INSTREAM,
				"format": SIMAD.Format.POPUP,
				"adServer": self.getName(),
				"active": true,
				"placeholder": placeholder.id
			});
		},


		getVideoAdInitiationAdFormat: function(ad){
			return SIMAD.Format.POPUP;
		},


		/**
		 * Returns an array of global variable names what must be synced between master and iframe on the adreload.
		 *
		 * @memberOf SIMAD.AdServerAdapter.SOI
		 * @public
		 * @returns {Array} Array of variable names
		 */
		getSyncVars: function() {
			return ['soi_adtrace', 'soi_dimension',
				'SoiSetPre', 'SoiSetSpon', 'SoiSetMid', 'SoiSetOva', 'SoiSetPost',
				'forceSkyscraperInside', 'forceSkyscraperOutside', 'preferSkyscraperOutside',
				'DFPSite', 'DFPZone', 'DFPTile', 'DFPOrd', 'DFPOid',
				'SOI_SITE', 'SOI_SUBSITE', 'SOI_SUB2SITE', 'SOI_SUB3SITE', 'SOI_SUB4SITE', 'SOI_SUB5SITE', 'SOI_SUB6SITE',
				'SOI_BREADCRUMBS', 'SOI_MARKETINGCLUSTER', 'SOI_CONTENT',
				'SOI_WERBUNG', 'SOI_FB1', 'SOI_FB2', 'SOI_RT1', 'SOI_RT2', 'SOI_RT3', 'SOI_SC1', 'SOI_PU1',
				'SOI_VP', 'SOI_VA1', 'SOI_VA2', 'SOI_VA3', 'SOI_VA4', 'SOI_VA5', 'SOI_LPY', 'SOI_NPY',
				'SOI_SOWEFO', 'SOI_PU', 'SOI_WP', 'SOI_PW', 'SOI_PB', 'SOI_PC', 'SOI_PL', 'SOI_PR', 'SOI_UPC'
			];
		},


		resetSyncVars: function() {
			SIMAD.Log.log("SIMAD.AdServerAdapter." + this.getName(), "Reset global sync variables");
			soi_ResetVars();
		},


		syncVars: function(from, to) {
			SIMAD.Log.log("SIMAD.AdServerAdapter." + this.getName(), "Sync global variables");
			soi_SyncVars(from, to);
		},


		/**
		 * Returns the adserver specific name of ad format.
		 * WARNING: This should only be called per ad once because SOI uses a counter of ads.
		 *
		 * @memberOf SIMAD.AdServerAdapter.SOI
		 * @public
		 * @public
		 * @param {String} format SIMAD format constant
		 * @returns {String} Adserver specific format
		 */
		getMappedAdFormat: function (format) {
			var shoppingTipFormatStr = "";
			var formatMap = [];
			formatMap[SIMAD.Format.FULLBANNER] 			= "fullbanner2";
			formatMap[SIMAD.Format.SKYSCRAPER] 			= "skyscraper1";
			formatMap[SIMAD.Format.MEDIUMRECTANGLE] 	= "rectangle1";
			formatMap[SIMAD.Format.POPUP] 				= "popup1";
			formatMap[SIMAD.Format.MAXIAD] 				= "maxiad1";
			formatMap[SIMAD.Format.PERFORMANCE1] 		= "performance1";
			formatMap[SIMAD.Format.PERFORMANCE2] 		= "performance2";

			if (format === SIMAD.Format.PERFORMANCEBOX1) { //SOI shoppingTip string
				if (window.SOI_ZAHL == null) {
					window.SOI_ZAHL = 1;
				} else {
					window.SOI_ZAHL += 1;
				}
				if (window.SOI_place && window.SOI_ZAHL) { //TODO count SOI_Zahl here
					shoppingTipFormatStr = window.SOI_place[window.SOI_ZAHL];
				}
			}

			formatMap[SIMAD.Format.PERFORMANCEBOX1] = shoppingTipFormatStr;

			return formatMap[format];
		},


		/**
		* Checks the type of the ad in the adtrace
		*
		* @memberOf SIMAD.AdServerAdapter.SOI
		* @private
		* @param {SIMAD.Ad} ad
		* @returns {boolean} Do the ad match the type or not
		*/
		__isAdType: function(ad, type) {
			var adTrace = window.soi_adtrace ? unescape(window.soi_adtrace) : '';
			if (adTrace && ad) {
				type = type || '';
				typeTest = new RegExp(ad.getAdServerFormat() + '.+' + type, 'i');
				return typeTest.test(adTrace.toLowerCase().replace(new RegExp( "\\n", "g" ), ''));
			}
			return false;
		},


		/**
		 * Returns the adserver specific content type name for the passed content type.
		 *
		 * @memberOf SIMAD.AdServerAdapter.SOI
		 * @private
		 * @param {String} contentType Internal content type value
		 * @returns {String} Mapped adserver specific content type value
		 */
		__mapContentType: function(contentType) {
			/*
				TODO Write the invers functionality
			*/
			var map = [];
			map[SIMAD.ContentType.HOME] 				= "home";
			map[SIMAD.ContentType.VIDEO_OVERVIEW]		= "MCcontent";
			map[SIMAD.ContentType.RICH_VIDEO] 			= "MCplayer";
			map[SIMAD.ContentType.VIDEO] 				= "video";
			map[SIMAD.ContentType.LIVE_VIDEO]			= "LivePlayer";
			map[SIMAD.ContentType.COMMUNITY] 			= "ugc";
			map[SIMAD.ContentType.GALLERY] 				= "gallery";
			map[SIMAD.ContentType.GALLERY_IMAGE] 		= "gallery_zoom";
			map[SIMAD.ContentType.GAME] 				= "games";
			map[SIMAD.ContentType.SHOP] 				= "shop";
			map[SIMAD.ContentType.RAFFLE] 				= "raffle";
			map[SIMAD.ContentType.DEFAULT]	 			= "content";
			map[SIMAD.ContentType.ERROR] 				= "error";
			return (map[contentType] !== undefined) ? map[contentType] : "content";
		}

	});

	/**
	 * Adserver adapter setting
	 *
	 * @memberOf SIMAD.AdServerAdapter.SOI
	 * @public
	 * @type Object
	 */
	SIMAD.AdServerAdapter.SOI.settings = {
		initFunctions : {
			"defaultInit": [
				SIMAD.AdServerAdapter.SOI.__init_SOIVars,
				SIMAD.AdServerAdapter.SOI.__init_includeSiteSpecificJS,
				SIMAD.AdServerAdapter.SOI.__init_includeGlobalV6
			],

			"iFrameInit": [
				SIMAD.AdServerAdapter.SOI.__init_SOIVars,
				SIMAD.AdServerAdapter.SOI.__init_inIFrame,
				SIMAD.AdServerAdapter.SOI.__init_includeSiteSpecificJS,
				SIMAD.AdServerAdapter.SOI.__init_includeGlobalV6,
				SIMAD.AdServerAdapter.SOI.__init_inIFrameAfter
			]
		}
	};
}

/**
* @namespace SIMAD.AdServerAdapter
* @class SIMAD.AdServerAdapter.GoogleAdSense
*/

if (typeof SIMAD !== 'undefined' && typeof SIMAD.AdServerAdapter !== 'undefined' && typeof SIMAD.AdServerAdapter.Base !== 'undefined') {

	SIMAD.AdServerAdapter.GoogleAdSense = SIMAD.Util.extend({}, SIMAD.AdServerAdapter.Base, {
		/**
		 * Name of the AdServerAdapter
		 *
		 * @memberOf SIMAD.AdServerAdapter.GoogleAdSense
		 * @private
		 * @type String
		 */
		__name: "GoogleAdSense",


		/**
		 * Counter for the google_skip variable.
		 * Every time the new ad is rendered on the same page, the counter will be increased.
		 *
		 * @memberOf SIMAD.AdServerAdapter.GoogleAdSense
		 * @private
		 * @type Number
		 */
		__googleAdsSum: 0,


		/**
		 * Buffer for currently proccessed ad. Needed to transfer the SIMAD ad onject into the googe_ad_request_done function.
		 *
		 * @memberOf SIMAD.AdServerAdapter.GoogleAdSense
		 * @private
		 * @type SIMAD.Ad || undefined
		 */
		__processedAd: undefined,


		/**
		 * Delivers empty string. GoogleAdSense AdServerAdapter doesn't support video ads.
		 *
		 * @memberOf SIMAD.AdServerAdapter.GoogleAdSense
		 * @public
		 * @returns {String} Empty string
		 */
		getVideoAdRequest: function(args) {
			return '';
		},


		/**
		* renderAd
		*
		* Renders the ad tag.
		*
		* @params {SIMAD.Ad} ad The ad to render
		* @returns {SIMAD.AdServerAdapter} The AdServerAdapter itself
		*/
		renderAd: function(ad) {
			if (ad) {
				if (this.__setGoogleAdParams(ad)) {
					this.__processedAd = ad;

					if (typeof(window.google_ad_request_done) != "function") {
					  window.google_ad_request_done = this.__googleAdRequestDone;
					}

					document.write('<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>');
				}
			}

			return this;
		},


		styleAd: function(ad) { // The ad should be styles current the renderer execution. The ad will passed to the onRenderCallback-function later througth __googleAdRequestDone.
			return '';
		},



		/**
		 * Returns dimensions of the ad as array with 2 elements (width and height).
		 *
		 * @memberOf SIMAD.AdServerAdapter.GoogleAdSense
		 * @public
		 * @param {SIMAD.Ad} ad Ad
		 * @returns {Array} Array with dimensions
		 */
		getDimensions: function(ad) {
			var dims = [0, 0];

			if (ad.getAdServerSpecific() && ad.getAdServerSpecific().GoogleAdSense && ad.getAdServerSpecific().GoogleAdSense.googleAds && ad.getAdServerSpecific().GoogleAdSense.googleAds.length > 0) {

				var googleAd = ad.getAdServerSpecific().GoogleAdSense.googleAds[0];
				if (googleAd.type === 'image' || googleAd.type === 'flash') { // No dimensions for ads of type 'text'
					dims[0] = googleAd.image_width;
					dims[1] = googleAd.image_height;
				}
			}
			return dims;
		},


		/**
		 * Returns true if the ad is delivered by the adserver. False if not.
		 *
		 * @memberOf SIMAD.AdServerAdapter.GoogleAdSense
		 * @public
		 * @param {SIMAD.Ad} ad
		 * @returns {Bolean} Delivered or not
		 */
		isDelivered: function(ad) {
			return (ad.getAdServerSpecific() && ad.getAdServerSpecific().GoogleAdSense && ad.getAdServerSpecific().GoogleAdSense.googleAds && ad.getAdServerSpecific().GoogleAdSense.googleAds.length > 0);
		},


		/**
		 * Returns the GoogleAdSenseReloader for google ads
		 *
		 * @memberOf SIMAD.AdServerAdapter.GoogleAdSense
		 * @public
		 * @param {SIMAD.Ad} ad
		 * @returns {SIMAD.Reloader.GoogleAdSenseReloader || undefined} GoogleAdSenseReloader or undefined
		 */
		getReloaderFor: function(ad) {
			if (ad.getAdServer() === this.getName()) {
				return SIMAD.Reloader.GoogleAdSenseReloader;
			}
			return undefined;
		},


		/**
		 * Sets google specific global variables for the next ad rendering
		 *
		 * @memberOf SIMAD.AdServerAdapter.GoogleAdSense
		 * @private
		 * @param {SIMAD.Ad} ad
		 * @returns {Boolean} True if everything went right, false if not
		 */
		__setGoogleAdParams: function(ad) {
			if (this.$s.adServerSpecific && this.$s.adServerSpecific.GoogleAdSense) {
				window.google_ad_client = 	this.$s.adServerSpecific.GoogleAdSense.google_ad_client;
				window.google_hints = 		this.$s.adServerSpecific.GoogleAdSense.google_hints || "";
				window.google_ad_output = 	this.$s.adServerSpecific.GoogleAdSense.google_ad_output;
				window.google_language = 	this.$s.adServerSpecific.GoogleAdSense.google_language || "de";
				window.google_encoding = 	this.$s.adServerSpecific.GoogleAdSense.google_encoding || "ISO-8859-1";
				window.google_feedback =	this.$s.adServerSpecific.GoogleAdSense.google_feedback || "on";
				window.google_ad_section =	this.$s.adServerSpecific.GoogleAdSense.google_ad_section || "default";
				window.google_ad_type = 	this.__getGoogleAdType(ad) || "text";
				window.google_ad_channel = (typeof SIMAD.CmsAdapter.__getGoogleChannel === "function") ? SIMAD.CmsAdapter.__getGoogleChannel(ad) : this.$s.adServerSpecific.GoogleAdSense.google_ad_channel;

				if (window.google_ad_type === 'text') {
					if (ad.getAdServerSpecific() && ad.getAdServerSpecific().GoogleAdSense && ad.getAdServerSpecific().GoogleAdSense.google_max_num_ads !== undefined) {
						window.google_max_num_ads = ad.getAdServerSpecific().GoogleAdSense.google_max_num_ads;
					} else {
						SIMAD.Log.warn("GoogleAdSense parameter max_num_ads must be defined for ad " + ad.getId());
					}
				} else {
					window.google_image_size = this.__getGoogleImageSize(ad);
					window.google_max_num_ads = 1;
				}

				if (this.__googleAdsSum > 0) {
					window.google_skip = this.__googleAdsSum;
				}

				return true;
			} else {
				SIMAD.Log.error("No adServerSpecific configs for GoogleAdSense found.");
			}
			return false;
		},


		/**
		 * Callback function called by google script when the current ad rendering is done.
		 * Adds delivered information to the ad object, styles and renders ad, inits google_skip param.
		 *
		 * @memberOf SIMAD
		 * @private
		 * @param {Array} googleAds Array of google ads
		 */
		__googleAdRequestDone: function(googleAds) {
			var $this = SIMAD.AdServerAdapter.GoogleAdSense;
			if (googleAds.length > 0 && $this.__processedAd) {
				var ad = $this.__processedAd;
				ad.addAdServerSpecific({
					"GoogleAdSense": {
						"googleAds": googleAds
					}
				});

				var renderCallback = ad.getOnRenderCallback() || $this.__defaultOnRenderCallback;
				if (typeof(renderCallback) === 'function') {
					document.write(renderCallback(ad, googleAds));
				}
				$this.__googleAdsSum += googleAds.length;
			}
			$this.__processedAd = undefined;
		},


		/**
		 * Returns google specific size string for passed ad.
		 *
		 * @memberOf SIMAD.AdServerAdapter.GoogleAdSense
		 * @private
		 * @param {SIMAD.Ad} ad
		 * @returns {String} Ad size as string
		 */
		__getGoogleImageSize: function(ad) {
			var map = [];
			map[SIMAD.Format.FULLBANNER] 			= "728x90";
			map[SIMAD.Format.SKYSCRAPER]			= "160x600";
			map[SIMAD.Format.MEDIUMRECTANGLE]		= "300x250";

			return (map[ad.getFormat()] !== undefined) ? map[ad.getFormat()] : "728x90";
		},


		/**
		 * Returns google specific type for passed ad.
		 *
		 * @memberOf SIMAD.AdServerAdapter.GoogleAdSense
		 * @private
		 * @param {SIMAD.Ad} ad
		 * @returns {String} Ad type as string
		 */
		__getGoogleAdType: function(ad) {
			var type;
			if (ad.getFormat() === SIMAD.Format.ADSENSETEXT) {
				type = 'text'
			} else {
				type = 'image, flash'
			}
			return type;
		},


		/**
		 * Default onRenderCallback used for google ads with no onRenderCallbacks defined in CMS.
		 * Renders images and flash ad clean HTML nodes. Texte as DIVs with Headers and text bodies.
		 *
		 * @memberOf SIMAD.AdServerAdapter.GoogleAdSense
		 * @private
		 * @param {SIMAD.Ad} ad Ad object
		 * @param {Array} googleAds Array of delivered google ads.
		 */
		__defaultOnRenderCallback: function(ad, googleAds) {
			SIMAD.Log.log("GoogleAdSense", "Got following ad into the default onRenderCallback", {"ad": ad, "googleAds": googleAds});
			var s = '';
			if (googleAds.length > 0) {
				switch(googleAds[0].type) {
					case 'text':
						for (var i = 0; i < googleAds.length; i++) {
							s += '<div class="adword" style="border: 1px solid red; margin-bottom: 5px"><h4><a href="' + googleAds[i].url + '" target="_top">' + googleAds[i].line1 + '</a></h4><p>' + googleAds[i].line2 + '</p><p><a href="' + googleAds[i].url + '" target="_blank">' + googleAds[i].visible_url + '</a></p></div>';
						}
					break;
					case 'image':
						for (var i = 0; i < googleAds.length; i++) {
							s += '<a href="' +
							googleAds[i].url + '" target="_top" title="go to ' +
							googleAds[i].visible_url + '"><img border="0" src="' +
							googleAds[i].image_url + '"width="' +
							googleAds[i].image_width + '"height="' +
							googleAds[i].image_height + '"></a>';
						}
					break;
					case "flash":
						for (var i = 0; i < googleAds.length; i++) {
							s += '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' +
							' codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" WIDTH="' +
							googleAds[i].image_width + '" HEIGHT="' +
							googleAds[i].image_height + '"> <PARAM NAME="movie" VALUE="' +
							googleAds[i].image_url + '">' +
							'<PARAM NAME="quality" VALUE="high">' +
							'<PARAM NAME="AllowScriptAccess" VALUE="never">' +
							'<EMBED src="' +
							googleAds[i].image_url + '" WIDTH="' +
							googleAds[i].image_width + '" HEIGHT="' +
							googleAds[i].image_height +
							'" TYPE="application/x-shockwave-flash"' +
							' AllowScriptAccess="never" ' +
							' PLUGINSPAGE="http://www.macromedia.com/go/getflashplayer"></EMBED></OBJECT>';
						}
					break;
					case "html":
						s += googleAds[i].snippet;
					break;
				}
			}
			return s;
		}
	});
}



if (SIMAD.Reloader && SIMAD.Reloader.ReplacementFrameReloader) {

	/**
	 * @class SIMAD.Reloader.GoogleAdSenseReloader
	 */
	SIMAD.Reloader.GoogleAdSenseReloader = SIMAD.Util.extend({}, SIMAD.Reloader.ReplacementFrameReloader);


	/**
	 * Name of the reloaders
	 *
	 * @memberOf SIMAD.Reloader.GoogleAdSenseReloader
	 * @private
	 * @type String
	 */
	SIMAD.Reloader.GoogleAdSenseReloader.__name = "GoogleAdSenseReloader";


	/**
	 * onIFrameAdRendered callback. Will be called from iframe just after the ad is rendered.
	 * It clears the iFrame and renders the google ad inside of placeholder or wrapper with innerHTML.
	 *
	 * @memberOf SIMAD.Reloader.GoogleAdSenseReloader
	 * @private
	 * @param {Event} event Event object
	 */
	SIMAD.Reloader.GoogleAdSenseReloader.__onIFrameAdRendered = function(event) {
		var ad = event.calledFromAd;
		SIMAD.Log.log("AdReload", "__onIFrameAdRendered() called for " + ad.getId());
		if (ad) {
			ad.unbindEvent('onIFrameAdFinished', '__onIFrameAdRendered');

			SIMAD.Reloader.GoogleAdSenseReloader.clean(ad);

			if (ad.getWrapper() === null && ad.getPlaceholder() !== null) {
				var placeholder = ad.getPlaceholder();
				if (placeholder && placeholder.nodeName) {
					var wrapperDiv = document.createElement('div');
					wrapperDiv.id = SIMAD.Core.getWrapperId(ad);
					placeholder.appendChild(wrapperDiv);
					ad.setWrapper(wrapperDiv);
				}
			}

			if (ad.getAdServerSpecific() && ad.getAdServerSpecific().GoogleAdSense && ad.getAdServerSpecific().GoogleAdSense.googleAds) {
				var renderCallback = ad.getOnRenderCallback() || SIMAD.AdServerAdapter.GoogleAdSense.__defaultOnRenderCallback;
				if (typeof(renderCallback) === 'function') {
					var googleAds = ad.getAdServerSpecific().GoogleAdSense.googleAds;
					var wrapper = ad.getWrapper() || ad.getPlaceholder();
					if (wrapper) {
						wrapper.innerHTML = renderCallback(ad, googleAds);
					}
				}
			}

			ad.setReloaded(true);

			ad.triggerEvent("afterReload");

			SIMAD.Core.reloadNextAd();
		}
	};
}
/**
* @fileoverview SIMAD Base CmsAdapter (Base)
*
*
* @author Benedikt Weiner, Gleb Kotov, Joachim Kuban
*
*
*/

if (typeof SIMAD !== 'undefined') {

	SIMAD.CmsAdapter = {
		config: function(params) {
			SIMAD.Core.setOriginalConfig(params);
			return SIMAD.Core.config(params);
		},

		init: function() {
			return SIMAD.Core.init();
		},

		preInit: function() {
			return SIMAD.Core.preInit();
		},

		postInit: function() {
			return SIMAD.Core.postInit();
		},

		doAd: function(adId, state) {
			return SIMAD.Core.__doAd(adId, state);
		},

		finalize: function() {
			return SIMAD.Core.__finalize();
		},

		reloadAds: function(adIds) {
			return SIMAD.Core.reloadAds(adIds);
		},

		getVideoAdRequest: function(args) {
			return SIMAD.Core.getVideoAdRequest(args);
		},

		getAd: function(adId) {
			return SIMAD.Core.getAd(adId);
		},

		getAds: function(filter) {
			return SIMAD.Core.getAds(filter);
		},

		addAd: function(ad) {
			return SIMAD.Core.addAd(ad);
		},

		updateConfig: function(params) {
			return SIMAD.Core.updateConfig(params);
		},

		getConfig: function() {
			return SIMAD.Core.getConfig();
		},

		hideAds: function() {
			return SIMAD.Core.hideAds();
		},

		showAds: function() {
			return SIMAD.Core.showAds();
		},

		newSession: function(json) {
			return SIMAD.Core.newSession(json);
		},

		closeSession: function(doNotClear) {
			return SIMAD.Core.closeSession(doNotClear);
		},

		bindEvent: function(eventName, eventId, eventFunc) {
			return SIMAD.Core.bindEvent(eventName, eventId, eventFunc);
		},

		unbindEvent: function(eventName, eventId) {
			return SIMAD.Core.unbindEvent(eventName, eventId);
		},


		/**
		* __getTLD
		*
		* Returns the top level domain
		*
		* @params params config JSON
		* @returns {String} tld
		*/
		__getTLD: function(params) {
			if (!this.__tld) {
				if (typeof(params.domain) === "string") {
					var arr = params.domain.split(".");
					this.__tld = arr[arr.length - 1];
				}
				var gets = SIMAD.Core.getLocationParams();
				if (gets && gets.simad_tld) {
					this.__tld = gets.simad_tld;
				}
			}
			return this.__tld;
		},

		configIFrame: function() {
			return SIMAD.Core.configInIFrame();
		},

		getAdInIFrame: function() {
			var out = SIMAD.Core.adInIFrame;
			if (!out) {
				out = {
					getId: function() {
						return "";
					}
				};
			}
			return out;
		}
	};

	SIMAD.CmsAdapter.CallbackFunctions = {
		map: {},

		registerFunction: function(adformat, eventname, afunction) {
			if (typeof(SIMAD.CmsAdapter.CallbackFunctions.map[adformat]) == "undefined") return;
			if (typeof(SIMAD.CmsAdapter.CallbackFunctions.map[adformat][eventname]) == "undefined") return;
			SIMAD.CmsAdapter.CallbackFunctions.map[adformat][eventname].push(afunction);
		},

		onAdReloadFinished: function(adformat, afunction) {
			if (typeof(afunction) == "function") {
				SIMAD.CmsAdapter.CallbackFunctions.registerFunction(adformat, SIMAD.Event.ADRELOAD, afunction);
			}
			return SIMAD.CmsAdapter.CallbackFunctions.map[adformat][SIMAD.Event.ADRELOAD];
		},
		beforeReload: function(adformat, afunction) {
			if (typeof(afunction) == "function") {
				SIMAD.CmsAdapter.CallbackFunctions.registerFunction(adformat, SIMAD.Event.BEFORE_RELOAD, afunction);
			}
			return SIMAD.CmsAdapter.CallbackFunctions.map[adformat][SIMAD.Event.BEFORE_RELOAD];
		},
		afterReload: function(adformat, afunction) {
			if (typeof(afunction) == "function") {
				SIMAD.CmsAdapter.CallbackFunctions.registerFunction(adformat, SIMAD.Event.RELOAD, afunction);
			}
			return SIMAD.CmsAdapter.CallbackFunctions.map[adformat][SIMAD.Event.RELOAD];
		},
		onRendered: function(adformat, afunction) {
			if (typeof(afunction) == "function") {
				SIMAD.CmsAdapter.CallbackFunctions.registerFunction(adformat, SIMAD.Event.RENDERED, afunction);
			}
			return SIMAD.CmsAdapter.CallbackFunctions.map[adformat][SIMAD.Event.RENDERED];
		},
		onLoad: function(adformat, afunction) {
			if (typeof(afunction) == "function") {
				SIMAD.CmsAdapter.CallbackFunctions.registerFunction(adformat, SIMAD.Event.LOAD, afunction);
			}
			return SIMAD.CmsAdapter.CallbackFunctions.map[adformat][SIMAD.Event.LOAD];
		},
		onIFrameAdStarted: function(adformat, afunction) {
			if (typeof(afunction) == "function") {
				SIMAD.CmsAdapter.CallbackFunctions.registerFunction(adformat, SIMAD.Event.BEFORE_IFRAMEAD, afunction);
			}
			return SIMAD.CmsAdapter.CallbackFunctions.map[adformat][SIMAD.Event.BEFORE_IFRAMEAD];
		},
		onIFrameAdFinished: function(adformat, afunction) {
			if (typeof(afunction) == "function") {
				SIMAD.CmsAdapter.CallbackFunctions.registerFunction(adformat, SIMAD.Event.IFRAMEAD, afunction);
			}
			return SIMAD.CmsAdapter.CallbackFunctions.map[adformat][SIMAD.Event.IFRAMEAD];
		},

		createMap: function() {
			for (var adformat in SIMAD.Format) {
				SIMAD.CmsAdapter.CallbackFunctions.map[SIMAD.Format[adformat]] = {};
				for (var eventname in SIMAD.Event) {
					SIMAD.CmsAdapter.CallbackFunctions.map[SIMAD.Format[adformat]][SIMAD.Event[eventname]] = [];
				}
			}
		}
	}
	SIMAD.CmsAdapter.CallbackFunctions.createMap();
}
/**
* @fileoverview SIMADCmsAdapter
*
*
* <p>Defines the public interface to the CMS</p>
*
* @author Benedikt Weiner, Gleb Kotov, Joachim Kuban
*
*
*/

if (typeof SIMAD !== 'undefined') {

	/**
	* doAdInstream
	*
	* Mapping function to the Core.doAd function
	*
	* @params {String} adId Id of the ad to render
	*/
	SIMAD.CmsAdapter.doAdInstream = function(adId) {
		this.doAd(adId, "inSlotBegin");
	};


	/**
	* finishAdInstream
	*
	* Mapping function to the Core.doAd function
	*
	* @params {String} adId Id of the ad to render
	*/
	SIMAD.CmsAdapter.finishAdInstream = function(adId) {
		this.doAd(adId, "inSlotEnd");
	};


	/**
	* doAdPoststream
	*
	* Mapping function to the Core.doAd function
	*
	* @params {String} adId Id of the ad to render
	*/
	SIMAD.CmsAdapter.doAdPoststream = function(adId) {
		this.doAd(adId, "outOfSlotBegin");
	};


	/**
	* finishAdPoststream
	*
	* Mapping function to the Core.doAd function
	*
	* @params {String} adId Id of the ad to render
	*/
	SIMAD.CmsAdapter.finishAdPoststream = function(adId) {
		this.doAd(adId, "outOfSlotEnd");
	};


	/**
	* setTaxonomy
	*
	* Mapping function to the Core.updateConfig function
	*
	* @params {Object} json JSON with the new taxonomy
	* @return {Object} SIMAD SIMAD itselfs
	*/
	SIMAD.CmsAdapter.setTaxonomy = function(params) {
		return this.updateConfig(this.__normalizeJSON1G(params));
	};


	/**
	* setProperty
	*
	* Mapping function to the Core.updateConfig function
	*
	* @params {String} prop Name of the property to set
	* @params {String} value Value of the property to set
	* @returns {Object} SIMAD SIMAD itselfs
	*/
	SIMAD.CmsAdapter.setProperty = function(prop, value) {
		var update = {};

		if (typeof(prop) === 'object') {
			update = this.__normalizeJSON1G(prop);

		} else if (typeof(prop) === 'string') {
			switch (prop) {
				case "debugLog":
					update.debug = {};
					update.debug.all = value;
				break;

				case "globalAdTagsLoading":
					var ads = SIMAD.Core.getAds();
					switch (value) {
						case SIMAD.Loading.INSTREAM:
							for (var i = 0; i < ads.length; i++) { ads[i].setLoading(SIMAD.Loading.INSTREAM); ads[i].activate(); }
						break;

						case SIMAD.Loading.POSTSTREAM:
							for (var i = 0; i < ads.length; i++) { ads[i].setLoading(SIMAD.Loading.POSTSTREAM); ads[i].activate(); }
						break;

						case SIMAD.Loading.ONEVENT:
							for (var i = 0; i < ads.length; i++) { ads[i].deactivate(); }
						break;

						case SIMAD.Loading.INDIVIDUAL:
							for (var i = 0; i < ads.length; i++) { ads[i].activate(); }
						break;
					}
				break;

				case "includedAdTypes":
					if (typeof(value) === 'object') {
						update = this.__normalizeJSON1G({
							"includedAdTypes": value
						});
					}
				break;

				default:
					update[prop] = value;
				break;
			}
		}

		return this.updateConfig(update);
	};


	/**
	* getProperty
	*
	* Mapping function to the Core.getConfig function
	*
	* @params {String} prop Name of the property to return
	* @returns {*} Value of the property
	*/
	SIMAD.CmsAdapter.getProperty = function(prop) {
		switch (prop) {
			case "globalAdTagsLoading":
				var activeAds = this.getAds(function(ad) { return ad.isActive(); } );
				if (this.getAds(function(ad) { return ad.isActive(); }).length === 0 && this.getAds().length > 0) {
					return SIMAD.Loading.ONEVENT;
				}
				if (this.getAds(function(ad) { return ad.getLoading() === SIMAD.Loading.POSTSTREAM; }).length === this.getAds().length && this.getAds().length > 0) {
					return SIMAD.Loading.POSTSTREAM;
				}

				if (this.getAds(function(ad) { return ad.getLoading() === SIMAD.Loading.INSTREAM; }).length === this.getAds().length && this.getAds().length > 0) {
					return SIMAD.Loading.INSTREAM;
				}

				return SIMAD.Loading.INDIVIDUAL;
			break;

			case "includedAdTypes":
				var dynamicAds = this.getConfig().dynamicAds;
				if (dynamicAds.include === "none" && dynamicAds.exceptOf && dynamicAds.exceptOf.length === 0) {
					return {
						"sowefo": false,
						"popup": false,
						"wallpaper": false,
						"powerbanner": false,
						"powerlayer": false,
						"powerrectangle": false
					};
				} else if (dynamicAds.include === "none" && dynamicAds.exceptOf && dynamicAds.exceptOf.length > 0) {
					var output = {
						"sowefo": true
					};
					var sowefos = {
						"popup": SIMAD.Format.POPUP_WINDOW,
						"wallpaper": SIMAD.Format.WALLPAPER,
						"powerlayer": SIMAD.Format.POWERLAYER,
						"powerbanner": SIMAD.Format.POWERBANNER,
						"powerrectangle": SIMAD.Format.POWERRECTANGLE
					};
					var j;
					var allow;
					for (var i in sowefos) {
						allow = false;
						for (j = 0; j < dynamicAds.exceptOf.length; j++) {
							if (sowefos[i] === dynamicAds.exceptOf[j]) { allow = true; }
						}
						output[i] = allow;
					}
					return output;
				} else if (dynamicAds.include === "all") {
					var output = {
						"sowefo": true
					};
					var sowefos = {
						"popup": SIMAD.Format.POPUP_WINDOW,
						"wallpaper": SIMAD.Format.WALLPAPER,
						"powerlayer": SIMAD.Format.POWERLAYER,
						"powerbanner": SIMAD.Format.POWERBANNER,
						"powerrectangle": SIMAD.Format.POWERRECTANGLE
					};
					var j;
					var allow;
					for (var i in sowefos) {
						allow = true;
						for (j = 0; j < dynamicAds.exceptOf.length; j++) {
							if (sowefos[i] === dynamicAds.exceptOf[j]) { allow = false; }
						}
						output[i] = allow;
					}
					return output;
				} else {
					return undefined
				}
			break;

			case "debugLog" :
				return SIMAD.Core.$s.debug.all;
			break;
		}
		return this.getConfig()[prop];
	};


	/**
	* setAdProperty
	*
	* Mapping function to the SIMAD.Ad setters
	*
	* @params {String} adId Id of the ad to modify
	* @params {String} prop Name of the property to set
	* @params {*} value Value of the property to set
	* @return {SIMAD.Ad|undefined} ad Ad, which was modified
	*/
	SIMAD.CmsAdapter.setAdProperty = function(adId, prop, value) {
		var ad = this.getAd(adId);
		if (ad) {
			switch (prop) {
				case "loading":
					if (value === SIMAD.Loading.ONEVENT) {
						ad.deactivate();
						ad.setLoading(SIMAD.Loading.INSTREAM);
					} else {
						ad.activate();
						ad.setLoading(value);
					}
				break;
				case "adTag":	 			ad.setFormat(value); break;
				case "onLoadCallback": 		ad.setOnLoadCallback(value); break;
				case "onRenderCallback": 	ad.setOnRenderCallback(value); break;
				case "placeholder":		 	ad.setPlaceholder(value); break;
			}
			return ad;
		}
		return undefined;
	};


	/**
	* getAdProperty
	*
	* Mapping function to the SIMAD.Ad getters
	*
	* @params {String} adId Id of the ad to get property from
	* @params {String} prop Name of the property to get
	* @returns {*} Value of the property
	*/
	SIMAD.CmsAdapter.getAdProperty = function(adId, prop) {
		var ad = this.getAd(adId);
		if (ad) {
			switch (prop) {
				case "loading":
					if (!ad.isActive()) {
						return SIMAD.Loading.ONEVENT;
					}
					return ad.getLoading();
				break;
				case "adTag":	 			return ad.getFormat(); break;
				case "onLoadCallback": 		return ad.getOnLoadCallback(); break;
				case "onRenderCallback": 	return ad.getOnRenderCallback(); break;
				case "placeholder":		 	return ad.getPlaceholder(); break;
			}
		}
		return undefined;
	};


	/**
	* addAdTag
	*
	* Mapping function to the addAd function
	*
	* @params {JSON} adTag JSON object with the parameters for a new ad
	* @returns {SIMAD.Ad|undefined} Created ad object
	*/
	SIMAD.CmsAdapter.addAdTag = function(adTag) {
		SIMAD.Log.log("input", "addAdTag() was called with", adTag);
		return this.addAd(adTag);
	};


	/**
	* addAd
	*
	* Mapping function to the addAd function
	*
	* @params {JSON} adTag JSON object with the parameters for a new ad
	* @returns {SIMAD.Ad|undefined} Created ad object
	*/
	SIMAD.CmsAdapter.addAd = function(adTag) {

		var json = { "adTagList": [adTag] };
		json = this.__normalizeJSON1G(json);

		var newAd;
		if (json.ads && json.ads[0]) {
			if (SIMAD.Util.filter(SIMAD.Core.getAds(), function(ad) { return !ad.isActive(); }).length === SIMAD.Core.getAds().length && SIMAD.Core.getAds().length > 0) {
				json.ads[0].active = false;
			}

			newAd = SIMAD.Core.addAd(new SIMAD.Ad(json.ads[0]));
			newAd.bindEvent("onLoad", "CMSonLoadCallback", this.__callOnloadCallbackFunction);
		}

		return newAd;
	};

	/**
	 * __callOnloadCallbackFunction
	 *
	 * This functions calles the Ad onLoadCallback and enshures that the Ad Object appears as a adTag from SIMAD 1G
	 * I make the following backwards compatibiliy properties avalibe
	 * { "id":
	 * 	 "loading":
	 * 	 "adTag":
	 */

	SIMAD.CmsAdapter.__callOnloadCallbackFunction= function(eventObject){
		var ad = eventObject.calledFromAd;
		var onLoadCallback = ad.getOnLoadCallback();
		if (typeof(onLoadCallback) === 'function') {
			var simad1gAd = ad;
			if(simad1gAd.isActive()){
				simad1gAd.loading = ad.getLoading();
			}else{
				simad1gAd.loading = SIMAD.Loading.ONEVENT;
			}
			simad1gAd.id = ad.getId();
			simad1gAd.adTag = ad.getFormat();

			onLoadCallback(simad1gAd);

			delete simad1gAd.id;
			delete simad1gAd.adTag;
			delete simad1gAd.loading;
		}
	};




	/**
	* __normalizeJSON1G
	*
	* Converts the JSON 1G to the JSON 2G or a part of it
	*
	* @params {Object} json JSON in format 1G
	* @returns {Object} json JSON in format 2G
	*
	* TODO write Test for this function
	*/
	SIMAD.CmsAdapter.__normalizeJSON1G = function(json) {
		if (json) {
			json = SIMAD.Util.extend({}, json);

			if (typeof(json.adTagList) !== 'undefined') {
				json.ads = json.adTagList.slice();
				delete json.adTagList;
			}

			if (typeof(json.debugLog) !== 'undefined') {
				json.debug = {"all": json.debugLog};
				delete json.debugLog;
			}

			if (typeof(json.ads) !== 'undefined') {
				for (var i = 0; i < json.ads.length; i++) {
					if (typeof(json.ads[i].adTag) !== 'undefined') {
						json.ads[i].format = json.ads[i].adTag;
						delete json.ads[i].adTag;
					}
					if (typeof(json.ads[i].active) === 'undefined') {
						json.ads[i].active = true;
					}
					if (json.ads[i].loading === SIMAD.Loading.ONEVENT) {
						json.ads[i].loading = SIMAD.Loading.POSTSTREAM;
						json.ads[i].active = false;
					}
				}
			}

			if (typeof(json.includedAdTypes) !== 'undefined') {
				if (json.includedAdTypes.sowefo === false) {
					json.dynamicAds = {"include": "none", "exceptOf": []};
				} else {
					if (!json.dynamicAds) { json.dynamicAds = {"include": "all", "exceptOf": [] }; }
					var sowefos = {
						"popup": SIMAD.Format.POPUP_WINDOW,
						"wallpaper": SIMAD.Format.WALLPAPER,
						"powerlayer": SIMAD.Format.POWERLAYER,
						"powerbanner": SIMAD.Format.POWERBANNER,
						"powerrectangle": SIMAD.Format.POWERRECTANGLE
					};

					for (var i in json.includedAdTypes) {
						var adExists = false;

						if (sowefos[i] && json.includedAdTypes[i] === false) {
							json.dynamicAds.exceptOf.push(sowefos[i]);
						}
					}
				}
				delete json.includedAdTypes;
			}

			if (typeof(json.globalAdTagsLoading) !== 'undefined') {
				switch (json.globalAdTagsLoading) {
					case SIMAD.Loading.INSTREAM:
					case SIMAD.Loading.POSTSTREAM:
						for (var i = 0; i < json.ads.length; i++) {
							json.ads[i].loading = json.globalAdTagsLoading;
						}
					break;

					case SIMAD.Loading.ONEVENT:
						for (var i = 0; i < json.ads.length; i++) {
							json.ads[i].active = false;
						}
					break;
				}
				delete json.globalAdTagsLoading;
			}

			if (typeof(json.video) !== 'undefined' && typeof(json.video.availableAdTags) !== 'undefined') {
				json.video.adFilter = SIMAD.Util.extend(true, {}, json.video.availableAdTags);
				json.video.adFilter.all = json.video.adFilter.videoAds;
				delete json.video.availableAdTags;
				delete json.video.adFilter.videoAds;
			}


			if (typeof(json.adserverSpecific) !== 'undefined') {
				json.adServerSpecific = {};
				var adServer = this.__getUsedAdServer(json);
				if (adServer) {
					json.adServerSpecific[adServer] = SIMAD.Util.extend(true, {}, json.adserverSpecific);
				} else {
					SIMAD.Log.warn("No used adserver found.");
				}
				delete json.adserverSpecific;
			}
		}

		return json;
	};
}
/**
* @fileoverview SIMADCmsAdapter
*
*
* <p>Defines the public interface to the CMS</p>
*
* @author Benedikt Weiner, Gleb Kotov, Joachim Kuban
*
*
*/

if (typeof SIMAD !== 'undefined' && typeof(SIMAD.CmsAdapter) !== 'undefined') {

  SIMAD.CmsAdapter.adjustLayout = function(info) {

		var ad = info.calledFromAd;

		var adFormat = ad.getFormat();
		var adserverFormat = ad.getAdServerFormat();

		var dimensions = ad.getDimensions();
		var width  = dimensions[0];
		var height = dimensions[1];

		var exists = ad.isDelivered();

		switch (adFormat) {
			case SIMAD.Format.FULLBANNER:
				if (window.SoiAd && SoiAd.isBillboard(adserverFormat)) {
					var billboardId = ad.getWrapper().id+"-billboard";
					var billboardContainer = document.getElementById(billboardId);
					if (!billboardContainer) return;

					billboardContainer.style.display = 'block';
					billboardContainer.style.width   = width + 'px';
					billboardContainer.style.height  = height + 'px';

					var class_name = 'ad';
					if (width <= 956) class_name += ' shadow round_bottom background';
					billboardContainer.className = class_name;

					var cssText = '#ad-fullbanner-outer {min-height: 0px;}\n';

					var billboardContainerOuter = document.getElementById(billboardId+"-outer");
					if (billboardContainerOuter) {
						var maxWidth = parseInt(SoiQuery.getCurrentStyle(billboardContainerOuter, 'width')) || 0;
						if (maxWidth) {
							var delta =  parseInt((maxWidth - width) / 2);
							if (delta > 1) {
								billboardContainer.style.paddingLeft  = delta + 'px';
								billboardContainer.style.paddingRight = (maxWidth - width - delta) + 'px';
							}
							else if (delta < -1) {
								billboardContainer.style.marginLeft = delta + 'px';
								cssText += '#ad-right {left:' + (970 - delta) + 'px;}\n';
							}
						}
					}
					if (cssText) SoiUtils.addStyleElement(cssText);
				}
			break;
			case SIMAD.Format.MEDIUMRECTANGLE:
        var outer = document.getElementById('ad-rectangle');
				if (outer) {
					if (!exists) {
					  try {
	  					if (SIMAD.Core.getConfig().cmsSpecific.marketingCluster == "home") {
  						  outer.innerHTML = "<a id='rectangleFallbackHome' href='/tv/die-harald-schmidt-show/video'></a>";
  						} else {
  						  outer.style.display = 'none';
  						}
  					} catch (err) {
  						  outer.style.display = 'none';
  					}
					}
					else if (outer.style.display == 'none') { // re-set possible 'none' value after ad-reload
						outer.style.display = 'block';
					}
					if (window.SoiAd) {
						var is_halfpage = SoiAd.isHalfpage(adserverFormat);
						var node = outer;
						while (node = node.nextSibling) {
						  break;
							if (node.nodeType != 1) continue;
							if (String(node.className).match(/(?:^| )grid_300(?:$| )/)) {
								if (is_halfpage) {
									node.style.display = 'none';
								}
								else if (node.style.display == 'none') { // re-set possible 'none' value after ad-reload
									node.style.display = 'block';
								}
								break;
							}
						}
					}
				}
			break;
		}
	};

	if (typeof(SIMAD.CmsAdapter.CallbackFunctions) != "undefined") {
		SIMAD.CmsAdapter.CallbackFunctions[SIMAD.Event.RENDERED](SIMAD.Format.POPUP, SIMAD.CmsAdapter.adjustLayout);
		SIMAD.CmsAdapter.CallbackFunctions[SIMAD.Event.RENDERED](SIMAD.Format.FULLBANNER, SIMAD.CmsAdapter.adjustLayout);
		SIMAD.CmsAdapter.CallbackFunctions[SIMAD.Event.RENDERED](SIMAD.Format.SKYSCRAPER, SIMAD.CmsAdapter.adjustLayout);
		SIMAD.CmsAdapter.CallbackFunctions[SIMAD.Event.RENDERED](SIMAD.Format.MEDIUMRECTANGLE, SIMAD.CmsAdapter.adjustLayout);
	};

	SIMAD.CmsAdapter.shoppingTippOnRender = function(ad, data) {
	  var html = '<article class="teaser clearfix trackable_teaser" style="overflow:hidden;height:120px; width:270px;margin-bottom:10px;"><header>' +
  		'<h3><a href="' + data.linkHref + '" class="" target="_blank">Shopping Tipp</a></h3>' +
  		'</header><figure>' +
  			'<a href="' + data.linkHref + '" class="" target="_blank">' +
  				'<img alt="' + data.teaserHeadline + '" src="' + data.imageURL + '" height="79" width="140" />' +
  				'<span style="display: none;" class="caption"></span>' +
  			'</a>' +
  		'</figure>' +
    	'<h4>' + data.teaserHeadline + '</h4>' +
  		'<span class="txt">' + data.teaserText + '</span>' +
  		'<footer>' +
  		  '<a class="arrow" href="' + data.linkHref + '" target="_blank">' + data.linkText + '</a>' +
  		'</footer></article>';
    return html;
	}

	SIMAD.CmsAdapter.adSenseOnLoad = function(ad) {
	  try {
  		if (ad.__wrapper.getElementsByTagName("article").length > 0) {
  			ad.__wrapper.parentNode.style.display = "block";
  		} else {
  			ad.__wrapper.parentNode.parentNode.parentNode.style.display = "none";
  		}
  	} catch (err) {}
	};

	SIMAD.CmsAdapter.adSenseOnRender = function(ad, googleAds) {
	  var s = '';
  	if (googleAds.length > 0) {
  		switch(googleAds[0].type) {
  			case 'text':
  				for (var i = 0; i < googleAds.length; i++) {
  					s += '<article class="teaser teaser_imagetext format_class clearfix"><header><h3><a href="' + googleAds[i].url + '" target="_top">' + googleAds[i].line1 + '</a></h3></header>' + googleAds[i].line2 + '<footer><a class="arrow" href="' + googleAds[i].url + '" target="_blank">' + googleAds[i].visible_url + '</a></footer></article>';
  				}
  			break;
  			case 'image':
  				for (var i = 0; i < googleAds.length; i++) {
  					s += '<a href="' +
  					googleAds[i].url + '" target="_top" title="go to ' +
  					googleAds[i].visible_url + '"><img border="0" src="' +
  					googleAds[i].image_url + '"width="' +
  					googleAds[i].image_width + '"height="' +
  					googleAds[i].image_height + '"></a>';
  				}
  			break;
  			case "flash":
  				for (var i = 0; i < googleAds.length; i++) {
  					s += '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' +
  					' codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" WIDTH="' +
  					googleAds[i].image_width + '" HEIGHT="' +
  					googleAds[i].image_height + '"> <PARAM NAME="movie" VALUE="' +
  					googleAds[i].image_url + '">' +
  					'<PARAM NAME="quality" VALUE="high">' +
  					'<PARAM NAME="AllowScriptAccess" VALUE="never">' +
  					'<EMBED src="' +
  					googleAds[i].image_url + '" WIDTH="' +
  					googleAds[i].image_width + '" HEIGHT="' +
  					googleAds[i].image_height +
  					'" TYPE="application/x-shockwave-flash"' +
  					' AllowScriptAccess="never" ' +
  					' PLUGINSPAGE="http://www.macromedia.com/go/getflashplayer"></EMBED></OBJECT>';
  				}
  			break;
  			case "html":
  				s += googleAds[i].snippet;
  			break;
  		}
  	}
  	return s;
	};


	/**
	 * adjust the vidoe.adFilter setting from CMS imported form the videoDB to the internal
	 * adFilter settings
	 * @private
	 */
	SIMAD.CmsAdapter.__adjustVideoDBadFilter = function(adFilter){
		var adjustedAdFilter = {};

		adjustedAdFilter.overlay =  !adFilter.overlay;
		adjustedAdFilter.midroll =  !adFilter.midroll;

		if (adFilter.all) {
			adjustedAdFilter.all = false;
			adjustedAdFilter.preroll  = false;
			adjustedAdFilter.postroll = false;
			adjustedAdFilter.sponsor =  false;
			adjustedAdFilter.midroll = false;
			adjustedAdFilter.overlay = false;
		} else {
			adjustedAdFilter.all = true;
			adjustedAdFilter.preroll  = true;
			adjustedAdFilter.postroll = true;
			adjustedAdFilter.sponsor =  true;
		}
		return adjustedAdFilter;
	};

	SIMAD.CmsAdapter.config = function(params) {
	  var rectangleDisabled = false;
	  for (var i=0; i<params.ads.length; i++) {
	    if (params.ads[i].id == "rectangle") {
	      rectangleDisabled = !params.ads[i].active;
	    }
	  }
	  if (params.adFree || rectangleDisabled) {
  	  var rectangle_css = document.createElement('style');
  		rectangle_css.type = 'text/css';
  		rectangle_css.id = "SIMAD_rectangle_s1_additionalStyles";
  	  document.getElementsByTagName('head')[0].appendChild(rectangle_css);
  	  if (rectangle_css.styleSheet) {
  			rectangle_css.styleSheet.cssText = "#ad-rectangle.ad {margin-bottom:0; min-height:0;}";
  		} else {
  			rectangle_css.appendChild(document.createTextNode("#ad-rectangle.ad {margin-bottom:0; min-height:0;}"));
  		};
  	}

		if (params.dynamicAds.include == "all") {
 			params.dynamicAds.exceptOf.push(SIMAD.Format.POWERRECTANGLE);
		};
		if (params.channel != "home" && params.subchannel1 == "") {
		  params.subchannel1 = "home";
		};
		if (params.channel != "home" && params.cmsSpecific.marketingCluster == "home") {
		  params.cmsSpecific.marketingCluster = "other";
		};
		switch (params.subchannel1) {
		  case "navy-cis":
		  case "navy-cis-la":
		  case "the-mentalist":
		  case "hawaii-five-0": params.cmsSpecific.contentCluster = "usformate"; break;
		};

		SIMAD.Core.setOriginalConfig(params);
		SIMAD.Log.log("config CMS", "config() was called with", params);
		params = this.__normalizeJSON1G(params);

		params.contentType = this.__mapContentType(params.contentType);

		if (!params.adServerSpecific) { params.adServerSpecific = {}; }
		if (!params.adServerSpecific[this.__getUsedAdServer(params)]) { params.adServerSpecific[this.__getUsedAdServer(params)] = {}; }

		switch (this.__getTLD(params)) {
			case "at":
				params.adServerSpecific[this.__getUsedAdServer(params)].domainId = 'sat1at';
			break;

			case "ch":
				params.adServerSpecific[this.__getUsedAdServer(params)].domainId = 'sat1ch';
			break;

			case "de":
			default:
				params.adServerSpecific[this.__getUsedAdServer(params)].domainId = 'sat1de';
				params.adServerSpecific[this.__getUsedAdServer(params)].siteSpecificJS = 'http://ad.71i.de/global_js/Sites/sat1de.js';
			break;
		}

		var normalizeLetters = ["&"];
		if (params.cmsSpecific) {
		  if (params.cmsSpecific.marketingCluster == undefined || params.cmsSpecific.marketingCluster == "") {
    			params.cmsSpecific.marketingCluster = "other";
		  } else {
			  params.cmsSpecific.marketingCluster = params.cmsSpecific.marketingCluster.toLowerCase();
  			for (var i=0; i < normalizeLetters.length; i++) {
  				params.cmsSpecific.marketingCluster = params.cmsSpecific.marketingCluster.split(normalizeLetters[i]).join("_");
  			}
  		}
		} else {
		}
		if (params.channel == "" && params.subchannel1 == "" && params.subchannel2 == "") {
			params.cmsSpecific.marketingCluster = "home";
		}


		if (!params.adServers) { params.adServers = []; }
		params.adServers.push(this.__getUsedAdServer(params));


		if (params.video) {

			params.video.__setByCMS = true;


			if (params.video.__adServer === undefined) {
				params.video.__adServer = this.__getUsedAdServer(params);
			}

			if(params.video.player){
				params.contentType = this.__mapContentType(params.video.player); // expects CPplayer or LivePlayer
			}
			if (params.video.adFilter && params.contentType === SIMAD.ContentType.VIDEO) {
				params.video.adFilter =  this.__adjustVideoDBadFilter(params.video.adFilter);

				if (params.video.type === "short") { params.video.adFilter.midroll = false; }

				if(!params.video.adFilter.all){// no ads if no videoads are allowed
					params.adFree = true;
					params.dynamicAds.include = "none";
					params.dynamicAds.exceptOf = [];
				}

			} else {
				SIMAD.Log.warn("The content type of the page with inline video metadata is not CPplayer");
			}
			if(params.video.path){
				var pathArray = [];
				pathArray.push("vplayer");
				if (params.video.type) {
					pathArray.push(params.video.type);
				}

				if(params.video.clip_id){
					pathArray.push(params.video.clip_id);
				}
				pathArray.push("pageplayer");
				var channelArray = [ "subchannel2", "subchannel3", "subchannel4", "subchannel5"]; //don't overwrite channel and subchannel1 use from cms
				for (var iPath = 0 ; (iPath < pathArray.length && iPath < channelArray.length ); iPath ++) {
					params[channelArray[iPath]] = pathArray[iPath]; // conferts the path into the chanel and subchanels
				}
			}
		}

		params.adServers.push("GoogleAdSense");
		params.adServerSpecific.GoogleAdSense = {
			google_ad_client: 'ca-pub-5757951654675015',
			google_ad_output: 'js',
			google_feedback: 'on'
		};
		for (var i = 0; i < params.ads.length; i++) {
			if (params.ads[i].format === SIMAD.Format.ADSENSETEXT && params.ads[i].adServer === undefined) {
				params.ads[i].adServer = "GoogleAdSense";
			}
		}



		if (params.staticIFrameLocation === undefined) { params.staticIFrameLocation = "/adserver/staticiframe.html"; }

		var configReturn = SIMAD.Core.config(params);

		var ads = SIMAD.getAds();
		for (var index = 0; index < ads.length; index++) {
			ads[index].bindEvent("onLoad", "CMSonLoadCallback", this.__callOnloadCallbackFunction);
			for (var events in SIMAD.Event) {
				var functions = SIMAD.CmsAdapter.CallbackFunctions[SIMAD.Event[events]](ads[index].getFormat());
				if (functions.length > 0) {
					for (var x = 0; x < functions.length; x++) {
						ads[index].bindEvent(SIMAD.Event[events],
											ads[index].getFormat() + "_" + SIMAD.Event[events] + "_" + x,
											functions[x]);
					}
				}
			}
		}
		return configReturn;

	};
	/**
	 * __getGoogleChannel builds the google Channel value acording to the CMS specific needs
	 */
	SIMAD.CmsAdapter.__getGoogleChannel = function(ad){
		var config = SIMAD.Core.getConfig();
		var formatList = [];
		var channel = [];
		var channelId;
		if (SIMAD.Util.inArray(formatList, config.subchannel1)) {
			channelId = config.subchannel1 + "_" + "AdSense" + "_";

		} else {
			channelId = config.cmsSpecific.marketingCluster + "_" + "AdSense" + "_";
		}
		channelId = channelId.slice(0,1).toUpperCase() + channelId.slice(1);
		channel.push(channelId + "Gesamt");
		channel.push(channelId + ad.getId());
		channel.push("Gesamt_" + ad.getId());
		return channel.join(",");
	};

	/**
	 * __getOASTaxonomyString can change / ajust the OAS Taxonomy value after it was genarate after the default patter in the OAS Adserver Adapter.
	 * called by the OAS Adserver Adapter
	 * @param {String} taxonomyString the OAS taxonomy string genarated the default patter in the OAS Adserver Adapter.
	 * @returns {String} taxonomy String after it was modified
	 */
	SIMAD.CmsAdapter.__getOASTaxonomyString = function(taxonomyString) {
		var patt=/[sat1ch|sat1at]\/lifestyle\/sendungen\/germanys_next_topmodel/;
		if (patt.exec(taxonomyString)){
			taxonomyString  = taxonomyString+ "/home";
		}
		return taxonomyString;

	};

	SIMAD.CmsAdapter.reloadAds = function(params) {

		if (params === undefined) {
			params = {};
		} else if (params.length !== undefined) {
			params = {
				ads: params
			};
		}

		switch (SIMAD.Core.getConfig().contentType) {
			case SIMAD.ContentType.VIDEO:
			case SIMAD.ContentType.RICH_VIDEO:
				var adsToActivate = SIMAD.Core.getAds(function(ad) { return ad.getFormat() === SIMAD.Format.SKYSCRAPER || ad.getFormat() === SIMAD.Format.FULLBANNER; });
				for (var i = 0; i < adsToActivate.length; i++) {
					adsToActivate[i].activate();
				}
			break;
			case SIMAD.ContentType.VIDEO_OVERVIEW:
				var skyscrapers = SIMAD.Core.getAds(function(ad) {return ad.getFormat() === SIMAD.Format.SKYSCRAPER});
				for (var i = 0; i < skyscrapers.length; i++) {
					skyscrapers[i].deactivate().clear();
					skyscrapers[i].triggerEvent("onLoad");
				}
				var adsToActivate = SIMAD.Core.getAds(function(ad) { return ad.getFormat() === SIMAD.Format.FULLBANNER; });
				for (var i = 0; i < adsToActivate.length; i++) {
					adsToActivate[i].activate();
				}
			break;

			case SIMAD.ContentType.GALLERY_IMAGE:
				params.force = false;
			break;
		}

		SIMAD.Core.reloadAds(params);
	};


	SIMAD.CmsAdapter.updateConfig = function(params) {

		if (params.cmsSpecific) {
			params.cmsSpecific.marketingCluster = this.__mapMarketingCluster(params.cmsSpecific.marketingCluster);
		}

		if (typeof params.contentType === "string") {
			params.contentType = this.__mapContentType(params.contentType);
		}
		return SIMAD.Core.updateConfig(params);
	};

 	SIMAD.CmsAdapter.insertBillboardContainer = function() {
  	if (!SIMAD.Core.allowDynamicAd(SIMAD.Format.BILLBOARD)) {
  	  return;
  	}
		var source_id = "SIMAD_wrapper_fullbanner";
		document.write(
				  '<div id="' + source_id + '-billboard-outer">'
					+ '<div id="' + source_id + '-billboard" style="display:none"><\/div>'
				+ '<\/div>'
			);
	};


	SIMAD.CmsAdapter.getConfig = function() {
		var config = SIMAD.Core.getConfig();

		config.contentType = this.__mapContentType(config.contentType, true);

		return config;
	};


	/**
	* __mapMarketingCluster
	*
	* Converts the marketingcluster form "np.cat.marketingcluster.comedy" into a format without leading "np.cat.marketingcluster." -> comedy
	*
	* @params {String} mc MarketingCluster of prosieben format
	* @returns {String} mc MarketingCluster of SOI/OAS Standard
	*/
	SIMAD.CmsAdapter.__mapMarketingCluster = function (mc) {
		if (typeof mc === "string") {
			var mcArray = mc.split(".");
			 mc = mcArray[mcArray.length - 1];
		}
		return mc;
	};


	/**
	* __mapContentType
	*
	* Map the Prosieben content type to the SIMAD internal content type. By setting the option "revers" to true, the mapping will be done in revers direction (internal to Prosieben)
	*
	* @params {String} contentType Prosieben content type
	* @params {boolean} revers Revers the mapping direction (internal to Prosieben)
	* @returns {boolean} contentType Internal content type
	*/
	SIMAD.CmsAdapter.__mapContentType = function (contentType, revers) {
		var map = [];
		/*map["np.cat.mediatyp.home"] 					= SIMAD.ContentType.HOME;
		map["np.catdimension.mediatyp.teaserhome"]		= SIMAD.ContentType.HOME;
		map["MCcontent"]								= SIMAD.ContentType.VIDEO_OVERVIEW;
		map["np.cat.mediatyp.mediacenter.video"] 		= SIMAD.ContentType.RICH_VIDEO;
		map["MCplayer"] 								= SIMAD.ContentType.RICH_VIDEO;
		map["np.cat.mediatyp.videopage"] 				= SIMAD.ContentType.VIDEO;
		map["np.cat.mediatyp.videoplayerpage"] 			= SIMAD.ContentType.VIDEO;
		map["np.cat.mediatyp.videofullepisodeplayerpage"]=SIMAD.ContentType.VIDEO;
		map["LivePlayer"]								=SIMAD.ContentType.VIDEO; //no specila livestream site zone at prosieben*/
		map["CPplayer"] 								= SIMAD.ContentType.VIDEO;
		/*map["np.cat.mediatyp.ugc"] 						= SIMAD.ContentType.COMMUNITY;
		map["np.cat.mediatyp.gallery"] 					= SIMAD.ContentType.GALLERY;
		map["gallery_zoom"] 							= SIMAD.ContentType.GALLERY_IMAGE;
		map["np.catdimension.mediatyp.game"] 			= SIMAD.ContentType.GAME;
		map["np.catdimension.mediatyp.shop"] 			= SIMAD.ContentType.SHOP;
		map["np.catdimension.mediatyp.gewinnspiel"] 	= SIMAD.ContentType.RAFFLE;
		map["error"] 									= SIMAD.ContentType.ERROR;
		if (revers) {
			for (var i in map) {
				if (map[i] === contentType){ return i;}
			}
			return "np.catdimension.mediatyp.content";
		} else {
			return (typeof map[contentType] !== "undefined") ? map[contentType] : SIMAD.ContentType.DEFAULT;
		}*/
		return (typeof map[contentType] !== "undefined") ? map[contentType] : contentType;
	};


	/**
	* __getUsedAdServer
	*
	* Return "OAS" or "SOI" accourding to the TLD
	*
	* @params params config JSON
	* @returns boolean
	*/
	SIMAD.CmsAdapter.__getUsedAdServer = function(params) {
		if (!this.__usedAdServer) {
			switch (this.__getTLD(params).toLowerCase()) {
				case "ch":
				case "at":
					this.__usedAdServer = 'OAS';
				break;

				case "de":
				default:
					this.__usedAdServer = 'SOI';
				break;
			}
		}

		return this.__usedAdServer;
	};
}
/**
*
* SIMAD.SIMAD.VideoAdapter
*
* @namespace SIMAD.VideoAdapter
* @member SIMAD.VideoAdapter
*
*/

if (typeof SIMAD === 'undefined') {
	SIMAD = {};
}

if (typeof SIMAD.VideoAdapter === "undefined") {
	SIMAD.VideoAdapter = {};
}

/**
*
* @namespace SIMAD.VideoAdapter.AdBridge
*
* SIMAD.VideoAdapter.AdBridge is the AdLayer component which implements the API to the VidoePlayer 2.0 AdBridge
*
*/
SIMAD.VideoAdapter.AdBridge = {

/**
 * @private
 * JSON transform function to get the AdBridge JSON into the AdLayer internal object structure
 * @param {JSON} newTaxonomy
 */
	__mapAdBrideJsonToSIMADJson: function(newTaxonomy){
		var tempTaxonomy = {
				video: {}
		};

		if (newTaxonomy) {
			if (newTaxonomy["triggered_for"]) {
				tempTaxonomy.contentType = newTaxonomy["triggered_for"];
				switch (tempTaxonomy.contentType) {
						case "MCplayer":
						case "CPplayer":
							tempTaxonomy.video.availableAdTags = {
								videoAds: true,
								preroll: true,
								postroll: true,
								midroll: true,
								overlay: true,
								sponsor: true,
								pauseroll: true
							};
						break;

						case "MCcontent":
							tempTaxonomy.video.availableAdTags = {
								videoAds: false,
								preroll: false,
								postroll: false,
								midroll: false,
								overlay: false,
								sponsor: false,
								pauseroll: false
							};
						break;

					}

				tempTaxonomy.video.player = newTaxonomy["triggered_for"];
			}

			if (newTaxonomy["path"]) {

				tempTaxonomy.video.path = newTaxonomy["path"];

				var pathArray = newTaxonomy["path"].split("/");
				if (pathArray.length > 0 && pathArray[0] === "" ) {
					pathArray.shift();
				}

				var channelArray = ["channel", "subchannel1", "subchannel2", "subchannel3", "subchannel4", "subchannel5"];
				for (var iPath = 0 ; (iPath < pathArray.length && iPath < channelArray.length ); iPath ++) {
					tempTaxonomy[channelArray[iPath]] = pathArray[iPath]; // conferts the path into the chanel and subchanels
				}
			}

			if (newTaxonomy["marketingCluster"]) {
				tempTaxonomy.cmsSpecific = {};
				tempTaxonomy.cmsSpecific.marketingCluster = newTaxonomy["marketingCluster"];

			}

			if (newTaxonomy["video_type"]) {
				tempTaxonomy.video.type = newTaxonomy["video_type"];
			}


			if (tempTaxonomy.contentType === "CPplayer" || tempTaxonomy.contentType === "MCplayer") {
				tempTaxonomy.video.availableAdTags = {};

				if (newTaxonomy["ad_exclude_all"] === 1 ||
					newTaxonomy["ad_exclude_all"] === "1" ||
					newTaxonomy["ad_exclude_all"] === true) {
						tempTaxonomy.video.availableAdTags.videoAds = false;
						tempTaxonomy.video.availableAdTags.preroll  = false;
						tempTaxonomy.video.availableAdTags.postroll = false;
						tempTaxonomy.video.availableAdTags.sponsor =  false;
				} else {
					tempTaxonomy.video.availableAdTags.videoAds = true;
					tempTaxonomy.video.availableAdTags.preroll  = true;
					tempTaxonomy.video.availableAdTags.postroll = true;
					tempTaxonomy.video.availableAdTags.sponsor =  true;
				}



				if (newTaxonomy["ad_exclude_midroll"] === 1 ||
				   newTaxonomy["ad_exclude_midroll"] === "1" ||
				   newTaxonomy["ad_exclude_midroll"] === true ||
				   tempTaxonomy.video.availableAdTags.videoAds === false) {
						tempTaxonomy.video.availableAdTags.midroll = false;
				} else {
					tempTaxonomy.video.availableAdTags.midroll = true;
				}

				if (newTaxonomy["ad_exclude_overlays"] === 1 ||
					newTaxonomy["ad_exclude_overlays"] === "1" ||
					newTaxonomy["ad_exclude_overlays"] === true ||
				    tempTaxonomy.video.availableAdTags.videoAds === false) {
						tempTaxonomy.video.availableAdTags.overlay = false;
				} else {
						tempTaxonomy.video.availableAdTags.overlay = true;
				}

				if (newTaxonomy["video_type"] === "short") {
					 	tempTaxonomy.video.availableAdTags.midroll = false;
				}


			}

			tempTaxonomy.video.__adServer = SIMAD.CmsAdapter.__getUsedAdServer();

			tempTaxonomy = SIMAD.Util.extend(true, tempTaxonomy, this.__mapCallbackFunctionToSIMADJson(newTaxonomy));
		}
		return tempTaxonomy;
	},


	__mapCallbackFunctionToSIMADJson: function(tax) {
		var output = { video: {} };

		output.video.onLoadCallback = tax["callback_function"];

		output.video.objectForOnLoadCallback = (tax["callback_id"]) ? document.getElementById(tax["callback_id"]) : undefined;

		return output;
	},



	/**
	* this function is called by the AdBridge and hands over the Video Metadata to the AdLayer.
	* It also starts an adreload of all banner ads on the page.
	* <br />
	* It receives the callback_function and callback_id parameter which are used to inform the AdBridge that the Adserver is initialised
	* and getVideoAdRequest functionscalls are allowed now. It calles the callback_function on the DOM Element with the ID callback_id
	*
	* @param {JSON}  newTaxonomy
	*
	* Example object form video AdBride
	* @example
	* var updateAdJSON = {
	*	"ad_exclude_all": "0",
	*	"ad_exclude_midroll": "0" ,
	*	"ad_exclude_overlays": "0",
	*	"callback_function": "callbackFunctionName",
	*	"callback_id": "DOMElementIdWhereCallbackFunctionIsCalledOn" ,
	*	"path": "/video/path/with/more/levels",
	*	"screen_mode": "normal" ,
	*	"triggered_for": "MCplayer" ,
	*	"video_type": "short" ,
	*	"marketingCluster" : "commedy"
	*	};
	* SIMAD.VideoAdapter.AdBridge.updateAds(updateAdJSON);
	* <p />
	*/
	updateAds: function(newTaxonomy) {
		SIMAD.Log.log("Video", "updateAds called in video adapter with", newTaxonomy);

		var config = SIMAD.getConfig();

		var originalConfig = SIMAD.Core.getOriginalConfig();
		if(originalConfig && originalConfig.video && originalConfig.video.adFilter){
			if(SIMAD.CmsAdapter.__getUsedAdServer() === "SOI"){
				var vidoeAdConfigStr = "contentType=" + originalConfig.contentType +
										",adFree=" 	+ originalConfig.adFree +
										",videoall="+ originalConfig.video.adFilter.all +
										",midroll=" + originalConfig.video.adFilter.midroll +
										",overlay=" + originalConfig.video.adFilter.overlay +
										",preroll=" + originalConfig.video.adFilter.preroll +
										",postroll="+ originalConfig.video.adFilter.postroll +
										",sponsor=" + originalConfig.video.adFilter.sponsor +
										",ad_exclude_all="+ (newTaxonomy["ad_exclude_all"] ? "true" : "false") +
										",ad_exclude_midroll="+ (newTaxonomy["ad_exclude_midroll"] ? "true" : "false") +
										",ad_exclude_overlays="+ (newTaxonomy["ad_exclude_overlays"]? "true" : "false") ;

				if(typeof(SIMAD.AdServerAdapter.SOI.__track) === "function"){
					SIMAD.AdServerAdapter.SOI.__track({	event:  'collect' ,  param: vidoeAdConfigStr });
				}
			}
		}

		if (config.video && config.video.__setByCMS && !config.video.__updateAdsNoTaxUpdate ) { //__updateAdsNoTaxUpdate false or not even set
			var videoConf = {"video": config.video};
			videoConf.video.__updateAdsNoTaxUpdate = true; // after the fist update ad don't use the CMS values
			SIMAD.CmsAdapter.setTaxonomy(SIMAD.Util.extend(true, videoConf , this.__mapCallbackFunctionToSIMADJson(newTaxonomy)));
			this.doAdBridgeCallback();
		} else {
			if (newTaxonomy) {
				var tempTaxonomy = this.__mapAdBrideJsonToSIMADJson(newTaxonomy);
				if(config.video && config.video.__setByCMS && config.video.__updateAdsNoTaxUpdate === true){ // only update taxonomy if __updateAdsNoTaxUpdate is not set, because of vidoe replay and oas adserver init
					SIMAD.CmsAdapter.setTaxonomy(SIMAD.Util.extend(true, config, this.__mapCallbackFunctionToSIMADJson(newTaxonomy))); //reqister the callback in video
				}else{
					SIMAD.CmsAdapter.setTaxonomy(tempTaxonomy);
				}
				if (!config.adFree) {
					var videoAdInitCallAfter = SIMAD.AdServerAdapter[tempTaxonomy.video.__adServer].getVideoAdInitiationAdFormat();
					var videoInitalisationAd = SIMAD.CmsAdapter.getAds(function(ad) {
						return ad.getFormat() === videoAdInitCallAfter && ad.getAdServer() === tempTaxonomy.video.__adServer ;
					 });

					if (videoInitalisationAd[0]) {
						videoInitalisationAd[0].bindEvent("afterReload", "VideoAdInit", SIMAD.VideoAdapter.AdBridge.doAdBridgeCallback);
					} else {
						SIMAD.Log.warn("Video: the AdBridge callback function couldn't be bound to the a object");
					}

					SIMAD.CmsAdapter.reloadAds();
				}
			}

			 if (config.adFree) {
				this.doAdBridgeCallback();
			}
		}
		return this;
	},

	/**
	 * retunrs the args paramente datastructure the adbrigde expects acording to the configuration
	 */
	__getAdBrigeCallbackArgs :function(){
		var config = SIMAD.getConfig();

		var flag;
		try	{
			flag = (config.adFree || !config.video.adFilter.all) ? 0 : 1;
		} catch (e) {
			SIMAD.Log.warn("Can't access the video settings in doAdBridgeCallback function");
		}


		var args = {
			init:  flag,
			ad_type: config.video.__adServer, // SOI | OAS // Adserver Identifier
			tld:    SIMAD.Core.getTLD() // to level domain
		};

		return args;
	},


	/**
	 * the Adverting Bridge expects after the call of the updateAds() function a callback function call.
	 * The callback function of the Advertising Bridege expects an JSON object.
	 *
	 * @example
	 * var args ={
	 *	init: 0 | 1 		// if init was succesfull
	 *	ad_type: SOI | OAS 	// the used Adserver Id
	 * 	tld: de | at | ch  	// the used top Level Domain
	 * };
	 * document.getElementById(callback_id).callback_function(args); // only illustrated code to explane the underling concept
	 */
	doAdBridgeCallback : function() {

		var args = SIMAD.VideoAdapter.AdBridge.__getAdBrigeCallbackArgs();

		var config = SIMAD.getConfig();
		var callbackFunction = config.video.onLoadCallback;
		if (!callbackFunction) { return; }

		var object = config.video.objectForOnLoadCallback;
		if (!object) { object = window; }

		try {
			SIMAD.Log.log("Video", 'doAdBridgeCallback for ' + callbackFunction + ' called with arguments:' , args);
			object[callbackFunction](args);
		} catch(e) {
			SIMAD.Log.warn('doAdBridgeCallback for ' + callbackFunction + ' FAILED with arguments:' , args);
			return;
		}

		return true;
	},


	/**
	 * @private
	 * __allowVideoAdRequest capsels the desition if a VideoAd should be processed or not
	 */
	__allowVideoAdRequest : function(video_ad_id) {
		var allowRequest = false;
		var currentConfig = SIMAD.getConfig();
		if(!currentConfig.adFree){
			if (typeof currentConfig.video !== "undefined"&& typeof currentConfig.video.adFilter != "undefined" ) {
				if(currentConfig.video.adFilter.all){
					if(video_ad_id.match(/^preroll/) && currentConfig.video.adFilter.preroll ){
						allowRequest = true;
					} else if (video_ad_id.match(/^postroll/) && currentConfig.video.adFilter.postroll ){
						allowRequest = true;
					} else if (video_ad_id.match(/^(presplit|midroll|postsplit)/) && currentConfig.video.adFilter.midroll){
						allowRequest = true;
					} else if (video_ad_id.match(/^overlay/) && currentConfig.video.adFilter.overlay ){
						allowRequest = true;
					} else if (video_ad_id.match(/^sponsor/) && currentConfig.video.adFilter.sponsor ){
						allowRequest = true;
					} else if (video_ad_id.match(/^pauseroll/)){
						allowRequest = true;
					}
				}
			}
		}
		return allowRequest;
	},

	/**
	 * Called from the Videoplayer20 AdBridge to get a Url to an XML file which descirbes the Video Ad including the flv file. <br />
	 * before this gets called the updateAds method was called and the AdLayer called a callback on the VideoPlayer Flash object.
	 *
	 * @param {String} video_ad_id the name of the video ad palce:
	 *	"preroll1","preroll1b","preroll1c","preroll1d","preroll1e",
	 *	"midroll1","midroll1b","midroll1c","midroll1d","midroll1e",
	 *	"midroll2","midroll2b","midroll2c","midroll2d","midroll2e",
	 *	"midroll3","midroll3b","midroll3c","midroll3d","midroll3e",
	 *	"midroll4","midroll4b","midroll4c","midroll4d","midroll4e",
	 *	"midroll5","midroll5b","midroll5c","midroll5d","midroll5e",
	 *	"sponsor1","sponsor1b","sponsor1c","sponsor1d","sponsor1e",
	 *	"presplit1","presplit2","presplit3","presplit4","presplit5",
	 *	"overlay1","overlay2","overlay3","overlay4","overlay5",
	 *	"postroll1","postroll1b","postroll1c","postroll1d","postroll1e"
	 *
	 * @param {JSON} args datastructure for prefetc and industry exclution
	 *
	 * @return {String} Returns the URL to the XML which descibes the video ad
	 * Will be called by the AdBridge for each video Ad Block:
	 *
	 * @example
	 * var args ={
	 * 	"oid":"",
	 * 	"prefetch":0,
	 * 	"industries":{
	 * 		"preroll1b":{
	 * 			"indtarget":"",
	 * 			"industry":""
	 * 		},
	 * 		"preroll1":{
	 * 			"indtarget":"",
	 * 			"industry":""
	 * 		}
	 * 		... // more past send industrie exclutions
	 * 	}
	 * };
	 * var video_ad_id = preroll1 | preroll1b | preroll1c ....
	 * getVideoAdRequest(video_ad_id, args);
	 *
	 */
	getVideoAdRequest: function(video_ad_id, args) {
		SIMAD.Log.log("Video", "getVideoAdRequest called in video adapter for " + video_ad_id , args);
		var url = "";
		if (this.__allowVideoAdRequest(video_ad_id)) {
			args["video_ad_id"] = video_ad_id;
			url =  SIMAD.CmsAdapter.getVideoAdRequest(args);
		} else {
			SIMAD.Log.log("Video", "getVideoAdRequest sciped for " + video_ad_id);
		}
		return url;
	},


	/**
	 * called from Video Bridge with a JSON object describing the event <br />
	 * used to inform adlayer about screenmod changes to hide the ad.
	 * @param {JSON} event screen mode informations
	 * var event = {
	 * 	event: "screen_mode" 		//event type = screen_mode
	 * 	screen_mode: "normal" | "fullsize" // "fullsize" -> AdLayer hides ads; "normal" -> AdLayer shows Ads
	 * }
	 * handleEvent(event);
	 */
	handleEvent: function (_event) {
		if(typeof _event === "object"){
			SIMAD.Log.log("Video", "handle event called",_event);
			switch (_event.screen_mode) {
				case "normal":
					SIMAD.CmsAdapter.showAds();

				break;
				case "fullsize":
					SIMAD.CmsAdapter.hideAds();

				break;
			}
		}else{
			SIMAD.Log.warn("VideoAdapter.AdBridge.handleEvent() was called with wrong parametes");
		}

	},

	/**
	 * returns the current to level Domain used in the AdLayer
	 * @return "de" | "at" | "ch"
	 */
	getTLD: function() {
		return SIMAD.Core.getTLD();
	}
};




