/**
	@Name: class Advertisement
	@Description: Display an HTML advertisement
	@Param: 1.1

	~History~
	Date        | Author        | [Version] Change
	===========================================================================
  2011-05-13  Ky Patterson    [1.1] support api1 and api2
*/
$WI.Class.Advertisement = new $WI.Class({
	/**
		@Name: Constructor
		@Description: See <Create()>
	*/
	__new: function(options) {
		if (options != undefined)
			this.Create(options);
	},
	/**
		@Name: Create
		@Description: Initialize object
		@Param: options
					uuid
						random uuid identifier for this banner display
					contentItemId
						id of banner spot item, for tracking
					contentItemUuid
						uuid of banner spot item, for tracking
					languageId
						language id of request, for tracking
					revisionId
						revision id of request, for tracking
					clusterMasterId
						id of page item, for tracking
					socketName
						name of ad socket, for tracking
					random_servers
						number of media servers. Zero (0) disables random server selection (default)
					logger
						true to send ajax notice to server for each banner impression (default)
						false for image-url based tracking where no ajax is needed
		@Returns: void
	*/
	Create: function(options) {
		this.options = options;
		this.uuid = options.uuid;
		this.placer = $E(this.options.uuid);
		this.analytical_url =options.analyticalurl;
		this.server_uuid =options.server_uuid
		this.logger = (options.logger != undefined && options.logger) ? true : false;
		if (options.random_servers != undefined)
			this._random_servers = options.random_servers;
	},
	/**
		@Name: SetLogger
		@Description: Turn server logging on or off
		@Param: status - (bool)
		@Returns: void
	*/
	SetLogger: function(status) {
		this.logger = (status != undefined && status) ? true : false;
	},
	/**
		@Name: SetRandomServers
		@Description: Set number of media servers. Zero (0) to disable random server selection
		@Returns: void
	*/
	SetRandomServers: function(servers){
		this.random_servers = (servers != undefined) ? servers : 0;
	},
	/**
		@Name: Write
		@Description:
		@Param: data - (string) base64-encoded xml document containing banner data; or null to load banner data via ajax from server
		@Param: load_priority - (int)
			1: load banners whem dom is ready
			2: load banners when page is loaded
			default: load banners immediately
		@Returns: void
	*/
	Write: function(data, load_priority) {
		this.load_priority = (load_priority != undefined) ? load_priority : 0;
		if (data) {
			var data = this._decodeBase64(data);
			var xml = this._xml(data);
			
			this._start(function(){this._loadResults(xml, data)}.Apply(this));
		}
		else {
			this._start(function(){this._loadBanners()}.Apply(this));
		}
	},
	// call load banners function at appropriate time
	_start: function(func) {
		switch(this.load_priority) {
			case '2': //load banners when page is loaded
				$WI.Event.OnLoadPage(func);
				break;
			case '1':  //load banners when dom is ready
				$WI.Event.OnLoadDOM(func);
				break;
			default: //instant load
				func.call();
				break;
		}
	},
	// load banner data from server via ajax
	_loadBanners: function() {
		this.Request({url: this._getAjaxUrl() + '&ReadInfo=true', method: 'GET', onComplete: this._loadResults});
	},
	// load banner data xml
	_loadResults: function(xml, text) {
		this.xml = xml;
		this.priority = [];
		this.banners = [];
		this.num_displayed_banners = parseInt(this.xml.getNodeValue('//advertisement/properties/num_displayed_banners'));
		this.num_columns = parseInt(this.xml.getNodeValue('//advertisement/properties/num_columns'));
		this.rotation_frequency = parseInt(this.xml.getNodeValue('//advertisement/properties/rotation_frequency'));
		var result = xml.List("banners");

		for(var i=0;i<result.length;i++) {
			//prevent banner display if it overlimited max number of display
			if(result[i].display_max!='' && result[i].display_max < result[i].lbs_display_count) continue;
			var __priority = result[i].priority;
			for(var j=0;j<__priority;j++) 
			this.priority.push(result[i].ab_id);						
			this.banners[result[i].ab_id] = result[i];
		}

		if(result.length > 0)
			this._showBanners();
		else
			this._cleanPlace();

		if(parseInt(this.rotation_frequency) > 0)
			setInterval(function(){this._showBanners()}.Apply(this), parseInt(this.rotation_frequency)*1000);
	},
	// display banner(s)
	_showBanners: function() {
		this.obj = this._createDOM({objType: 'table', cellPadding: '0px', cellSpacing: '0px'});
		var current_col = 1;
		var _appender = this.obj.tr;
		var _logged = [];

		for (var i=0; i < this.num_displayed_banners; i++) {
			if (this.priority.length==0)
				this._regeneratePriorityList();

			//generating random banner number
			if (this.priority.length == 1)
				_randNum = 0;
			else
				_randNum = this._random(this.priority.length - 1);

			var _randBanner = this.banners[this.priority[_randNum]];

			//create a new line
			if(this.num_columns < current_col) {
				current_col = 1;
				_appender = this._insertDOM(this.obj.tbody, {objType: 'tr'}, 'insertinto');
			}
			if(_randBanner !=undefined)
			{
			this._insertDOM(_appender, {newNode: this._createBanner(_randBanner)}, 'insertinto');

			//log banner id
			_logged.push(_randBanner.ab_id);

			//lets remove banner from the priority list
			var _index = this.priority.Search(_randBanner.ab_id);
			if(_index != -1) this.priority.splice(_index, _randBanner.priority);
			}
			
			current_col++;
		}

		//insert main banner object into the page
		this._cleanPlace();
		this._insertDOM(this.placer, {newNode: this.obj}, 'insertinto');

		//execute logger
		if (this.logger)
			this.Request({url: this._getAjaxUrl() + '&LogBanner=true', method: 'POST', parameters: '&member_uuid=' + this._getMemberUuid() + '&o1302281-85a4-bd74-f91da41fc01645a3=' + _logged.join(',')});
	},
	// Get visitor's uuid
	_getMemberUuid: function() {
	  return this._getCookie('TEMP_MEM_UUID');
	},
	// generate list of banners to display in rotation, based on priority
	_regeneratePriorityList: function() {
		this.priority = [];
		var result = this.xml.List("banners");
		for (var i=0; i < result.length; i++) {
			// prevent banner display if it overlimited max number of display
			if (result[i].display_max != '' && result[i].display_max < result[i].lbs_display_count)
				continue;
			var __priority = result[i].priority;
			for (var j=0; j < __priority; j++)
				this.priority.push(result[i].ab_id);
		}
	},
	// create html dom for a banner
	_createBanner: function(banner) {
		if(banner !=undefined){
		var file_ext = banner.ab_banner_filename.split('.').pop();
		var column = this._createDOM({objType: 'td', vAlign: 'top'});
		var ___href = null;

		// create a link
		if (!(banner.ab_use_ci_id == '' ||  (banner.click_max != '' && parseInt(banner.click_max) < parseInt(banner.lbs_click_count)))) {
			
			var ___href = '/index.php/tmpl/request/ci_uuid/' + this.options.contentItemUuid + '/cm_id/' + this.options.clusterMasterId + '/AE4D54E5-8BA4-ED2F-E3C94CAC40A05048/' + banner.ab_id;
		
		}

		// randomize banner servers, if banner url is passed as subdomain1.domain.com and or subdomain2.domain.com
		if (this.random_servers && this.random_servers > 1) {
			var _rand = this._random(this.random_servers - 1) + 1;
			banner.banner_url = banner.banner_url.replace(/^(http:\/\/)([a-zA-Z]*)./, '$1$2' + _rand)
			
		}

		// create banner asset html dom
		if(banner['ab_type'] == 1)
			this._createFlashBanner(banner, ___href, column);
		else if(file_ext == 'swf')
			this._createFlashBanner(banner, ___href, column);
		else
			this._createImageBanner(banner, ___href, column);

		//this is required to log banners located on the media server
		if (!this.logger)
			this._createLogSpacer(banner, column);

		//this.obj.tr.appendChild(column);
		return column;
		}
		else
		return"";
	},
	// create spacer image to log banner view
	_createLogSpacer: function(banner, column) {
		this._insertDOM(column, {objType: 'img', src: '' + this.analytical_url +'spacer.gif?type=log_banner_display&time=' + new Date().getTime() +'&server_uuid='+this.server_uuid+ '&ab_id=' + banner.ab_id +'&ci_id=' + this.options.contentItemId + '&cm_id=' + this.options.clusterMasterId + '&mem_uuid=' + this._getMemberUuid(), width: '1px', height: '1px'}, 'insertinto');
	},
	// create html dom for flash banner or html
	_createFlashBanner: function(banner, ___href, column) {
		var wrapper = null;
		var linking = null;
		if (___href) {
			wrapper = this._insertDOM(column, {objType: 'div', position: 'relative'}, 'insertinto');
			linking = this._insertDOM(wrapper, {objType: 'div', top: '0px', left: '0px', width: '100%', height: '100%', position: 'absolute', backgroundImage: 'url(/prism_resource/images/spacer.gif)'}, 'insertinto');
			linking.style.cursor = 'pointer';

			if(banner['ab_popup']=='1') {
				this.AddDOMEvent({obj: linking, type: 'click', onevent: function(){$WI.DOM.PopUp(___href, 'BANNER_' + banner['ab_id'], "width=" + this._getScreenWH().w + ", height=" + this._getScreenWH().h + ", top=0, left=0, resizable=1, scrollbars=1, status=1, toolbar=1, location=1, menubar=1, directories=1")}});
			} else if(banner['ab_popup']=='2') {
				this.AddDOMEvent({obj: linking, type: 'click', onevent: function(){$WI.DOM.PopUp(___href, 'BANNER_' + banner['ab_id'], "width=" + banner['ab_popup_width'] + ", height=" + banner['ab_popup_height'] + ", top=0, left=0, resizable=1, scrollbars=1")}});
			} else {
				this.AddDOMEvent({obj: linking, type: 'click', onevent: function(){location.href = ___href}});
			}
		}
		if (banner['ab_type'] == 1)
			this._insertDOM((wrapper)?wrapper:column, {objType: 'div', html: banner['ab_html']}, 'insertinto');
		else
			this._insertDOM((wrapper)?wrapper:column, {objType: 'div', html: $WI.Flash("src", banner.banner_url, "width", this._fixPx(banner['ab_banner_width']), "height", this._fixPx(banner['ab_banner_height']), "wmode", "transparent")}, 'insertinto');

		return column;
	},
	// create html dom for image banner
	_createImageBanner: function(banner, ___href, column) {
		var linking = null;

		if(___href) {
			linking = this._insertDOM(column, {objType: 'a'}, 'insertinto');
			linking.style.cursor = 'pointer';

			if(banner['ab_popup']=='1') {
				linking.href = ___href;
				linking.target = '_blank';
			} else if(banner['ab_popup']=='2') {
				this.AddDOMEvent({obj: linking, type: 'click', onevent: function(){$WI.DOM.PopUp(___href, 'BANNER_' + banner['ab_id'], "width=" + banner['ab_popup_width'] + ", height=" + banner['ab_popup_height'] + ", top=0, left=0, resizable=1, scrollbars=1")}});
			} else {
				linking.href = ___href;
			}
		}

		var __img = this._insertDOM((linking)?linking:column, {objType: 'img', src: banner.banner_url, borderWidth: '0px'}, 'insertinto');
		if (banner['ab_banner_width'])
			__img.style.width = this._fixPx(banner['ab_banner_width']);
		if (banner['ab_banner_height'])
			__img.style.height = this._fixPx(banner['ab_banner_height']);

		return column;
	},
	// remove contents of banner div
	_cleanPlace: function(){
		var _children = this._getChildren(this.placer);
		for(var i=0;i<_children.length;i++)
			this._removeDOM(_children[i]);
	},
	// return base ajaz url
	_getAjaxUrl: function() {
		return '/index.php?tmpl=request&ci_id=' + this.options.contentItemId + '&la_id=' + this.options.languageId + '&re_id=' + this.options.revisionId + '&cm_id=' + this.options.clusterMasterId + '&ci_socket_name=' + escape(this.options.socketName);
	},
	// UTILITY FUNCTIONS
	// Get a random number
	_random: function(val) {
		if(val!==undefined)
			return Math.round(val*Math.random());
		else
			return Math.round(9999999*Math.random());
	},
	// Converrt string to xml document
	_xml: function(data) {
		return ($WI.Method.XML != undefined) ? $WI.Method.XML.Init(data) : $WI.XmlDocument(data);
	},
	// get a cookie
	_getCookie: function (name) {
		var start = document.cookie.indexOf( name + "=" );
		var len = start + name.length + 1;
		if ( ( !start ) && ( name != document.cookie.substring( 0, name.length ) ) ) {
			return null;
		}
		if ( start == -1 ) return null;
		var end = document.cookie.indexOf( ';', len );
		if ( end == -1 ) end = document.cookie.length;
		return unescape( document.cookie.substring( len, end ) );
	},
	// Decode a base64 string
	_decodeBase64: function (input) {
		var output = "";
		var chr1, chr2, chr3;
		var enc1, enc2, enc3, enc4;
		var i = 0;
		input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
		while (i < input.length) {
			enc1 = this._keyStr.indexOf(input.charAt(i++));
			enc2 = this._keyStr.indexOf(input.charAt(i++));
			enc3 = this._keyStr.indexOf(input.charAt(i++));
			enc4 = this._keyStr.indexOf(input.charAt(i++));
			chr1 = (enc1 << 2) | (enc2 >> 4);
			chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
			chr3 = ((enc3 & 3) << 6) | enc4;
			output = output + String.fromCharCode(chr1);
			if (enc3 != 64) {
				output = output + String.fromCharCode(chr2);
			}
			if (enc4 != 64) {
				output = output + String.fromCharCode(chr3);
			}
		}
		output = this._utf8_decode(output);
		return output;
	},
	// convert utf8 to browser native
	_utf8_decode: function (utftext) {
		var string = "";
		var i = 0;
		var c = c1 = c2 = 0;
		while ( i < utftext.length ) {
			c = utftext.charCodeAt(i);
			if (c < 128) {
				string += String.fromCharCode(c);
				i++;
			}
			else if((c > 191) && (c < 224)) {
				c2 = utftext.charCodeAt(i+1);
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			}
			else {
				c2 = utftext.charCodeAt(i+1);
				c3 = utftext.charCodeAt(i+2);
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			}
		}
		return string;
	},
	_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
});
