/*
	(w) 2005-2009 Ingrid Graefen, BRAINPOOL Artist und Content Services GmbH
*/

// Guarantee that some variables are defined.
if (!window.add2tag) add2tag = '';
if (!window.soi_adtrace) soi_adtrace = '';
if (!window.soi_ad) soi_ad = '';

if (!window.SIMAdWriter) {
	window.SIMAdWriter = new SIMAdHandler('DUMMY', null, window, 0);
}

/* GOOGLE ADS CONFIG */

/*
	This object allows google ads to query the state of relevant ordinary ads.
	It does *not* provide full info on display of ordinary ads.
	Key/value pairs ad_id => 0|1 are set by checkRectangle (e.g. rectangle2: 1).
	Thus SIM_ADTAG_INFO must only be queried after execution of these functions.
*/
var SIM_ADTAG_INFO = {};

// This variable is needed for incrementing google_skip
var SIM_GOOGLE_COUNT = 0;
var SIM_GOOGLE_SEARCH_COUNT = 0;

// This variable is set with google variable configuration
// before including google's show_ads.js
var SIM_GOOGLE_ADTYPE = '';

/**********************************/

/*************************************************
Encapsulation for different adservers
*************************************************/
/*
	Arguments:
	ad_type:       string
	adserver_call: either reference to function, or NAME of global function (i.e. STRING)
	my_window:     window object (obsolete)
	config:        associative array
	               Valid properties (optional):
	               - path:                subsite path # maybe different from document path
	               - content_type:        beitrag|video|...
	               - available_ad_ids:    ['popup1', 'fullbanner2', ...]
	               - available_video_ads: ['preroll', 'sponsor', 'presplit', 'midroll', 'postsplit', 'overlay', 'postroll']
	               - videoad:             true|false
	               - ad_iframe:           URL for ad iframe document (currently not used)
	               - do_log:              0|1 (enable logging with timestamps)

	public properties:
		adType, bannerAdRequests, videoAdRequests

	public general methods:
		getSessionID, updateAds, handleEvent, isUpdateStart, loadNextIFrameAd,
		clearAdContainer, clearAdContainers,
		finishIFrameAd, resizeIFrame, syncVars, resetVars, getTLD, hasVideoAds,
		doLog, showLog, clearLog

	public methods (ad_type specific):
		doAd, getVideoAdRequest, getAdtrace, getAdDimensions

	public method (OAS only)
		loadScript

	(1) Valid properties for updateAds config (all optional)
	- path                taxonomie path for update, e.g. '/kino/one/two'
	- triggered_for:      CPplayer|iframe_action|contentgallery|video...
	- callback_function:  name of callback function (string)
	- callback_id:        id of object whose callback_function is to be called
	- callback_object:    object whose callback_function is to be called (wins over callback_id)
	- callback_caller:    OPTIONAL, passed only if callback must be fired from specific ad_id, i.e. rectangle for contentgalleries
	- ad_iframe:          path to domino iframe - pass this only if default_ad_iframe is not suitable,
	                      and a suitable path could not be set on initialization of SIMAdWriter

	Applicable for videos only
	- video_type:         short|full
	- ad_exclude_all:      0|1
	- ad_exclude_midroll:  0|1
	- ad_exclude_overlays: 0|1
	- screen_mode:         fullscreen|fullsize|normal

	(2) Valid properties for handleEvent config
	- event:               screen
	- screen_mode:         fullscreen|fullsize|normal

	(3) Arguments for getVideoAdRequest
		(3.1) video_ad_id:  preroll1|midroll1|midroll1b...
		(3.2) JSON config - valid properties (optional)
		- prefetch:    0|1 // for prefetched video ad types, e.g. midrolls
		- industries:  {
		                  midroll1:  {industry: 'blub'},
		                  midroll1c: {industry: 'blab'}
		               }
*/
function SIMAdHandler(ad_type, adserver_call, my_window, config)
{
	var self = arguments.callee;
	
	// Constants
	this.__DOM_SAFE_ID = 'simadwriter-dom-safe';

	// Instance properties

	// Valid ad types are SOI|OAS
	this.adType = ad_type && ad_type == 'SOI' || ad_type == 'OAS' ?
		ad_type : 'DUMMY';

	// This property is obsolete
	// but set here to explain the meaning of the third argument,
	// which must be passed for backward compatibility
	this.__window = (my_window || window);

	this.__start_time = new Date().getTime();

	this.__adserver_call = adserver_call;

	this.__display_ads_cleared = false;

	if (!this.__log)       this.__log = [];
	if (!this.__clear_log) this.__clear_log = [];

	this.__config = typeof(config) == 'object' ? config : new Object;

	if (!this.__config.site) this.__config.site = '';
	if (!this.__config.tld)  this.__config.tld  = 'de';
	if (!this.__config.available_ad_ids) this.__config.available_ad_ids = [];
	if (!this.__config.available_video_ads) this.__config.available_video_ads = [];

	if (this.adType == 'OAS') {
		this.__adserver   = 'http://austria1.adverserve.net/RealMedia/ads';
		this.__dimensions = [];
		this.__adtrace    = '';
	}

	if (!self.__init_general) {
		self.__init_general = 1;

		self.prototype.__iframe_prefix = 'iframe_';
		self.prototype.__default_ad_iframe = '/php-bin/functions/adtags/ad_iframek1.php';

		// Public general methods

		self.prototype.isUpdateStart = function() {
			return (this.__is_update_start || 0);
		}

		self.prototype.updateAds = function(args) {
				// Prevent IE abortion on premature dom manipulation
				var is_dom_safe = this.__isDOMSafe();

				if (is_dom_safe == 0) {
					var that = this;
					setTimeout(function() {that.updateAds(args);}, 50);
					return;
				}
				else if (is_dom_safe < 0) {
					// Check was impossible.
					// Simply looped for some time.
					// Should be ok now => continue.
				}

				this.__logMsg('updateAds called with arguments:', args);

				this.__initUpdateConfig(args);

				if (this.adType == 'DUMMY') {
					this.__doCallback(0);
				}
				else {
					this.__startAdUpdate();
				}
			};

		self.prototype.handleEvent = function(args) {
				if (!args || typeof(args) != 'object') return;

				var event = args.event;
				if (!event) return;
				
				var content_type = this.__getUpdateConfig('content_type');

				if (event == 'screen') {
					var flag;
					if (content_type == 'CPplayer') {
						var screen_mode = args.screen_mode || 'normal';
						flag = screen_mode == 'normal' ? 1 : 0;
					}
					else {
						return;
					}

					this.__logMsg('handleEvent called with arguments:', args);

					this.__setDisplayForAdIFrames(flag);
				}
			};

		self.prototype.loadNextIFrameAd = function(is_start, retry) {
				var ad_id = this.__getNextAdID(is_start, retry);
				if (!ad_id) return;
				
				// Default is used unless ad_iframe is passed on initialization
				// or via updateAds
				var ad_iframe = this.__getUpdateConfig('ad_iframe')
					|| this.__getConfig('ad_iframe')
					|| this.__default_ad_iframe;
				if (!ad_iframe) return;

				// Checking for the private property directly is necessary
				// to allow standalone test for ad_iframe*.php
				if (typeof(this.__update_config) != 'object') {
					this.updateAds();
					return;
				}

				var content_type = (this.__getUpdateConfig('content_type') || '');
				
				var url = ad_iframe + '?path='+ escape(this.__getUpdateConfig('path'))
					+ '&ad_id=' + escape(ad_id);

				if (content_type) url += '&content_type=' + escape(content_type);

				var available_ad_ids = this.__getConfig('available_ad_ids');
				if (available_ad_ids.length)
					url += '&all_iframe_ads=' + available_ad_ids.join('-');

				if (content_type.match(/^(video|CPplayer)$/)) {
					var video_type  = this.__getUpdateConfig('video_type');
					var screen_mode = this.__getUpdateConfig('screen_mode');

					if (video_type)                                    url += '&video_type=' + escape(video_type);
					if (screen_mode && screen_mode != 'normal')        url += '&video_screen_mode=' + escape(screen_mode);
					if (this.__getUpdateConfig('ad_exclude_all'))      url += '&video_no_ad=1';
					if (this.__getUpdateConfig('ad_exclude_midroll'))  url += '&video_no_midrolls=1';
					if (this.__getUpdateConfig('ad_exclude_overlays')) url += '&video_no_overlays=1';
				}

				// Params for debugging
				var query_string = window.location.search;
				if (query_string) {
					var found = query_string.match(/(?:[ios]+_[a-z]+_[a-z]+|[df][a-z]+_ads_?[a-z]*|ad_[a-z]+)=[a-zA-Z0-9_-]*/g);
					if (found) url += '&' + found.join('&');
				}

				var ok = false;
				try {
					ok = this.__getIFrameHandler().loadIFrame(ad_id, this.__getIFrameID(ad_id), url);
					this.__logMsg('loadNextIFrameAd for ' + ad_id + ' session id: ' + this.getSessionID() + (ok ? ' successful' : ' failed'));

					// Topple the next domino iframe if this one falls into a hole.
					// This allows to continue after an ad_id whose placeholder is missing.
					// Important: The second argument (i.e. retry) must be set to true.
					if (!ok) ok = this.loadNextIFrameAd(is_start, true);
				}
				catch(e) {}

				return ok ? true : false;
			};

		self.prototype.finishIFrameAd = function(ad_id, iframe_window) {
				this.syncVars(iframe_window, window, 'after');

				if (this.__getUpdateConfig('callback_function')) {
					var callback_caller = (this.__getUpdateConfig('callback_caller') || '');
					if (callback_caller == ad_id) this.__doCallback(1);
				}

				this.resizeIFrame(ad_id);
			};

		self.prototype.resizeIFrame = function(ad_id) {
				var dimensions = this.getAdDimensions(ad_id);

				// Do not clobber dimensions array
				var x = dimensions[0];
				var y = dimensions[1];
				// Remedy for wrong fallback values
				if (x == 1 && y == 1) x = y = 0;

				try {
					this.__getIFrameHandler().resizeIFrame(this.__getIFrameID(ad_id), [x, y]);
					this.__logMsg('resizeIFrame for ' + ad_id + ': ' + [x, y].join('x'), {}, 3);
				}
				catch(e) {
					this.__logMsg('resizeIFrame for ' + ad_id + ':\n' + this.__catchMe(e));
					return;
				}
				
				return true;
			};

		self.prototype.clearAdContainer = function(ad_id) {
				// Always re-initialize.
				this.clearLog('clear');

				// Please note:
				// It is intended that the outer container for popup1 (sowefo)
				// is not found here.
				var outer = document.getElementById(ad_id);
				if (outer) outer.style.display = 'none';

				var container = document.getElementById('target_' + ad_id);
				if (!container) return;

				var children = container.childNodes;
				if (!children) return;
				
				var iframe_id = this.__getIFrameID(ad_id);
				
				for (var i = children.length - 1; i >= 0; i--) {
					var child = children[i];
					var id = child.id || '';
					if (id == iframe_id) {
						this.__clearIFrameAd(ad_id);
					}
					else {
						this.__freeNode(child, true);
					}
				}

				var clear_log = this.showLog('clear');
				if (clear_log) {
					clear_log = '\n' + clear_log;
					// Always reset.
					this.clearLog('clear');
				}
				this.__logMsg('clearAdContainer for ' + ad_id + ' on ' + container.tagName + ' ' + container.id + clear_log);
			};

		self.prototype.clearAdContainers = function() {
				if (this.__display_ads_cleared) return;

				// All *initially* present ad containers must be cleared.
				// Do not query __getUpdateConfig here.
				var available_ad_ids = this.__getConfig('available_ad_ids') || [];
				for (var i = 0; i < available_ad_ids.length; i++) {
					var ad_id = available_ad_ids[i];
					this.clearAdContainer(ad_id);
				}
				this.__clearGoogleContainers();

				this.__display_ads_cleared = true;
			};

		// This can be used to sync vars between arbitrary objects,
		// e.g. (parent, window), (this, window) ...
		// The third argument 'which' specifies sync_vars slot
		self.prototype.syncVars = function(from, to, which) {
				if (typeof(from) != 'object' || typeof(to) != 'object') return;
				if (from == to) return;
				
				// Adserver specific call
				if (typeof(this.__syncVars) == 'function') this.__syncVars(from, to, which);

				if (typeof(this.__sync_vars) != 'object') return;

				var varnames = this.__sync_vars[which] || [];
				
				for (var i = 0; i < varnames.length; i++) {
					to[varnames[i]] = from[varnames[i]];
				}
			};
			
		// Clear adserver variables
		self.prototype.resetVars = function() {
				// Adserver specific call
				if (typeof(this.__resetVars) == 'function') this.__resetVars();

				if (typeof(this.__sync_vars) != 'object') return;

				// Declare but do not define variable.
				// This is necessary because very old or exotic browsers
				// might not have native undefined property.
				var my_undefined;

				// Clear adserver variables
				for (var key in this.__sync_vars) {
					var varnames = this.__sync_vars[key] || [];
					for (var i = 0; i < varnames.length; i++) {
						// IMPORTANT:
						// The delete operator deletes only global variables
						// that were explicitly defined as *window* property,
						// i.e. window[PROP] rather than using the var keyword.
						// Some global SOI variables cannot be deleted via delete.
						// Must be set to undefined, not to null!
						window[varnames[i]] = my_undefined;
					}
				}
			};
		
		// Setter and getter method
		self.prototype.hasVideoAds = function() {
				if (arguments.length) this.__setConfig('videoad', arguments[0]);
				return this.__getConfig('videoad');
			};
		
		self.prototype.getTLD = function() {
				return this.__getConfig('tld');
			};
		
		self.prototype.getSessionID = function() {
				return this.__session_id || '';
			};
		
		self.prototype.doLog = function(flag) {
				if (typeof(flag) != 'undefined') this.__setConfig('do_log', flag);
				return this.__getConfig('do_log') || 0;
			};
			
		self.prototype.showLog = function(which) {
				var retval = '';
				if (which == 'clear') {
					if (this.__clear_log) retval = this.__clear_log.join('\n');
				}
				else {
					if (this.__log) {
						retval = this.__log.join('\n\n');
						if (retval) retval = 'ALL TIMES ARE GIVEN IN SECS AFTER INIT OF SIMAdWriter\n\n' + retval;
					}
				}
				return retval;
			};

		self.prototype.clearLog = function(which) {
				if (which == 'clear') {
					this.__clear_log = [];
				}
				else {
					this.__log = [];
				}
			};

		// Private general methods
		self.prototype.__isVideoAd = function(ad_id) {
				return ad_id && ad_id.match(/^(?:preroll|sponsor|presplit|midroll|postsplit|overlay|postroll)[1..9]/) ?
					true : false;
			};

		self.prototype.__initInstance = function() {
				this.__setSessionID();
				if (typeof(this.__setSyncVars) == 'function') this.__setSyncVars();
				// For ie dom safe test
				if (parent == window && !document.getElementById(this.__DOM_SAFE_ID)) {
					document.write('<div id="' + this.__DOM_SAFE_ID + '" style="display:none"><\/div>');
				}

				try {
					var found = top.location.search.match(/simadwriter_debug=([0-9]+)/)
					if (found) this.doLog(found[1]);
				}
				catch(e) {
					this.__logMsg('__initInstance:\n' + this.__catchMe(e));
				}

				if (this.adType != 'DUMMY') this.__logMsg('new\nadType: ' + this.adType, this.__config);
			};

		self.prototype.__setSessionID = function() {
				var master = this.__findMaster();
				var rand = String(Math.random()).substring(2,11);
				this.__session_id = master ? (master.getSessionID() || rand) : rand;
				return this.__session_id;
			};

		self.prototype.__getAdserverCall = function() {
				var func = this.__adserver_call;
				var type = typeof(func);

				if (type == 'string') func = window[func];

				// Do not clobber property!
				if (typeof(func) != 'function') func = function() {return ''};

				return func;		
			};

		self.prototype.__startAdUpdate = function() {
				this.__setSessionID();

				// Clear everything before new round.
				this.clearAdContainers();
				this.__clearDebugPanel();

				this.resetVars();
				
				// Reset properties
				this.bannerAdRequests = {};
				this.videoAdRequests  = {};

				this.__dimensions     = {};
				this.__adtrace        = '';

				this.__display_ads_cleared = false;

				// Init new update round with true argument.
				this.loadNextIFrameAd(true);
			};

		self.prototype.__findMaster = function(key) {
				if (window == parent) return;
				
				// This cannot be done on initialization
				// because child might exist before parent,
				// e.g. because of firefox iframe caching bug
				if (!this.__master) {
					try {
						// Should not know the name of parent instance, but ...
						if (parent.SIMAdWriter) this.__master = parent.SIMAdWriter;
					}
					catch(e) {
						this.__logMsg('__findMaster:\n' + this.__catchMe(e));
					}
				}

				return this.__master;
			};

		self.prototype.__getConfig = function(key) {
				if (!key || typeof(this.__config) != 'object') return;
				return this.__config[key];
			};

		self.prototype.__setConfig = function(key, value) {
				if (!key) return;
				if (typeof(this.__config) != 'object')
					this.__config = new Object;
				this.__config[key] = value;
			};

		self.prototype.__initUpdateConfig = function(args) {
				// Reset
				this.__update_config  = new Object;
				this.__video_ads_skip = new Object;

				if (typeof(args) == 'object') {
					for (var key in args) {
						this.__setUpdateConfig(key, args[key]);
					}
				}

				var available_ad_ids = this.__getConfig('available_ad_ids');

				// Special content types
				var triggered_for = (this.__getUpdateConfig('triggered_for') || '');
				if (triggered_for == 'CPplayer') {
					this.__setUpdateConfig('content_type', 'CPplayer');
				}
				else if (triggered_for == 'video') {
					this.__setUpdateConfig('content_type', 'video');
				}
				else if (triggered_for == 'contentgallery') {
					this.__setUpdateConfig('content_type', 'gallery');
				}

				// Defaults
				if (!this.__getUpdateConfig('path'))
					this.__setUpdateConfig('path', (this.__getConfig('path') || '/'));

				if (!this.__getUpdateConfig('content_type'))
					this.__setUpdateConfig('content_type', (this.__getConfig('content_type') || ''));
					
				if (!this.__getUpdateConfig('event'))
					this.__setUpdateConfig('event', '');
					
				if (!this.__getUpdateConfig('screen_mode'))
					this.__setUpdateConfig('screen_mode', 'normal');

				if (this.__getUpdateConfig('callback_function')) {
					if (!this.__getUpdateConfig('callback_caller')) {
						var l = available_ad_ids.length;
						if (l) {
							// callback should happen after fullbanner2
							// because fullbanner2 is reference ad type
							if (l > 1 && available_ad_ids[1] == 'fullbanner2') {
								this.__setUpdateConfig('callback_caller', 'fullbanner2');
							}
							else if (l > 0) {
								this.__setUpdateConfig('callback_caller', available_ad_ids[0]);
							}
						}
					}
					else {
						// callback_caller property was passed with update config
					}
				}

				if (this.__getUpdateConfig('ad_exclude_all'))      this.__video_ads_skip.all = 1;
				if (this.__getUpdateConfig('ad_exclude_midroll'))  this.__video_ads_skip.midrolls = 1;
				if (this.__getUpdateConfig('ad_exclude_overlays')) this.__video_ads_skip.overlays = 1;
			};

		self.prototype.__getUpdateConfig = function(key) {
				if (!key || typeof(this.__update_config) != 'object') return;
				return this.__update_config[key];
			};

		self.prototype.__setUpdateConfig = function(key, value) {
				if (!key) return;
				if (typeof(this.__update_config) != 'object')
					this.__update_config = new Object;
				this.__update_config[key] = value;
			};

		self.prototype.__doCallback = function(flag) {
			var callback_function = this.__getUpdateConfig('callback_function');
			if (!callback_function) return;

			var object = this.__getUpdateConfig('callback_object');
			if (!object) {
				var callback_id = this.__getUpdateConfig('callback_id');
				object = callback_id ? document.getElementById(callback_id) : window;
			}
			if (!object) return;

			var args = {
					init:    flag ? 1 : 0,
					ad_type: this.adType,
					tld:     this.__getConfig('tld')
				};

			var triggered_for = (this.__getUpdateConfig('triggered_for') || '');

			try {
				object[callback_function](args);
				this.__logMsg('callback function ' + callback_function + ' called with arguments:', args);
			}
			catch(e) {
				this.__logMsg('callback function ' + callback_function + ' FAILED with arguments:', args);
				return;
			}

			return true;
		}

		// flag: true => node is removed from DOM, false => node is not removed
		self.prototype.__freeNode = function(node, flag) {
				try {
					if (node.nodeType == 1) {
						// Prevent memory leaks to some extent.
						// Please note:
						// Blind destruction of non-eventhandlers causes too many problems.
						// Looping through all node properties and element attributes is too time-consuming.
						var events = [
								'onabort', 'onblur', 'onchange', 'onclick', 'ondblclick', 'onerror',
								'onfocus', 'onkeydown', 'onkeypress', 'onkeyup', 'onload',
								'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup',
								'onreset', 'onselect', 'onsubmit', 'onunload'
							];
						for (var i = 0; i < events.length; i++) {
							var k = events[i];
							if (typeof(node[k]) != 'function') continue;

							var strf = String(node[k]);
							strf = strf.replace(/^(function *[^\(]*)(?:.|\s|\n)+/, '$1');

							this.__logMsg('Destroying event handler from ' + node.tagName + ' ' + (node.id || '') + ' ' + k + ' ' + strf, {}, 3, 'clear');
							node[k] = null;
						}

						// Do not use *hasChildNodes* because this method
						// does not exist on iframe nodes.
						var children = node.childNodes;
						if (children) {
							for (var i = children.length - 1; i >= 0; i--) {
								// No need to remove children recursively
								// because node itself is removed..
								this.__freeNode(children[i], false);
							}
						}
					}

					if (flag && node.parentNode) {
						this.__logMsg('Removing node ' + (node.tagName || 'type ' + node.nodeType) + ' ' + (node.id || '') + ' ' + (node.src || ''), {}, 3, 'clear');
						node.parentNode.removeChild(node);
					}
				}
				catch(e) {
					this.__logMsg('__freeNode for ' + node.id + ':\n' + this.__catchMe(e));
				}
			};

		self.prototype.__clearGoogleContainers = function() {
				// Clear only google ads with dependency on sim ads.
				this.clearAdContainer('google_rectangle2');
				// Unfortunately, inflow case must be handled separately.
				var google_rectangle = document.getElementById('google-rectangle2');
				if (google_rectangle) {
					google_rectangle.innerHTML = '';
					google_rectangle.style.display = 'none';
				}
			};

		self.prototype.__clearIFrameAd = function(ad_id) {
				setAttributeForElement(ad_id, 'display', 'none');

				var iframe_handler = this.__getIFrameHandler();
				iframe_handler.resizeIFrame(this.__getIFrameID(ad_id), [0,0]);

				this.__logMsg('Clearing domino iframe for ' + ad_id, {}, 3, 'clear');

				try {
					iframe_handler.loadIFrame(ad_id, this.__getIFrameID(ad_id), 'about:blank');
				}
				catch(e) {
					this.__logMsg('__clearIFrameAd for ' + ad_id + ':\n' + this.__catchMe(e));
					return;
				}
			};

		self.prototype.__clearIFrameAds = function() {
				// All *initially* present ad iframes must be cleared.
				// Do not query __getUpdateConfig here.
				var available_ad_ids = this.__getConfig('available_ad_ids') || [];
				for (var i = 0; i < available_ad_ids.length; i++) {
					var ad_id = available_ad_ids[i];
					this.__clearIFrameAd(ad_id);
				}
			};

		self.prototype.__setDisplayForAdIFrames = function(flag) {
				var available_ad_ids = this.__getConfig('available_ad_ids');
				var l = available_ad_ids.length;
				if (!l) return;

				for (var i = 0; i < l; i++) {
					var ad_id = available_ad_ids[i];
					var div_id = ad_id;
					try {
						this.__getIFrameHandler().setIFrameDisplay(this.__getIFrameID(ad_id), flag);
						// Necessary for powerdomino ads
						if (flag) {
							checkRectangle(ad_id, div_id);
						}
						else {
							var container = document.getElementById(div_id);
							if (container) container.style.display = 'none';
						}
					}
					catch(e) {}
				}
			};

		self.prototype.__clearDebugPanel = function() {
				var debug_id = 'sim_ad_debug';
				var debug_container = document.getElementById(debug_id);
				if (debug_container) debug_container.innerHTML = '';
			};

		self.prototype.__getNextAdID = function(is_start, retry) {
				var available_ad_ids = this.__getConfig('available_ad_ids');
				var total = available_ad_ids.length;
				
				if (!total) {
					this.__updating = false;
					return;
				}
				
				// Avoid endless loop
				if (!is_start && !this.__updating) return;

				if (is_start) {
					this.__updating = true;
					// Avoid endless loop
					if (!retry) {
						this.__update_index = 0;
					}
					else {
						++this.__update_index;
					}
					this.__is_update_start = true;
				}
				else {
					++this.__update_index;
				}
				
				if (!is_start || this.__update_index >= total) {
					this.__is_update_start = false;

					if (this.__update_index >= total) {
						this.__updating = false;
						this.__update_index = null;
						return;
					}
				}

				return available_ad_ids[this.__update_index];
			};

		self.prototype.__getIFrameID = function(ad_id, prefix) {
				return (prefix || this.__iframe_prefix) + ad_id;
			};
			
		self.prototype.__getIFrameHandler = function() {
				if (!this.__ad_iframe_handler) {
					this.__ad_iframe_handler = new SIMAdIFrameHandler();
				}
				return this.__ad_iframe_handler;
			};

		self.prototype.__skipVideoAdRequest = function(video_ad_id) {
				if (!this.hasVideoAds()) return true;
				if (!this.__video_ads_skip) return false;
				if (this.__video_ads_skip.all) return true;
				if (video_ad_id) {
					if (video_ad_id.match(/^(presplit|midroll|postsplit)/) && this.__video_ads_skip.midrolls) return true;
					if (video_ad_id.match(/^overlay/) && this.__video_ads_skip.overlays) return true;
				}
				return false;
			};

		// Check if IE is ready for dom manipulation.
		// The hidden container is written on instance initialization
		self.prototype.__isDOMSafe = function() {
				var retval;
				
				if (window != top) {
					// Should never happen
					retval = 0;
				}
				else {
					if (!this.__dom_check) {
						var container = document.getElementById(this.__DOM_SAFE_ID);
						var safe = !/msie/.test(window.navigator.userAgent.toLowerCase()) || window.opera ? 1 : 0;
						var hopeless = safe || (container && container.doScroll) ? 0 : 1;
						this.__dom_check = {
								counter:    1,
								safe:       safe,
								container:  container,
								hopeless:   hopeless,
								max_rounds: hopeless ? 10 : 40
							};
					}

					if (this.__dom_check.safe) {
						retval = 1;
					}
					else {
						if (this.__dom_check.hopeless) {
							// DOM safe check is impossible, just loop max_rounds
							if (++this.__dom_check.counter > this.__dom_check.max_rounds) {
								retval = -1;
							}
							else {
								retval = 0;
							}
						}
						else {
							try {
								this.__dom_check.container.doScroll('left');
								retval = 1;
							}
							catch(e) {
								retval = ++this.__dom_check.counter > this.__dom_check.max_rounds ? -1 : 0;
							}
						}

						// Also considered safe in -1 case (i.e. hopeless after max rounds)
						if (retval != 0) this.__dom_check.safe = 1;

						if (retval < 0 && this.__dom_check.safe) {
							this.__logMsg('__isDOMSafe check impossible. Considered safe in round ' + this.__dom_check.counter);
						}
						else if (retval > 0) {
							this.__logMsg('__isDOMSafe ok in round ' + this.__dom_check.counter);
						}
					}
				}
				
				return retval;
			};
		
		self.prototype.__logMsg = function(msg, args, level, which) {
				if (!level) level = 0;
				var verbosity = this.doLog();
				if (!verbosity || level > verbosity) return;

				if (typeof(msg) == 'undefined') msg = '';
				
				if (typeof(args) == 'object') {
					var x = '';
					for (var k in args) {
						if (k == 'industries' && typeof(args[k]) == 'object') {
							// Currently full dump only for industries property
							var y = '';
							for (var m in args[k]) {
								if (!args[k][m] || !args[k][m].industry) continue;
								y += '    ' + m + ':\n';
								if (typeof(args[k][m]) == 'object') {
									for (var n in args[k][m]) {
										if (n == 'indtarget') continue; // obsolete
										y += ['        ' + n, args[k][m][n]].join(': ') + '\n';
									}
								}
							}
							x += y ? k + ':\n' + y : k + ': [EMPTY OBJECT]\n';
						}
						else {
							x += [k, args[k]].join(': ') + '\n';
						}
					}
					if (x) msg += '\n' + x.replace(/\n+$/, '');
				}

				var master = this.__findMaster();
				if (master) {
					// Currently the only way to log from within domino iframes.
					master.__logMsg(msg + ' from domino iframe', {}, level, which);
				}
				else {
					// Usually, this case applies to parent instance.
					// But master is also not defined
					// if domino iframes are loaded before master instance has been initialized.
					// This may happen due to firefox iframe caching bug.
					// Unfortunately, such messages are lost for the parent document
					// because the domino iframes are reloaded immediately.
					if (which == 'clear') {
						this.__clear_log.push(msg);
					}
					else {
						var time_passed = (new Date().getTime() - this.__start_time) / 1000;
						this.__log.push('* ' + time_passed + ' secs\n' + msg);
					}
				}
			};

		self.prototype.__catchMe = function(e) {
				return '<span style="color:red">' + (typeof(e) == 'string' ? e : [e.name, e.message].join('\n')) + '<\/span>\n';
			};
	}

	if (!self.__init_ad_type) {
		if (this.adType != 'DUMMY') {
			// Set __init_ad_type property for first *regular* object, not for dummy objects.
			// After that all SIMAdHandler objects share these properties.
			self.__init_ad_type = 1;
		}

		// Prototype property
		if (!this.bannerAdRequests) this.bannerAdRequests = new Object();
		if (!this.videoAdRequests)  this.videoAdRequests  = new Object();
		
		if (this.adType == 'SOI') {
			// Public prototype methods

			// WARNING:
			// doAd writes a *script* tag to the document.
			// Thus it is not possible to fill the
			// properties '__dimensions' and '__adtrace'.
			// The variables are simply accessible too late.
			self.prototype.doAd = function(ad_id) {
					this.__logMsg('doAd for ' + ad_id);
					var adserver_call = this.__getAdserverCall()
					var retval = adserver_call(ad_id);

					// For debugging.
					var master = this.__findMaster();

					var found = retval.match(/src=["']?([^"'< ]+)/);
					var src = found && found[1] ? found[1] : '';

					this.bannerAdRequests[ad_id] = src;
					// Always collect also in master
					if (master) master.bannerAdRequests[ad_id] = src;

					document.write(retval);
				};

			self.prototype.getVideoAdRequest = function(video_ad_id, args) {
					if (this.__skipVideoAdRequest(video_ad_id)) return '';

					// Backwards compatibility:
					// Second and third argument used to be strings (tvl, tcluster),
					// which are obsolete.
					if (!args || typeof(args) != 'object') args = new Object;
					
					var ad_request = '';

					if (typeof(window.soi_VideoAdRequest) == 'function') {
						var content_type = this.__getUpdateConfig('content_type');
						var config_data = new Object;
						if (typeof(args.industries) == 'object') config_data.industries = args.industries;
						if (args.prefetch) config_data.prefetch = true;
						// FIXME: This must disappear eventually.
						// Player must pass 'prefetch' if needed.
						if (typeof(args.prefetch) == 'undefined' && content_type == 'CPplayer') {
							if (video_ad_id.match(/^midroll/)) {
								config_data.prefetch = true;
							}
						}

						ad_request = window.soi_VideoAdRequest(video_ad_id, config_data);
					}

					// For debugging.
					this.videoAdRequests[video_ad_id] = ad_request;
					
					this.__logMsg('getVideoAdRequest for ' + video_ad_id, args);

					if (ad_request && video_ad_id.match(/(presplit|midroll)/)) {
						this.clearAdContainers();
					}

					return ad_request;
				};

			self.prototype.getAdtrace = function() {
					return window.soi_adtrace ? unescape(window.soi_adtrace) : '';
				};

			self.prototype.getAdDimensions = function(ad_id) {
					var dimensions;

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

					if (dimensions && ad_id == 'fullbanner2'
						&& isType('fullbanner2', 'PB2', this.getAdtrace())) {
						// For some strange reason, the powerbanner height value
						// is usually faulty (90 instead of 180).
						dimensions[1] = 180;
					}

					return (dimensions || [0,0]);
				};

			// Private prototype methods
			self.prototype.__setSyncVars = function() {
					this.__sync_vars = {};
					this.__sync_vars.after = ['forceSkyscraperInside', 'forceSkyscraperOutside', 'preferSkyscraperOutside'];
				};

			self.prototype.__syncVars = function(from, to, which) {
					if (from == to) return;
					if (which != 'after') return;
					if (typeof(window.soi_SyncVars) == 'function') window.soi_SyncVars(from, to);
				};

			self.prototype.__resetVars = function() {
					if (typeof(window.soi_ResetVars) == 'function') window.soi_ResetVars();
				};
		}
		else if (this.adType == 'OAS') {
			// Public prototype methods
			self.prototype.doAd = function(ad_id) {
					var oas_ad_id = this.__getOASAdID(ad_id);
					if (!oas_ad_id) return;

					var adserver_call = this.__getAdserverCall()
					adserver_call(oas_ad_id);

					// Get and store adtrace and dimension info
					var oasinfo_container = document.getElementById('oasinfo_' + oas_ad_id);

					var width, height, info;

					if (oasinfo_container) {
						width  = parseInt(oasinfo_container.style.width);
						height = parseInt(oasinfo_container.style.height);
						info   = oasinfo_container.title;
					}

					if (!width) width   = 0;
					if (!height) height = 0;
					if (!info) info     = 'fallback';
					
					// Fix faulty dimensions from AdverServe
					/*
					if (ad_id == 'fullbanner1' || ad_id == 'fullbanner2') {
						if (width  > 728) width  = 728;
						if (height >  90) height =  90;
					}
					else if (ad_id == 'rectangle2') {
						if (width  > 180) width  = 180;
						if (height > 150) height = 150;
					}
					else if (ad_id == 'skyscraper1') {
						if (width  > 2.0 * 160) width  = 160;
						if (height > 1.2 * 600) height = 600;
					}
					*/
					
					var dimensions = [width, height];
					var adtrace = ad_id + ' - ' + info + ' ' + width + 'x' + height
						+ ' (oas ad_id ' + oas_ad_id + ')\n';

					this.__dimensions[oas_ad_id] = dimensions;
					this.__adtrace += adtrace;
						  
					var master = this.__findMaster();
					if (master) {
						// IFrame ads must also set these properties for the parent object.
						master.__dimensions[oas_ad_id] = dimensions;
						master.__adtrace += adtrace;
					}

					this.__logMsg('doAd for ' + ad_id);
				};

			self.prototype.getVideoAdRequest = function(video_ad_id, args) {
					if (this.__skipVideoAdRequest(video_ad_id)) return '';
					
					if (!args || typeof(args) != 'object') args = new Object;

					var oas_video_ad_id = this.__getOASAdID(video_ad_id);

					var ad_request = this.__buildAdServerURI({method: 'sx', ad_id: oas_video_ad_id, params: {no_sowefo: 1}});

					// For debugging.
					this.videoAdRequests[video_ad_id] = ad_request;

					this.__logMsg('getVideoAdRequest for ' + video_ad_id, args);

					if (!ad_request) return '';

					if (ad_request && video_ad_id.match(/(presplit|midroll)/)) {
						// No exclusivity for OAS
						// this.clearAdContainers();
					}

					if (typeof(args.industries) == 'object') {
						var seen = {};
						var ind_param = '';
						for (var key in args.industries) {
							if (!args.industries[key]) continue;

							var value = String(args.industries[key].industry || '');
							value = value.replace(/^ +/, '').replace(/ +$/, '');
							if (!value) continue;

							// Avoid duplicates
							if (seen[value]) continue;
							seen[value] = 1;

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

						if (ind_param) ad_request += '&' + ind_param;
					}

					return ad_request;
				};

			self.prototype.getAdtrace = function() {
					return this.__adtrace;
				};

			self.prototype.getAdDimensions = function(ad_id) {
					var oas_ad_id = this.__getOASAdID(ad_id);
					var dimensions = this.__dimensions[oas_ad_id];
					return dimensions ? dimensions : [0,0];
				};

			self.prototype.loadScript = function(args) {
					var src = this.__buildAdServerURI(args);
					if (!src) return;

					document.write('<script src="' + src + '"><\/script>');
					this.__logMsg('loadScript:\n' + src);
				};

			// Backwards compatibility
			self.prototype.loadScripts = function(args) {
					args.params = args.info || {};
					this.loadScript(args);
				};

			// Private prototype methods
			self.prototype.__setSyncVars = function() {
					this.__sync_vars = {};

					this.__sync_vars.after = ['forceSkyscraperInside', 'forceSkyscraperOutside', 'preferSkyscraperOutside'];
				};

			self.prototype.__getOASAdID = function(ad_id) {
					var retval;

					if (ad_id.match(/^postsplit[1..5]/)) {
						// postsplit currently not supported
					}
					else if (this.__isVideoAd(ad_id)) {
						retval = ad_id;
					}

					if (!retval) {
						var soi_to_oas = {
								popup1:      'Popup',
								fullbanner1: 'Top1',
								fullbanner2: 'Top',
								rectangle1:  'Middle1',
								rectangle2:  'Position1',
								rectangle3:  'Position2',
								maxiad1:     'Middle2',
								skyscraper1: 'Right1'
							};

						retval = soi_to_oas[ad_id];
					}

					return retval || '';
				};

			/*
				args = {
						method: '[method]' // mjx|jx|sx
						ad_id:  '[ad_id]',   // for jx|sx only popup1|preroll1|... 
						params: {
								no_sowefo: 1 // 0|1
							}
					}

				Examples:

				mjx: bulk load of all display ads in main document
				http://austria1.adverserve.net/RealMedia/ads/adstream_mjx.ads/sevengamesat/home/1[randnum]@Popup,Top,Middle1,Position1,Right1?content_type=cpplayer&no_sowefo=1

				jx: single ad in domino iframe
				http://austria1.adverserve.net/RealMedia/ads/adstream_jx.ads/sevengamesat/home/1[randnum]@Popup,Top,Middle1,Position1,Right1,Video1,Video1b,Sponsor1,Sponsor1b!Popup?content_type=cpplayer&no_sowefo=1

				sx: video ad
				http://austria1.adverserve.net/RealMedia/ads/adstream_sx.ads/sevengamesat/home/1[randnum]@Video1?videotype=preroll1
			*/
			self.prototype.__buildAdServerURI = function(args) {
					if (typeof(args) != 'object') return '';

					if (!this.__adserver) return '';

					var method = args.method;
					if (!method) return '';

					if (method.match(/^(jx|sx)$/)) {
						if (!args.ad_id || (method == 'sx' && !this.__isVideoAd(args.ad_id))) return '';
						var oas_id = this.__getOASAdID(args.ad_id);
						if (!oas_id) return '';
					}

					var positions = '';
					var url_params = '';

					if (method == 'sx') {
						positions  = 'Video1';
						url_params = 'videotype=' + escape(oas_id);
					}
					else if (method.match(/^(?:mjx|jx)$/)) {
						// Positions
						var available_ad_ids = this.__getConfig('available_ad_ids') || [];

						for (var i = 0; i < available_ad_ids.length; i++) {
							var x_oas_id = this.__getOASAdID(available_ad_ids[i]);
							if (!x_oas_id) continue;
							if (positions) positions += ',';
							positions += x_oas_id;
						}

						if (!positions) return '';

						if (method == 'jx') positions += '!' + oas_id;

						var content_type = this.__getUpdateConfig('content_type')
							|| this.__getConfig('content_type');

						// URL params
						url_params = 'content_type=' + escape(content_type);

						var params = args.params || {};

						for (var key in params) {
							var value = params[key];
							if (typeof(value) == 'undefined' || !String(value).length) continue;
							if (url_params) url_params += '&';
							url_params += [escape(key), escape(params[key])].join('=');
						}
					}
					else {
						return '';
					}
					
					var screen_width = getScreenWidth();
					if (screen_width) {
						if (url_params) url_params += '&';
						url_params += 'width=' + screen_width;
					}

					// Showroom
					try {
						var found = top.location.search.match(/(showroom)=([a-zA-Z0-9_-]*)/);
						if (found) {
							if (url_params) url_params += '&';
							url_params += [found[1], found[2] || 'standard'].join('=')
						}
					}
					catch(e) {
						this.__logMsg('__buildAdServerURI:\n' + this.__catchMe(e));
					}

					var path = this.__getUpdateConfig('path') || this.__getConfig('path') || '/';
					path = path.replace(/\/+$/, '');
					var parts = path.split('/');
					if (parts.length > 4) {
						parts.length = 4;
					}
					else if (parts.length < 4) {
						parts.push('home');
					}
					path = parts.join('/');

					return this.__adserver + '/adstream_' + method + '.ads'
						+ '/' + this.__getConfig('site') + this.getTLD() + path
						+ '/1' + this.getSessionID()
						+ '@' + positions
						+ (url_params ? '?' + url_params : '');
				};
		}

		// Define defaults for undefined methods.
		var methods = ['doAd', 'getVideoAdRequest', 'getAdtrace', 'loadScript'];

		for (var i = 0; i < methods.length; ++i ) {
			var method = methods[i];
			if (!self.prototype[method]) {
				self.prototype[method] = function() {return ''};
			}
		}
		
		if (!self.prototype.getAdDimensions) {
			self.prototype.getAdDimensions = function() {return []};
		}
	}

	this.__initInstance();
}

/*******************************************
IMPORTANT:
SIMAdIFrameHandler is only useful
in main document
*******************************************/

function SIMAdIFrameHandler()
{
	var self = arguments.callee;

	if (!self.__init) {
		self.__init = 1;

		self.prototype.loadIFrame = function(ad_id, iframe_id, url) {
				if (!url) url = 'about:blank';

				try {
					var iframe_window = this.__getIFrameWindow(ad_id, iframe_id);
					iframe_window.location.replace(url);
				}
				catch(e) {
					try {
						var iframe = document.getElementById(iframe_id);
						iframe.src = url;
					}
					catch(e) {
						return;
					}
				}

				return true;
			};

		self.prototype.resizeIFrame = function(iframe_id, dimensions) {
				var iframe = document.getElementById(iframe_id);
				if (!iframe) return;

				if (iframe.style.display == 'none') iframe.style.display = 'inline';
				if (iframe.style.border) iframe.style.borderStyle = 'none';
				iframe.style.width  = dimensions[0] + 'px';
				iframe.style.height = dimensions[1] + 'px';
			};
			
		self.prototype.setIFrameDisplay = function(iframe_id, flag) {
				var iframe = document.getElementById(iframe_id);
				if (!iframe) return;
				
				if (flag) {
					if (iframe.style.display == 'none') iframe.style.display = 'inline';
				}
				else {
					// Always
					iframe.style.display = 'none';
				}
			};

		self.prototype.__getIFrameWindow = function(ad_id, iframe_id) {
				var iframe = this.__getAdIFrame(ad_id, iframe_id);
				if (!iframe) return;

				var iframe_window = iframe.contentWindow;

				if (!iframe_window) {
					try {
						iframe_window = iframe.contentDocument.defaultView;
					}
					catch(e) {
						try {
							iframe_window = window.frames[iframe_id];
						}
						catch(e) {}
					}
				}

				return iframe_window;
			};

		self.prototype.__getAdIFrame = function(ad_id, iframe_id) {
				if (!ad_id) return;
				if (!this.__ad_iframes) this.__ad_iframes = new Object;

				if (!this.__ad_iframes[ad_id]) {
					var iframe = document.getElementById(iframe_id);

					if (!iframe) {
						var ad_container = document.getElementById('target_' + ad_id);
						if (!ad_container) return;

						var width        = 0;
						var height       = 0;
						var border       = 0;
						var border_style = 'none';

						iframe = document.createElement('iframe');

						iframe.id                = iframe_id;
						iframe.name              = iframe_id;
						iframe.style.width       = width + 'px';
						iframe.style.height      = height + 'px';
						iframe.style.borderStyle = border_style;
						iframe.style.borderWidth = border + 'px';
						iframe.style.padding     = '0px';
						iframe.style.margin      = '0px';
						iframe.src               = 'about:blank';
						iframe.frameBorder       = border;
						iframe.border            = border;
						iframe.scrolling         = 'no';
						iframe.allowTransparency = true;

						ad_container.appendChild(iframe);
					}

					this.__ad_iframes[ad_id] = iframe;
				}

				return this.__ad_iframes[ad_id];
			};

	}
}

/*****************************************
Functions for adtags check and adjustment
*****************************************/

function isType(ad_id, type) {
	var ad_type = SIMAdWriter.adType;
	
	var adtrace = SIMAdWriter.getAdtrace();
	if (!adtrace) return false;

	// Existence check.
	if (type == null) type = '';

	var typeTest = new RegExp(ad_id + '.+' + type, 'i');
	var result = typeTest.test(adtrace);

	return result ? true : false;
}

function getMyCurrentStyle(arg, property) {
	var element = typeof(arg) == 'string' ? document.getElementById(arg) : arg;
	if (!element) return;

	var get_computed_style = document.defaultView ? document.defaultView.getComputedStyle : window.getComputedStyle;

	if (typeof(get_computed_style) == 'function') {
		var styles = get_computed_style(element, null);
		if (styles) {
			var selector = property.match(/^(?:float|styleFloat)$/) ?
				  'cssFloat'
				: property.replace(/([A-Z])/g, function(x, c){return '-' + c.toLowerCase()});
			value = styles.getPropertyValue(selector);
		}
	}
	else {
		var styles = element.currentStyle;
		if (styles) {
			// IE uses styleFloat instead of standard cssFloat
			var selector = property.match(/^(?:float|cssFloat)$/) ?
				  'styleFloat'
				: property.replace(/-(.)/g, function(x, c){return c.toUpperCase()});
			value = styles[selector];
		}
	}

	return value;
};

function existsRectangle(ad_id) {
	var exists   = isType(ad_id);
	var fallback = isType(ad_id, 'Fallback');

    return exists && !fallback ? true : false;
}

function hasBlockpixel(ad_id) {
	return isType(ad_id, 'Block[_-]?pixel') ? true : false;
}

function reserveSowefoSpace(ad_id) {
	var reserve_space = isType(ad_id, 'Block[_-]?pixel.+' + ad_id);

	// fullbanner2 keyword can also be 'superblock'
	if (!reserve_space && ad_id == 'fullbanner2') {
		reserve_space = isType(ad_id, 'Block[_-]?pixel.+' + 'superblock');
	}

	return reserve_space ? true : false;
}

function minWidthForSkyscraperOutside() {
	var searchstring = window.location.search.substring(1);

	var found;
	var min_width;

	if (searchstring) {
		found = searchstring.match(/outside=([0-9]+)/);
		if (found && found[1]) min_width = parseInt(found[1]);
	}
	
	if (!min_width) min_width = 1175;
	return min_width;
}

function checkRectangle(ad_id, div_id) {
	var exists = existsRectangle(ad_id) ? true : false;
	SIM_ADTAG_INFO[ad_id] = exists ? 1 : 0;

	// Container might not exist.
	var elem = document.getElementById(div_id);
	if (!elem) return exists;

	if (exists) {
		if (hasBlockpixel(ad_id)) {
			if (reserveSowefoSpace(ad_id)) {
				if (ad_id != 'fullbanner2') {
					elem.style.backgroundColor = 'transparent';
				}
				elem.style.backgroundImage = 'none';
				var td_elem = document.getElementById('td-' + ad_id);
				if (td_elem) td_elem.style.backgroundImage = 'none';
			}
			else {
				elem.style.display = 'none';
				return;
			}
		}

		adjustLayoutForBigbanner();
		adjustLayoutForWallpaper();

		elem.style.display = 'block';
	}
	else {
		elem.style.display = 'none';
	}

	return exists;
}

function adjustLayoutForBigbanner() {
	if (!isType('fullbanner2', 'PB2')) return;
	
	var container = document.getElementById('fullbanner2');
	if (!container) return;
	
	// Nothing to be done in case of new header structure
	if (container.parentNode.id != 'head2') return;

	// Backwards compatibility for old header structure
	setAttributeForElement('head2', 'height', '240px');
	setAttributeForElement('head3', 'height', '240px');
	setAttributeForElement('head1', 'backgroundPosition', '1004px 224px');
	setAttributeForElement('head4', 'top', '224px');
	setAttributeForElement('fullbanner2', 'height', '190px');
}

function adjustLayoutForWallpaper() {

	if (isType('popup1', 'wallpaper')) {
		// Obsolete because of new wallpaper design:
		// skyscraper part is now outside
		return;

		// Keep original left and width values synchronized
		// with base.css style #header .headlinks
		// left  = 630 - 206 = 424
		// width = 374 + 206 = 580

		setAttributeForElement('head4', 'left', '424px');
		setAttributeForElement('head4', 'width', '580px');
	}
	else if (isType('fullbanner2', 'wallpaper') || isType('fullbanner2', 'wp')) {
		setAttributeForElement('fullbanner2', 'backgroundImage', 'none');
	}
}

/* Flash Banner between header and content */
function adjustLayoutForExtremeFB2() {
	if (!isType('popup1', 'extremefb2')) return;
	var container = document.getElementById('sowefo');
	if (!container) return;

	var header = document.getElementById('header');
	if (header) header.style.marginBottom='270px';

	container.style.position = 'absolute';
	container.style.left = '14px';
	container.style.top  = '200px';
	container.style.zIndex = 999999;
}

// Function may be called after loading popup1
function adjustLayoutForSowefo() {
	adjustLayoutForWallpaper();
	adjustLayoutForExtremeFB2();
}

function shiftSkyscraper(div_id) {
	var el = document.getElementById(div_id);
	if (!el) return;
	if (el.style.display == 'none') return;

	if (needsSkyscraperEmbedded()) {
		el.className = 'skyscraper-embedded';
	}
}

function needsSkyscraperEmbedded() {
	var needs_skyscraper_embedded;

	if (!window.forceSkyscraperOutside) {
		if (window.forceSkyscraperInside) {
			needs_skyscraper_embedded = 1;
		}
		else if (!window.preferSkyscraperOutside
			&& !hasScreenWidthForSkyscraperOutside()) {
				needs_skyscraper_embedded = 1;
		}
	}

	return (needs_skyscraper_embedded || 0);
}

function hasSkyscraperEmbedded() {
	return SIM_ADTAG_INFO['skyscraper1'] && needsSkyscraperEmbedded();
}

function hasScreenWidthForSkyscraperOutside()
{
	return getScreenWidth() >= minWidthForSkyscraperOutside() ? true : false; 
}

function getScreenWidth()
{
	var x;
	try {
		x = top.innerWidth;

		if (!x) {
			var element = top.document.documentElement || top.document.body;
			if (element) x = element.clientWidth;
			if (!x) x = top.document.body.offsetWidth;
		}
	}
	catch(e) {}

	return x || 0; 
}

function checkGalleryRectangle(ad_id, forwardUrl) {
    if (!existsRectangle(ad_id)) document.location = forwardUrl;
}

function checkCrossRectangles() {
	void(0);
}

/*
	Function for moving ordinary and google ads to final location
*/
function moveAd(id)
{
	var source_element = document.getElementById('source_' + id);
	var target_element = document.getElementById('target_' + id);

	if (!source_element || !target_element) return;
	
	// Workaround for IE bug:
	// Prevent IE duplicate request of script src when moving content of container.
	var embedded_scripts = source_element.getElementsByTagName('script');
	for (var i = 0; i < embedded_scripts.length; i++) {
		if (!embedded_scripts[i].src) continue;
		embedded_scripts[i].removeAttribute('src');
	}

	var target_parent = target_element.parentNode;

	target_parent.replaceChild(source_element, target_element);

	// Renaming of id is necessary for dynamic ad update via iframe.
	source_element.id = 'target_' + id;

	source_element.style.display = source_element.tagName.toLowerCase() == 'div' ?
		'block' : 'inline';
}

/******************************************
Functions for reloading adtags in iframes. 
******************************************/

/*
	Usage:
	*******
	
	The function iframesReload can be assigned to the onload event of an iframe.

	This will trigger the reload of adtags and ivw count (optionally)
	on each reload of this iframe.
	
	Arguments:
	**********
	
	- iframe_ids:
	  an array of iframe ids associated with iframes containing adtags
	  *or*
	  a string containing a single iframe id
	  PLEASE NOTE: This argument is obsolete but still required.
	
	- iframe:
	  a reference to the iframe that triggers the function
	  (this iframe must have a unique id)
	  *or*
	  a string containing a unique id
	
	- do_ivw_count:
	  boolean value
	  If set to true, executes the function 'count_ivw' provided
	  this function is defined.
	  
	Please note:
	************
	
	- The function gets executed on reload of the master iframe,
	  but *not* on first load of the document.
	
	- In IE 5.0, iframes do not fire the onload event.
	  Thus, this function gets never called in IE5.0.
*/

function iframesReload(iframe_ids, iframe, do_ivw_count)
{
	var id = typeof(iframe) == 'object' ? iframe.getAttribute('id') : iframe;
	// Some default id.
	if (!id) id = 'null';
	
	// This prevents reloading of iframes on initial load of master document.
	if (iframesReload[id]) {
		if (do_ivw_count && window.count_ivw) {count_ivw();}
		SIMAdWriter.updateAds({triggered_for: 'iframe_action'});
	}
	else {
		iframesReload[id] = 1;
	}
}

/***************************
Shopping tipps
****************************/

/*
	Usage:
	Functions must be called in *separate* script tags!
*/

function loadShoppingtipp(do_load) {
	if (SIMAdWriter.adType != 'SOI') return;

	// SOI variable
	if (!window.SOI_place) return;

	if (window.SOI_ZAHL == null) {
		window.SOI_ZAHL = 1;
	}
	else {
		window.SOI_ZAHL += 1;
	}

	if (window.SOI_ZAHL == 1) document.write('<div id="adtags-shop1" class="shoptipp-head">Shopping Tipp<\/div>');

	// do_load argument may be set to false for debugging.
	// Value is passed in shoppingtipp template.
	if (!do_load) return;

	SIMAdWriter.doAd(window.SOI_place[window.SOI_ZAHL]);
}

function cross_shoptipp_197() {
	if (SIMAdWriter.adType != 'SOI') return;

	if (!window.SOI_ZAHL) return;

	var tipp_exists = window.IMPERIA_PREVIEWMODE || existsRectangle('shoppingtipp' + window.SOI_ZAHL);

	if (tipp_exists) {
		if ((window.SOI_TXT1 || window.SOI_TXT2 || window.SOI_TXT3 || window.SOI_IMG) && window.SOI_LNK) {
			var snippet =
				  '<div class="shoptipp-bg">'
				+ '<table border="0" cellspacing="0" cellpadding="0" class="align-top">'
				+ '<tr>'
				+ '<td style="width:65px"><a href="'+window.SOI_LNK+'" target="_blank"><img src="'+window.SOI_IMG+'" width="60" height="60" alt="" \/><\/a><br \/><\/td>'
				+ '<td style="width:127px"><h1><a href="'+window.SOI_LNK+'" target="_blank">'+window.SOI_TXT1+'<\/a><\/h1>'
				+ '<p>'+window.SOI_TXT2+'<\/p>'
				+ '<p><a href="'+window.SOI_LNK+'" class="tipplink" target="_blank">'+window.SOI_TXT3+'<\/a><\/p><\/td>'
				+ '<\/tr>'
				+ '<\/table>'
				+ '<\/div>'
				+ '<div class="shoptipp-spacer"><\/div>'
			document.write(snippet)
		}

		// Always, because swf shoppingtipps do not have SOI vars defined
		setAttributeForElement('adtags-shop1', 'display', 'block');

		// Reset SOI vars
		for (var i = 1; i < 4; i++) {
			window['SOI_TXT'+i] = '';
		}
		window.SOI_LNK = window.SOI_IMG = '';
	}
}

/***************************
Google Adsense
****************************/

/*
	This function is called from adtags*.class.php
	It loads the google script 'show_ads.js' dynamically if needed.
*/
function load_google_ads(type, mode)
{
	if (!mode) mode = '';
    
    // No google ads with ExtremeFB2
	if (isType('popup1', 'extremefb2')) return;
    
	if (type.match(/^rectangle2/)) {
		if (SIM_ADTAG_INFO['rectangle2']) return;

		if (type == 'rectangle2-contentvideo'
			&& hasSkyscraperEmbedded()) return;
	}
	else if (type == 'skyscraper') {
		// No depency on ordinary adtags
	}
	else if (type.match(/^fullbanner2/)) {
		if (SIM_ADTAG_INFO['fullbanner2']) return;
	}

	var src = mode == 'afs' ?
		  'http://www.google.com/afsonline/show_afs_ads.js'
		: 'http://pagead2.googlesyndication.com/pagead/show_ads.js';

	document.write('<script language="JavaScript" src="' + src + '"><\/script>');
}

/*
	The function 'google_ad_request_done' is executed in
	http://pagead2.googlesyndication.com/pagead/show_ads.js
	Thus the function is not executed if load_google_ads returns,
	and existence checks for other ads is not required here.
*/
function google_ad_request_done(google_ads) {
	if (!google_ads || google_ads.length == 0) return;
	
	var type = SIM_GOOGLE_ADTYPE;

	if (type == 'rectangle2') {
		write_google_ads(google_ads, type);
	}
	else if (type == 'skyscraper') {
		write_google_ads(google_ads, type);
	}
	else if (type.match(/^fullbanner2/)) {
		write_google_ads_popup(google_ads, type);
	}
	else {
		return;
	}

	if (google_ads[0].bidtype == "CPC" && google_ads[0].type != 'image') {
		SIM_GOOGLE_COUNT += google_ads.length;
	}

	return;
}

/*
	The function 'google_afs_request_done' is executed in
	http://www.google.com/afsonline/show_afs_ads.js,
	and is manually called on search pages
	for left and right column google ads.
*/
function google_afs_request_done(google_ads, num)
{
	var self = arguments.callee;
	
	if (!self.__init) {
		self.__init = 1;
		self.wide_ads   = new Array();
		self.narrow_ads = new Array();
		if (google_ads) {
			for (var i = 0; i < google_ads.length; ++i) {
				if (google_ads[i].type == 'text/wide') {
					self.wide_ads.push(google_ads[i]);
				}
				else {
					self.narrow_ads.push(google_ads[i]);
				}
			}
		}
	}

	var type = SIM_GOOGLE_ADTYPE;

	if (type == 'suchergebnisse') {
		if (self.wide_ads.length == 0) return;
		write_google_suchergebnisse(self.wide_ads);
	}
	else if (type == 'suchergebnisse_top') {
		if (self.wide_ads.length == 0) return;
		write_google_suchergebnisse_top(self.wide_ads);
	}
	else {
		if (self.narrow_ads.length == 0) return;

		var narrow_ads_todo = new Array();
		var narrow_ads_left = new Array();

		for (var i = 0; i < self.narrow_ads.length; ++i) {
			if (i < num) {
				narrow_ads_todo.push(self.narrow_ads[i]);
			}
			else {
				narrow_ads_left.push(self.narrow_ads[i]);
			}
		}
		
		self.narrow_ads = narrow_ads_left;
		
		google_ad_request_done(narrow_ads_todo);
	}
}

function write_google_ads(google_ads, type) {
	if (!google_ads || google_ads.length == 0) return;
	
	var s = '';
	
	if (type == 'rectangle2') {
		var title = google_ads.length == 1 ?
			  'Anzeige'
			: 'Anzeigen';
		s += '<div id="google-rectangle2" class="google-rectangle2">'
			+ '<p class="anzeige"><a href="' + google_info.feedback_url + '" target="_blank">' + title + '<\/a><\/p>';
		for (var i = 0; i < google_ads.length; ++i) {
			s += '<div class="google1-body">'
				+ '<p class="title"><a href="' + google_ads[i].url + '" target="_blank" onmouseover="window.status=\'' + google_ads[i].visible_url + '\';return true" onmouseout="window.status=\'\'">' + google_ads[i].line1 + '<\/a><\/p>'
				+ '<p>' + google_ads[i].line2 + ' ' + google_ads[i].line3 + '<\/p>'
				+ '<p><a href="' + google_ads[i].url + '" target="_blank" onmouseover="window.status=\'' + google_ads[i].visible_url + '\';return true" onmouseout="window.status=\'\'">' + google_ads[i].visible_url + '<\/a><\/p>'
				+ '<\/div>';
		}
		s += '<\/div>';
		// FIXME:
		// With postponed loading, the container should be
		// turned to block only *after* receiving content.
		setAttributeForElement('rectangle2', 'display', 'block');
	}
	else if (type == 'skyscraper') {
		var title = google_ads.length == 1 ?
			  'Anzeige'
			: 'Anzeigen';

		s += '<div class="tipps">'
			+ '<div class="tipps-top"><\/div>'
			+ '<div class="tipps-bg">'
			+ '<div class="tipps-inner">'
			+ '<h1 class="tipps-head" style="font-size:11px"><a href="' + google_info.feedback_url + '" target="_blank">' + title + '<\/a><\/h1>'
			+ '<div class="webtipps">';

		for (var i = 0; i < google_ads.length; ++i) {
			s += '<div class="google4-body">'
				+ '<h1><a href="' + google_ads[i].url + '" target="_blank" onmouseover="window.status=\'' + google_ads[i].visible_url + '\';return true" onmouseout="window.status=\'\'">' + google_ads[i].line1 + '<\/a><\/h1>'
				+ '<p>' + google_ads[i].line2 + ' ' + google_ads[i].line3 + '<\/p>'
				+ '<p><a class="tipplink" href="' + google_ads[i].url + '" target="_blank" onmouseover="window.status=\'' + google_ads[i].visible_url + '\';return true" onmouseout="window.status=\'\'">' + google_ads[i].visible_url + '<\/a><\/p>'
				+ '<\/div>';
		}
		
		s += '<\/div>'
			+ '<\/div>'
			+ '<\/div>'
			+ '<div class="tipps-bottom"><\/div>'
			+ '<\/div>';
	}
	
	document.write(s);
}

// Valid types are fullbanner2-GAL|fullbanner2-VID|fullbanner2-GAME|fullbanner2-CONTENTPOPUP
// Currently type is not needed.
function write_google_ads_popup(google_ads, type) {
	if (!google_ads || google_ads.length == 0) return;

	var s = '<div class="google-popup-fullbanner2">';

	for (var i = 0; i < google_ads.length; ++i) {
		s += '<div class="google-item">'
			+ '<h1><a href="' + google_ads[i].url + '" target="_blank" onmouseover="window.status=\'' + google_ads[i].visible_url + '\';return true" onmouseout="window.status=\'\'">' + google_ads[i].line1 + '<\/a><\/h1>'
			+ '<p>' + google_ads[i].line2 + ' ' + google_ads[i].line3 + '<\/p>'
			+ '<p><a class="linkstyle" href="' + google_ads[i].url + '" target="_blank" onmouseover="window.status=\'' + google_ads[i].visible_url + '\';return true" onmouseout="window.status=\'\'">' + google_ads[i].visible_url + '<\/a><\/p>'
			+ '<\/div>';
	}
	
	s += '<div class="google-title">Anzeigen<\/div>'
		+ '<\/div>';
	
	// FIXME:
	// With postponed loading, the container should be
	// turned to block only *after* receiving content.
	setAttributeForElement('fullbanner2', 'display', 'block');

	document.write(s);
}

function write_google_suchergebnisse(google_ads) {
	if (!google_ads || google_ads.length == 0) return;
	
	var s = '<div id="google-suchergebnisse" style="margin:0px 5px 20px 5px;">';

	for (var i = 3; i < google_ads.length-3; ++i) {
		var text = google_ads[i].line2;
		if (google_ads[i].line3) text += ' ' + google_ads[i].line3;

		s += '<div style="padding:12px 0px">'
			+ '<h1><a href="'+ google_ads[i].url +'" target="_blank" onmouseover="window.status=\'' + google_ads[i].visible_url + '\';return true" onmouseout="window.status=\'\'">' + google_ads[i].line1 + '<\/a><\/h1>'
			+ '<p>' + text + '<\/p>'
			+ '<p><a class="linkstyle" href="'+ google_ads[i].url +'" target="_blank" onmouseover="window.status=\'' + google_ads[i].visible_url + '\';return true" onmouseout="window.status=\'\'">' + google_ads[i].visible_url + '<\/a><\/p>';
			+ '<\/div>';
		SIM_GOOGLE_SEARCH_COUNT++;
	}

	s += '<\/div>';

	document.write(s);
}

function write_google_suchergebnisse_top(google_ads) {
	if (!google_ads || google_ads.length == 0) return;

	var s = '<div class="google-suchergebnisse-top">';
	s += '<h2><a href="https://www.google.com/adsense/support/bin/request.py?contact=afs_violation" target="_blank">Google-Anzeigen<\/a><\/h2>';
	
	for (var i=SIM_GOOGLE_SEARCH_COUNT; i < SIM_GOOGLE_SEARCH_COUNT+3; ++i) {
		if (google_ads[i]) {
			var text = google_ads[i].line2;
			if (google_ads[i].line3) text += ' ' + google_ads[i].line3;			
				s += '<table class="google-suchergebnisse-top-table">'
				+ '<tr><td colspan="2"><h1><a href="'+ google_ads[i].url +'" target="_blank" onmouseover="window.status=\'' + google_ads[i].visible_url + '\';return true" onmouseout="window.status=\'\'">' + google_ads[i].line1 + '<\/a><\/h1><\/td><\/tr>'
				+ '<tr><td><a class="linkstyle" href="'+ google_ads[i].url +'" target="_blank" onmouseover="window.status=\'' + google_ads[i].visible_url + '\';return true" onmouseout="window.status=\'\'">' + google_ads[i].visible_url + '<\/a><span style="margin-right: 10px;">&nbsp;<\/span><\/td>'
				+ '<td style="text-align:left">' + text + '<\/td><\/tr>'
				+ '<\/table>';
		}
	}
	SIM_GOOGLE_SEARCH_COUNT+=3;
	
	s += '<\/div>';

	document.write(s);

	return;
}
