var otm = otm ? otm : {};
otm.widget = otm.widget ? otm.widget : {};
otm.widget.ad = otm.widget.ad ? otm.widget.ad : {};

otm.widget.ad.AdWidget = function(params, options, seedDefaultThemes) {
	var PREVIEW_WIDTH = 320;
	var PREVIEW_HEIGHT = 240;

	var PREVIEW_DIV_ID = 'com.otm.partner.previewer';
	var EDIT_DIV_ID = 'com.otm.partner.editor';

	var contextPath = options != null && options.contextPath;
	var partnerKey = options != null && options.partnerKey; 
	var showExpanded = options != null && options.showExpanded;
	var initiallyHidden = options != null && options.initiallyHidden;
	var defaultThemes = seedDefaultThemes;

	function isArray(testObject) {
		return testObject &&
			!testObject.propertyIsEnumerable('length') &&
			typeof testObject === 'object' &&
			typeof testObject.length === 'number';
	}

	function generateRandomNumberSeed(intFrom, intTo, intSeed){
		// Make sure that we have integers.
		intFrom = Math.floor(intFrom);
		intTo = Math.floor(intTo);

		return Math.floor(intFrom + (intTo - intFrom + 1) * Math.random(intSeed ? intSeed : 0));
	}

	function ConfiguratorDataItem(paramName) {
		function getElementId(index) {
			return 'com.otm.partner.configurator.input' + index;
		}

		function getValue(index) {
			var element = document.getElementById(getElementId(index));
			if (element.type == 'select-one') {
				if(element.selectedIndex < 0) {
					return null;
				}

				return element.options[element.selectedIndex].value;
			}

			return element.value;	// for type == 'text';
		}

		this.updateFormField = function(configurator, index) {
			var currentValue = configurator.getValue(paramName);
			var element = document.getElementById(getElementId(index));
			if (element.type == 'select-one') {
				var options = element.getElementsByTagName('option');
				for (var i = 0; i < options.length; i++) {
					var option = options[i];
					option.selected = option.getAttribute('value') == currentValue;
				}
			} else {
				element.setAttribute('value', currentValue);
			}
		}

		this.updateConfigurator = function(configurator, index) {
			var value = getValue(index);
			if(value)
				configurator.setValue(paramName, value);
		}
	}

	function ConfiguratorData() {
		var _data = [];

		_data.push(new ConfiguratorDataItem('content'));
		_data.push(new ConfiguratorDataItem('theme_id'));
		_data.push(new ConfiguratorDataItem('name'));
		_data.push(new ConfiguratorDataItem('anon_0'));
		_data.push(new ConfiguratorDataItem('anon_1'));
		_data.push(new ConfiguratorDataItem('anon_2'));
		_data.push(new ConfiguratorDataItem('anon_3'));

		this.getSize = function() {
			return _data.length;
		}

		this.getConfiguratorDataItem = function(index) {
			return _data[index];
		}
	}

	function Configurator(configuratorData) {
		var _valueMap = {};
		var _visible;

		var that = this;

		function updateValuesFromConfiguratorData() {
			if(!_visible) {
				return;
			}

			for (var i = 0; i < configuratorData.getSize(); i++) {
				var configDataItem = configuratorData.getConfiguratorDataItem(i);
				configDataItem.updateConfigurator(that, i);
			}
		}

		function updateFormFields() {
			for(var i = 0; i < configuratorData.getSize(); i++) {
				var configDataItem = configuratorData.getConfiguratorDataItem(i);

				configDataItem.updateFormField(that, i);
			}
		}

		this.getValuesString = function() {
			updateValuesFromConfiguratorData();

			var values = '';

			for(var key in _valueMap) {
				if(values.length > 0) {
					values += '&';
				}

				values += encodeURIComponent(key) + '=' + encodeURIComponent(_valueMap[key]);
			}

			values += '&partner_key=' + partnerKey;

			return values;
		}

		this.setValue = function(key, value) {
			_valueMap[key] = value;
		}

		this.getValue = function(key) {
			return _valueMap[key];
		}

		this.render = function() {
			var divElement = document.getElementById(EDIT_DIV_ID);
			if (divElement) {
                updateFormFields();

				_visible = true;
			}
		}

		this.preview = function() {
            this.setValue('random_number_seed', generateRandomNumberSeed(0, 1000000, 1000000));

			var values = this.getValuesString();

			var streamParam = contextPath + '/ad_stream?createParams=' + encodeURIComponent(values) + '&a=' + Math.random();

			var flashVars = {
				streamName: encodeURIComponent(streamParam),
				autoPlay: 'true'
			}

			var previewer = document.getElementById(PREVIEW_DIV_ID);
			if (previewer && previewer.externalCloseVideoStream) {
				previewer.externalCloseVideoStream();
			}

			var content = document.getElementById(PREVIEW_DIV_ID);
			if (!content) {	// if removeSWF() has been called already
				var div = document.createElement('div');
				div.setAttribute('id', PREVIEW_DIV_ID);

				document.getElementById('com.otm.partner.previewContainer').appendChild(div);
			}

			swfobject.embedSWF(contextPath + '/media/auth/PlayerAdWidget.swf?v=0.3', PREVIEW_DIV_ID , PREVIEW_WIDTH, PREVIEW_HEIGHT, '8.0',
					false, flashVars, {allowScriptAccess: "always"}, false);
		}

		function setValuesFromMap(map) {
			that.setValue('name', map.name);
			that.setValue('content', map.category);
			that.setValue('page', map.page);
			that.setValue('format', map.format); 
			that.setValue('anon_0', map.text0);
			that.setValue('anon_1', map.text1);
			that.setValue('anon_2', map.text2);
			that.setValue('anon_3', map.text3);
		}

		this.refresh = function(map) {
			setValuesFromMap(map);
			updateFormFields();

			this.preview();
		}

		// configure defaults
		var map = isArray(params) ? params[0] : params;
		setValuesFromMap(map);
		var selectedThemeIndex = Math.floor(Math.random() * defaultThemes.length);
		this.setValue('theme_id', defaultThemes[selectedThemeIndex]);
	}

	var _configurator;

	var that = this;

	function renderWidget() {
		var configuratorData = new ConfiguratorData();

		_configurator = new Configurator(configuratorData);

		if(!initiallyHidden) {
			_configurator.preview();
		}

		if (showExpanded) {
			that.renderEditOptions();
		}
	}

	function postToSpotMixer(step) {
		var values = _configurator.getValuesString();

		var form = document.getElementById('com.otm.partner.configuratorForm');
		form.elements['createParams'].setAttribute('value', values);

		if (step) {
			form.elements['step'].setAttribute('value', step);
		}

		form.submit();

		return false;
	}

	this.postToSpotMixer = postToSpotMixer;
	this.preview = function() {
		_configurator.preview();
	}

	function updateSelectedBusiness(index) {
		var map = params[index];
		if (!map) {
			return;
		}

		_configurator.refresh(map);
	}

	function assignClickHandlers() {
		var contentSelect = document.getElementById('com.otm.partner.configurator.input0');
		if (contentSelect) {
			contentSelect.onchange = function() {
				_configurator.preview();
			};
		}

		var themeSelect = document.getElementById('com.otm.partner.configurator.input1');
		if (themeSelect) {
			themeSelect.onchange = function() {
				_configurator.preview();
			};
		}

		var previewButton = document.getElementById('com.otm.partner.configuratorForm.submit0');
		if (previewButton) {
			previewButton.onclick = function() {
				_configurator.preview();
			};
		}
		var customizeButton = document.getElementById('com.otm.partner.configuratorForm.submit1');
		if (customizeButton) {
			customizeButton.onclick = function() {
				postToSpotMixer();
			};
		}
		var useThisButton = document.getElementById('com.otm.partner.configuratorForm.submit2');
		if (useThisButton) {
			useThisButton.onclick = function() {
				postToSpotMixer('publish');
			};
		}
		var campaignSelector = document.getElementById('com.otm.partner.campaignSelector');
		if (campaignSelector) {
			campaignSelector.onchange = function() {
				updateSelectedBusiness(this.selectedIndex);
			}
		}
	}

	this.renderEditOptions = function() {
		// render the configurator
		_configurator.render();
		assignClickHandlers();
	}

	renderWidget();
}

